update for HEAD-2003091401
[reactos.git] / subsys / win32k / dib / dib8bpp.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_8BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c)
32 {
33   PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta + x;
34
35   *byteaddr = c;
36 }
37
38 ULONG
39 DIB_8BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y)
40 {
41   PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta + x;
42
43   return (ULONG)(*byteaddr);
44 }
45
46 VOID
47 DIB_8BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
48 {
49   PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta;
50   PBYTE addr = byteaddr + x1;
51   LONG cx = x1;
52
53   while(cx < x2) {
54     *addr = c;
55     ++addr;
56     ++cx;
57   }
58 }
59
60 VOID
61 DIB_8BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
62 {
63   PBYTE byteaddr = SurfObj->pvScan0 + y1 * SurfObj->lDelta;
64   PBYTE addr = byteaddr + x;
65   LONG lDelta = SurfObj->lDelta;
66
67   byteaddr = addr;
68   while(y1++ < y2) {
69     *addr = c;
70
71     addr += lDelta;
72   }
73 }
74
75 BOOLEAN
76 DIB_8BPP_BitBltSrcCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
77                        SURFGDI *DestGDI,  SURFGDI *SourceGDI,
78                        PRECTL  DestRect,  POINTL  *SourcePoint,
79                        XLATEOBJ *ColorTranslation)
80 {
81   LONG     i, j, sx, sy, xColor, f1;
82   PBYTE    SourceBits, DestBits, SourceLine, DestLine;
83   PBYTE    SourceBits_4BPP, SourceLine_4BPP;
84
85   DestBits = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + DestRect->left;
86
87   switch(SourceGDI->BitsPerPixel)
88   {
89     case 1:
90       sx = SourcePoint->x;
91       sy = SourcePoint->y;
92
93       for (j=DestRect->top; j<DestRect->bottom; j++)
94       {
95         sx = SourcePoint->x;
96         for (i=DestRect->left; i<DestRect->right; i++)
97         {
98           if(DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
99           {
100             DIB_8BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 0));
101           } else {
102             DIB_8BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 1));
103           }
104           sx++;
105         }
106         sy++;
107       }
108       break;
109
110     case 4:
111       SourceBits_4BPP = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + (SourcePoint->x >> 1);
112
113       for (j=DestRect->top; j<DestRect->bottom; j++)
114       {
115         SourceLine_4BPP = SourceBits_4BPP;
116         sx = SourcePoint->x;
117         f1 = sx & 1;
118
119         for (i=DestRect->left; i<DestRect->right; i++)
120         {
121           xColor = XLATEOBJ_iXlate(ColorTranslation,
122               (*SourceLine_4BPP & altnotmask[sx&1]) >> (4 * (1-(sx & 1))));
123           DIB_8BPP_PutPixel(DestSurf, i, j, xColor);
124           if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
125           sx++;
126         }
127
128         SourceBits_4BPP += SourceSurf->lDelta;
129       }
130       break;
131
132     case 8:
133       if (NULL == ColorTranslation || 0 != (ColorTranslation->flXlate & XO_TRIVIAL))
134       {
135         if (DestRect->top < SourcePoint->y)
136           {
137             SourceBits = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x;
138             for (j = DestRect->top; j < DestRect->bottom; j++)
139               {
140                 RtlMoveMemory(DestBits, SourceBits, DestRect->right - DestRect->left);
141                 SourceBits += SourceSurf->lDelta;
142                 DestBits += DestSurf->lDelta;
143               }
144           }
145         else
146           {
147             SourceBits = SourceSurf->pvScan0 + ((SourcePoint->y + DestRect->bottom - DestRect->top - 1) * SourceSurf->lDelta) + SourcePoint->x;
148             DestBits = DestSurf->pvScan0 + ((DestRect->bottom - 1) * DestSurf->lDelta) + DestRect->left;
149             for (j = DestRect->bottom - 1; DestRect->top <= j; j--)
150               {
151                 RtlMoveMemory(DestBits, SourceBits, DestRect->right - DestRect->left);
152                 SourceBits -= SourceSurf->lDelta;
153                 DestBits -= DestSurf->lDelta;
154               }
155           }
156       }
157       else
158       {
159         if (DestRect->top < SourcePoint->y)
160           {
161             SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x;
162             DestLine = DestBits;
163             for (j = DestRect->top; j < DestRect->bottom; j++)
164               {
165                 SourceBits = SourceLine;
166                 DestBits = DestLine;
167                 for (i=DestRect->left; i<DestRect->right; i++)
168                   {
169                     *DestBits++ = XLATEOBJ_iXlate(ColorTranslation, *SourceBits++);
170                   }
171                 SourceLine += SourceSurf->lDelta;
172                 DestLine += DestSurf->lDelta;
173               }
174           }
175         else
176           {
177             SourceLine = SourceSurf->pvScan0 + ((SourcePoint->y + DestRect->bottom - DestRect->top - 1) * SourceSurf->lDelta) + SourcePoint->x;
178             DestLine = DestSurf->pvScan0 + ((DestRect->bottom - 1) * DestSurf->lDelta) + DestRect->left;
179             for (j = DestRect->bottom - 1; DestRect->top <= j; j--)
180               {
181                 SourceBits = SourceLine;
182                 DestBits = DestLine;
183                 for (i=DestRect->left; i<DestRect->right; i++)
184                   {
185                     *DestBits++ = XLATEOBJ_iXlate(ColorTranslation, *SourceBits++);
186                   }
187                 SourceLine -= SourceSurf->lDelta;
188                 DestLine -= DestSurf->lDelta;
189               }
190           }
191       }
192       break;
193
194     case 16:
195       SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 2 * SourcePoint->x;
196       DestLine = DestBits;
197
198       for (j = DestRect->top; j < DestRect->bottom; j++)
199       {
200         SourceBits = SourceLine;
201         DestBits = DestLine;
202
203         for (i = DestRect->left; i < DestRect->right; i++)
204         {
205           xColor = *((PWORD) SourceBits);
206           *DestBits = XLATEOBJ_iXlate(ColorTranslation, xColor);
207           SourceBits += 2;
208           DestBits += 1;
209         }
210
211         SourceLine += SourceSurf->lDelta;
212         DestLine += DestSurf->lDelta;
213       }
214       break;
215
216     case 24:
217       SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 3 * SourcePoint->x;
218       DestLine = DestBits;
219
220       for (j = DestRect->top; j < DestRect->bottom; j++)
221       {
222         SourceBits = SourceLine;
223         DestBits = DestLine;
224
225         for (i = DestRect->left; i < DestRect->right; i++)
226         {
227           xColor = (*(SourceBits + 2) << 0x10) +
228              (*(SourceBits + 1) << 0x08) +
229              (*(SourceBits));
230           *DestBits = XLATEOBJ_iXlate(ColorTranslation, xColor);
231           SourceBits += 3;
232           DestBits += 1;
233         }
234
235         SourceLine += SourceSurf->lDelta;
236         DestLine += DestSurf->lDelta;
237       }
238       break;
239
240     case 32:
241       SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 4 * SourcePoint->x;
242       DestLine = DestBits;
243
244       for (j = DestRect->top; j < DestRect->bottom; j++)
245       {
246         SourceBits = SourceLine;
247         DestBits = DestLine;
248
249         for (i = DestRect->left; i < DestRect->right; i++)
250         {
251           xColor = *((PDWORD) SourceBits);
252           *DestBits = XLATEOBJ_iXlate(ColorTranslation, xColor);
253           SourceBits += 4;
254           DestBits += 1;
255         }
256
257         SourceLine += SourceSurf->lDelta;
258         DestLine += DestSurf->lDelta;
259       }
260       break;
261
262     default:
263       DbgPrint("DIB_8BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
264       return FALSE;
265   }
266
267   return TRUE;
268 }
269
270 BOOLEAN
271 DIB_8BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
272                  SURFGDI *DestGDI,  SURFGDI *SourceGDI,
273                  PRECTL  DestRect,  POINTL  *SourcePoint,
274                  PBRUSHOBJ Brush, PPOINTL BrushOrigin,
275                  XLATEOBJ *ColorTranslation, ULONG Rop4)
276 {
277   LONG     i, j, k, sx, sy;
278   ULONG    Dest, Source, Pattern;
279   PULONG   DestBits;
280   BOOL     UsesSource = ((Rop4 & 0xCC0000) >> 2) != (Rop4 & 0x330000);
281   BOOL     UsesPattern = ((Rop4 & 0xF00000) >> 4) != (Rop4 & 0x0F0000);  
282   LONG     RoundedRight = DestRect->right - (DestRect->right & 0x3);
283
284   if (Rop4 == SRCCOPY)
285     {
286       return(DIB_8BPP_BitBltSrcCopy(DestSurf, SourceSurf, DestGDI, SourceGDI, DestRect, SourcePoint, ColorTranslation));
287     }
288   else
289     {
290       sy = SourcePoint->y;
291
292       for (j=DestRect->top; j<DestRect->bottom; j++)
293       {
294         sx = SourcePoint->x;
295         DestBits = (PULONG)(DestSurf->pvScan0 + DestRect->left + j * DestSurf->lDelta);
296         for (i=DestRect->left; i<RoundedRight; i+=4, DestBits++)
297           {
298             Dest = *DestBits;
299             if (UsesSource)
300               {
301                 Source = 0;
302                 for (k = 0; k < 4; k++)
303                   {
304                     Source |= (DIB_GetSource(SourceSurf, SourceGDI, sx + i + k, sy, ColorTranslation) << (k * 8));
305                   }
306               }
307             if (UsesPattern)
308               {
309                 /* FIXME: No support for pattern brushes. */
310                 Pattern = (Brush->iSolidColor & 0xFF) |
311                           ((Brush->iSolidColor & 0xFF) << 8) |
312                           ((Brush->iSolidColor & 0xFF) << 16) |
313                           ((Brush->iSolidColor & 0xFF) << 24);
314               }
315             *DestBits = DIB_DoRop(Rop4, Dest, Source, Pattern);     
316           }
317         if (i < DestRect->right)
318           {
319             Dest = *DestBits;
320             for (; i < DestRect->right; i++)
321               {
322                 if (UsesSource)
323                   {
324                     Source = DIB_GetSource(SourceSurf, SourceGDI, sx + i, sy, ColorTranslation);
325                   }
326                 if (UsesPattern)
327                   {
328                     /* FIXME: No support for pattern brushes. */
329                     Pattern = (Brush->iSolidColor & 0xFF) |
330                               ((Brush->iSolidColor & 0xFF) << 8) |
331                               ((Brush->iSolidColor & 0xFF) << 16) |
332                               ((Brush->iSolidColor & 0xFF) << 24);
333                   }                             
334                 DIB_8BPP_PutPixel(DestSurf, i, j, DIB_DoRop(Rop4, Dest, Source, Pattern) & 0xFFFF);
335                 Dest >>= 8;
336               }  
337           }
338       }
339     }
340   return TRUE;
341 }
342
343 /* EOF */