update for HEAD-2003091401
[reactos.git] / subsys / win32k / dib / dib32bpp.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 #undef WIN32_LEAN_AND_MEAN
21 #include <windows.h>
22 #include <stdlib.h>
23 #include <win32k/bitmaps.h>
24 #include <win32k/debug.h>
25 #include <debug.h>
26 #include <ddk/winddi.h>
27 #include "../eng/objects.h"
28 #include "dib.h"
29
30 VOID
31 DIB_32BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c)
32 {
33   PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta;
34   PDWORD addr = (PDWORD)byteaddr + x;
35
36   *addr = c;
37 }
38
39 ULONG
40 DIB_32BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y)
41 {
42   PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta;
43   PDWORD addr = (PDWORD)byteaddr + x;
44
45   return (ULONG)(*addr);
46 }
47
48 VOID
49 DIB_32BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
50 {
51   PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta;
52   PDWORD addr = (PDWORD)byteaddr + x1;
53   LONG cx = x1;
54
55   while(cx < x2) {
56     *addr = (DWORD)c;
57     ++addr;
58     ++cx;
59   }
60 }
61
62 VOID
63 DIB_32BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
64 {
65   PBYTE byteaddr = SurfObj->pvScan0 + y1 * SurfObj->lDelta;
66   PDWORD addr = (PDWORD)byteaddr + x;
67   LONG lDelta = SurfObj->lDelta / sizeof(DWORD);
68
69   byteaddr = (PBYTE)addr;
70   while(y1++ < y2) {
71     *addr = (DWORD)c;
72
73     addr += lDelta;
74   }
75 }
76
77 BOOLEAN
78 DIB_32BPP_BitBltSrcCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
79                         SURFGDI *DestGDI,  SURFGDI *SourceGDI,
80                         PRECTL  DestRect,  POINTL  *SourcePoint,
81                         XLATEOBJ *ColorTranslation)
82 {
83   LONG     i, j, sx, sy, xColor, f1;
84   PBYTE    SourceBits, DestBits, SourceLine, DestLine;
85   PBYTE    SourceBits_4BPP, SourceLine_4BPP;
86
87   DestBits = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + 4 * DestRect->left;
88
89   switch(SourceGDI->BitsPerPixel)
90   {
91     case 1:
92       sx = SourcePoint->x;
93       sy = SourcePoint->y;
94
95       for (j=DestRect->top; j<DestRect->bottom; j++)
96       {
97         sx = SourcePoint->x;
98         for (i=DestRect->left; i<DestRect->right; i++)
99         {
100           if(DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
101           {
102             DIB_32BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 0));
103           } else {
104             DIB_32BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 1));
105           }
106           sx++;
107         }
108         sy++;
109       }
110       break;
111
112     case 4:
113       SourceBits_4BPP = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + (SourcePoint->x >> 1);
114
115       for (j=DestRect->top; j<DestRect->bottom; j++)
116       {
117         SourceLine_4BPP = SourceBits_4BPP;
118         sx = SourcePoint->x;
119         f1 = sx & 1;
120
121         for (i=DestRect->left; i<DestRect->right; i++)
122         {
123           xColor = XLATEOBJ_iXlate(ColorTranslation,
124               (*SourceLine_4BPP & altnotmask[sx&1]) >> (4 * (1-(sx & 1))));
125           DIB_32BPP_PutPixel(DestSurf, i, j, xColor);
126           if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
127           sx++;
128         }
129
130         SourceBits_4BPP += SourceSurf->lDelta;
131       }
132       break;
133
134     case 8:
135       SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x;
136       DestLine = DestBits;
137
138       for (j = DestRect->top; j < DestRect->bottom; j++)
139       {
140         SourceBits = SourceLine;
141         DestBits = DestLine;
142
143         for (i = DestRect->left; i < DestRect->right; i++)
144         {
145           xColor = *SourceBits;
146           *((PDWORD) DestBits) = (DWORD)XLATEOBJ_iXlate(ColorTranslation, xColor);
147           SourceBits += 1;
148           DestBits += 4;
149         }
150
151         SourceLine += SourceSurf->lDelta;
152         DestLine += DestSurf->lDelta;
153       }
154       break;
155
156     case 16:
157       SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 2 * SourcePoint->x;
158       DestLine = DestBits;
159
160       for (j = DestRect->top; j < DestRect->bottom; j++)
161       {
162         SourceBits = SourceLine;
163         DestBits = DestLine;
164
165         for (i = DestRect->left; i < DestRect->right; i++)
166         {
167           xColor = *((PWORD) SourceBits);
168           *((PDWORD) DestBits) = (DWORD)XLATEOBJ_iXlate(ColorTranslation, xColor);
169           SourceBits += 2;
170           DestBits += 4;
171         }
172
173         SourceLine += SourceSurf->lDelta;
174         DestLine += DestSurf->lDelta;
175       }
176       break;
177
178     case 24:
179       SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 3 * SourcePoint->x;
180       DestLine = DestBits;
181
182       for (j = DestRect->top; j < DestRect->bottom; j++)
183       {
184         SourceBits = SourceLine;
185         DestBits = DestLine;
186
187         for (i = DestRect->left; i < DestRect->right; i++)
188         {
189           xColor = (*(SourceBits + 2) << 0x10) +
190              (*(SourceBits + 1) << 0x08) +
191              (*(SourceBits));
192           *((PDWORD)DestBits) = (DWORD)XLATEOBJ_iXlate(ColorTranslation, xColor);
193           SourceBits += 3;
194           DestBits += 4;
195         }
196
197         SourceLine += SourceSurf->lDelta;
198         DestLine += DestSurf->lDelta;
199       }
200       break;
201
202     case 32:
203       if (NULL == ColorTranslation || 0 != (ColorTranslation->flXlate & XO_TRIVIAL))
204       {
205         if (DestRect->top < SourcePoint->y)
206           {
207             SourceBits = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 4 * SourcePoint->x;
208             for (j = DestRect->top; j < DestRect->bottom; j++)
209               {
210                 RtlMoveMemory(DestBits, SourceBits, 4 * (DestRect->right - DestRect->left));
211                 SourceBits += SourceSurf->lDelta;
212                 DestBits += DestSurf->lDelta;
213               }
214           }
215         else
216           {
217             SourceBits = SourceSurf->pvScan0 + ((SourcePoint->y + DestRect->bottom - DestRect->top - 1) * SourceSurf->lDelta) + 4 * SourcePoint->x;
218             DestBits = DestSurf->pvScan0 + ((DestRect->bottom - 1) * DestSurf->lDelta) + 4 * DestRect->left;
219             for (j = DestRect->bottom - 1; DestRect->top <= j; j--)
220               {
221                 RtlMoveMemory(DestBits, SourceBits, 4 * (DestRect->right - DestRect->left));
222                 SourceBits -= SourceSurf->lDelta;
223                 DestBits -= DestSurf->lDelta;
224               }
225           }
226       }
227       else
228       {
229         /* FIXME */
230         DPRINT1("DIB_32BPP_Bitblt: Unhandled ColorTranslation for 32 -> 32 copy");
231         return FALSE;
232       }
233       break;
234
235     default:
236       DbgPrint("DIB_32BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
237       return FALSE;
238   }
239
240   return TRUE;
241 }
242
243 BOOLEAN
244 DIB_32BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
245                  SURFGDI *DestGDI,  SURFGDI *SourceGDI,
246                  PRECTL  DestRect,  POINTL  *SourcePoint,
247                  PBRUSHOBJ Brush, PPOINTL BrushOrigin,
248                  XLATEOBJ *ColorTranslation, ULONG Rop4)
249 {
250   LONG     i, j, k, sx, sy;
251   ULONG    Dest, Source, Pattern;
252   PULONG   DestBits;
253   BOOL     UsesSource = ((Rop4 & 0xCC0000) >> 2) != (Rop4 & 0x330000);
254   BOOL     UsesPattern = ((Rop4 & 0xF00000) >> 4) != (Rop4 & 0x0F0000);  
255
256   if (Rop4 == SRCCOPY)
257     {
258       return(DIB_32BPP_BitBltSrcCopy(DestSurf, SourceSurf, DestGDI, SourceGDI, DestRect, SourcePoint, ColorTranslation));
259     }
260   else
261     {
262       sy = SourcePoint->y;
263
264       for (j=DestRect->top; j<DestRect->bottom; j++)
265       {
266         sx = SourcePoint->x;
267         DestBits = (PULONG)(DestSurf->pvScan0 + 4 * DestRect->left + j * DestSurf->lDelta);
268         for (i=DestRect->left; i<DestRect->right; i++, DestBits++)
269           {
270             Dest = *DestBits;
271             if (UsesSource)
272               {
273                 Source = DIB_GetSource(SourceSurf, SourceGDI, sx + i + k, sy, ColorTranslation);
274               }
275             if (UsesPattern)
276               {
277                 /* FIXME: No support for pattern brushes. */
278                 Pattern = Brush->iSolidColor;
279               }
280             *DestBits = DIB_DoRop(Rop4, Dest, Source, Pattern);     
281           }
282       }
283     }
284   return TRUE;
285 }
286
287 /* EOF */