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