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