update for HEAD-2003091401
[reactos.git] / subsys / win32k / dib / dib.c
1 /*
2  *  ReactOS W32 Subsystem
3  *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /* $Id$ */
20
21 #include <windows.h>
22 #include <ddk/winddi.h>
23 #include <win32k/debug.h>
24 #include <debug.h>
25 #include "../eng/objects.h"
26 #include "dib.h"
27
28 /* Static data */
29
30 unsigned char notmask[2] = { 0x0f, 0xf0 };
31 unsigned char altnotmask[2] = { 0xf0, 0x0f };
32 unsigned char mask1Bpp[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
33
34 ULONG
35 DIB_GetSource(SURFOBJ* SourceSurf, SURFGDI* SourceGDI, ULONG sx, ULONG sy, XLATEOBJ* ColorTranslation)
36 {
37   switch (SourceGDI->BitsPerPixel)
38     {
39     case 1:
40       if (DIB_1BPP_GetPixel(SourceSurf, sx, sy))
41         {
42           return(XLATEOBJ_iXlate(ColorTranslation, 0));
43         }
44       else
45         {
46           return(XLATEOBJ_iXlate(ColorTranslation, 1));
47         }
48     case 4:
49       if (ColorTranslation != NULL)
50         {
51           return(XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy)));
52         }
53       else
54         {
55           return(DIB_4BPP_GetPixel(SourceSurf, sx, sy));
56         }
57     case 8:
58       return(XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy)));
59     case 16:
60       return(XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy)));
61     case 24:
62       return(XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy)));
63     case 32:
64       return(XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy)));
65     default:
66       DPRINT1("DIB_16BPP_ExpandSource: Unhandled number of bits per pixel in source.\n");
67       return(0);
68     }
69 }
70
71 ULONG
72 DIB_DoRop(ULONG Rop, ULONG Dest, ULONG Source, ULONG Pattern)
73 {
74   ULONG ResultNibble;
75   ULONG Result;
76   ULONG i;
77   static const ULONG ExpandDest[16] = 
78     {
79       0x55555555 /* 0000 */,
80       0x555555AA /* 0001 */,
81       0x5555AA55 /* 0010 */,
82       0x5555AAAA /* 0011 */,
83       0x55AA5555 /* 0100 */,
84       0x55AA55AA /* 0101 */,
85       0x55AAAA55 /* 0110 */,
86       0x55AAAAAA /* 0111 */,
87       0xAA555555 /* 1000 */,
88       0xAA5555AA /* 1001 */,
89       0xAA55AA55 /* 1010 */,
90       0xAA55AAAA /* 1011 */,
91       0xAAAA5555 /* 1100 */,
92       0xAAAA55AA /* 1101 */,
93       0xAAAAAA55 /* 1110 */,
94       0xAAAAAAAA /* 1111 */,
95     };
96   static const ULONG ExpandSource[16] = 
97     {
98       0x33333333 /* 0000 */,
99       0x333333CC /* 0001 */,
100       0x3333CC33 /* 0010 */,
101       0x3333CCCC /* 0011 */,
102       0x33CC3333 /* 0100 */,
103       0x33CC33CC /* 0101 */,
104       0x33CCCC33 /* 0110 */,
105       0x33CCCCCC /* 0111 */,
106       0xCC333333 /* 1000 */,
107       0xCC3333CC /* 1001 */,
108       0xCC33CC33 /* 1010 */,
109       0xCC33CCCC /* 1011 */,
110       0xCCCC3333 /* 1100 */,
111       0xCCCC33CC /* 1101 */,
112       0xCCCCCC33 /* 1110 */,
113       0xCCCCCCCC /* 1111 */,
114     };
115   static const ULONG ExpandPattern[16] = 
116     {
117       0x0F0F0F0F /* 0000 */,
118       0x0F0F0FF0 /* 0001 */,
119       0x0F0FF00F /* 0010 */,
120       0x0F0FF0F0 /* 0011 */,
121       0x0FF00F0F /* 0100 */,
122       0x0FF00FF0 /* 0101 */,
123       0x0FF0F00F /* 0110 */,
124       0x0FF0F0F0 /* 0111 */,
125       0xF00F0F0F /* 1000 */,
126       0xF00F0FF0 /* 1001 */,
127       0xF00FF00F /* 1010 */,
128       0xF00FF0F0 /* 1011 */,
129       0xF0F00F0F /* 1100 */,
130       0xF0F00FF0 /* 1101 */,
131       0xF0F0F00F /* 1110 */,
132       0xF0F0F0F0 /* 1111 */,
133     };
134
135   /* Optimized code for the various named rop codes. */
136   switch (Rop)
137     {
138     case BLACKNESS:   return(0);
139     case NOTSRCERASE: return(~(Dest | Source));
140     case NOTSRCCOPY:  return(~Source);
141     case SRCERASE:    return((~Dest) & Source);
142     case DSTINVERT:   return(~Dest);
143     case PATINVERT:   return(Dest ^ Pattern);
144     case SRCINVERT:   return(Dest ^ Source);
145     case SRCAND:      return(Dest & Source);
146     case MERGEPAINT:  return(Dest & (~Source));
147     case SRCPAINT:    return(Dest | Source);
148     case MERGECOPY:   return(Source & Pattern);
149     case SRCCOPY:     return(Source);
150     case PATCOPY:     return(Pattern);
151     case PATPAINT:    return(Dest | (~Source) | Pattern);
152     case WHITENESS:   return(0xFFFFFFFF);
153     }
154   /* Expand the ROP operation to all four bytes */
155   Rop &= 0x00FF0000;
156   Rop = (Rop << 8) | (Rop) | (Rop >> 8) | (Rop >> 16);
157   /* Do the operation on four bits simultaneously. */
158   Result = 0;
159   for (i = 0; i < 8; i++)
160     {
161       ResultNibble = Rop & ExpandDest[Dest & 0xF] & ExpandSource[Source & 0xF] & ExpandPattern[Pattern & 0xF];
162       Result |= (((ResultNibble & 0xFF000000) ? 0x8 : 0x0) | ((ResultNibble & 0x00FF0000) ? 0x4 : 0x0) | 
163         ((ResultNibble & 0x0000FF00) ? 0x2 : 0x0) | ((ResultNibble & 0x000000FF) ? 0x1 : 0x0)) << (i * 4);
164       Dest >>= 4;
165       Source >>= 4;
166       Pattern >>= 4;
167     }
168   return(Result);
169 }
170
171 /* EOF */