implemented TransparentBlt() on 32bpp surfaces, but there are still some clipping...
[reactos.git] / reactos / 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: dib24bpp.c,v 1.19 2004/04/06 17:54:32 weiden Exp $ */
20 #undef WIN32_LEAN_AND_MEAN
21 #include <windows.h>
22 #include <stdlib.h>
23 #include <win32k/bitmaps.h>
24 #include <win32k/brush.h>
25 #include <win32k/debug.h>
26 #include <debug.h>
27 #include <include/object.h>
28 #include <ddk/winddi.h>
29 #include "../eng/objects.h"
30 #include "dib.h"
31
32 VOID
33 DIB_24BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c)
34 {
35 PBYTE addr = SurfObj->pvScan0 + (y * SurfObj->lDelta) + (x << 1) + x;
36 *(PUSHORT)(addr) = c & 0xFFFF;
37 *(addr + 2) = (c >> 16) & 0xFF;
38 }
39
40 ULONG
41 DIB_24BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y)
42 {
43 PBYTE addr = SurfObj->pvScan0 + y * SurfObj->lDelta + (x << 1) + x;
44 return *(PUSHORT)(addr) + (*(addr + 2) << 16);
45 }
46
47 VOID
48 DIB_24BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
49 {
50 PBYTE addr = SurfObj->pvScan0 + y * SurfObj->lDelta + (x1 << 1) + x1;
51 LONG cx = x1;
52
53 c &= 0xFFFFFF;
54 while(cx < x2) {
55 *(PUSHORT)(addr) = c & 0xFFFF;
56 addr += 2;
57 *(addr) = c >> 16;
58 addr += 1;
59 ++cx;
60 }
61 }
62
63 VOID
64 DIB_24BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
65 {
66 PBYTE addr = SurfObj->pvScan0 + y1 * SurfObj->lDelta + (x << 1) + x;
67 LONG lDelta = SurfObj->lDelta;
68
69 c &= 0xFFFFFF;
70 while(y1++ < y2) {
71 *(PUSHORT)(addr) = c & 0xFFFF;
72 *(addr + 2) = c >> 16;
73
74 addr += lDelta;
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[f1]) >> (4 * (1 - f1)));
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 ULONG X, Y;
257 ULONG SourceX, SourceY;
258 ULONG Dest, Source, Pattern;
259 PBYTE DestBits;
260 BOOL UsesSource;
261 BOOL UsesPattern;
262 /* Pattern brushes */
263 PGDIBRUSHOBJ GdiBrush;
264 HBITMAP PatternSurface = NULL;
265 PSURFOBJ PatternObj;
266 ULONG PatternWidth, PatternHeight;
267
268 if (Rop4 == SRCCOPY)
269 {
270 return DIB_24BPP_BitBltSrcCopy(
271 DestSurf,
272 SourceSurf,
273 DestGDI,
274 SourceGDI,
275 DestRect,
276 SourcePoint,
277 ColorTranslation);
278 }
279
280 UsesSource = ((Rop4 & 0xCC0000) >> 2) != (Rop4 & 0x330000);
281 UsesPattern = ((Rop4 & 0xF00000) >> 4) != (Rop4 & 0x0F0000);
282
283 if (UsesPattern)
284 {
285 if (Brush == NULL)
286 {
287 UsesPattern = FALSE;
288 } else
289 if (Brush->iSolidColor == 0xFFFFFFFF)
290 {
291 PBITMAPOBJ PatternBitmap;
292
293 GdiBrush = CONTAINING_RECORD(
294 Brush,
295 GDIBRUSHOBJ,
296 BrushObject);
297
298 PatternBitmap = BITMAPOBJ_LockBitmap(GdiBrush->hbmPattern);
299 PatternSurface = BitmapToSurf(PatternBitmap, NULL);
300 BITMAPOBJ_UnlockBitmap(GdiBrush->hbmPattern);
301
302 PatternObj = (PSURFOBJ)AccessUserObject((ULONG)PatternSurface);
303 PatternWidth = PatternObj->sizlBitmap.cx;
304 PatternHeight = PatternObj->sizlBitmap.cy;
305 }
306 }
307
308 SourceY = SourcePoint->y;
309 DestBits = (PBYTE)(
310 DestSurf->pvScan0 +
311 (DestRect->left << 1) + DestRect->left +
312 DestRect->top * DestSurf->lDelta);
313
314 for (Y = DestRect->top; Y < DestRect->bottom; Y++)
315 {
316 SourceX = SourcePoint->x;
317 for (X = DestRect->left; X < DestRect->right; X++, DestBits += 3, SourceX++)
318 {
319 Dest = *((PUSHORT)DestBits) + (*(DestBits + 2) << 16);
320
321 if (UsesSource)
322 {
323 Source = DIB_GetSource(SourceSurf, SourceGDI, SourceX, SourceY, ColorTranslation);
324 }
325
326 if (UsesPattern)
327 {
328 if (Brush->iSolidColor == 0xFFFFFFFF)
329 {
330 Pattern = DIB_1BPP_GetPixel(PatternObj, X % PatternWidth, Y % PatternHeight) ? GdiBrush->crFore : GdiBrush->crBack;
331 }
332 else
333 {
334 Pattern = Brush->iSolidColor;
335 }
336 }
337
338 Dest = DIB_DoRop(Rop4, Dest, Source, Pattern) & 0xFFFFFF;
339 *(PUSHORT)(DestBits) = Dest & 0xFFFF;
340 *(DestBits + 2) = Dest >> 16;
341 }
342
343 SourceY++;
344 DestBits -= (DestRect->right - DestRect->left) * 3;
345 DestBits += DestSurf->lDelta;
346 }
347
348 if (PatternSurface != NULL)
349 EngDeleteSurface(PatternSurface);
350
351 return TRUE;
352 }
353
354 BOOLEAN DIB_24BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
355 SURFGDI *DestGDI, SURFGDI *SourceGDI,
356 RECTL* DestRect, RECTL *SourceRect,
357 POINTL* MaskOrigin, POINTL* BrushOrigin,
358 XLATEOBJ *ColorTranslation, ULONG Mode)
359 {
360 DbgPrint("DIB_24BPP_StretchBlt: Source BPP: %u\n", SourceGDI->BitsPerPixel);
361 return FALSE;
362 }
363
364 BOOLEAN
365 DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
366 PSURFGDI DestGDI, PSURFGDI SourceGDI,
367 RECTL* DestRect, POINTL *SourcePoint,
368 XLATEOBJ *ColorTranslation, ULONG iTransColor)
369 {
370 return FALSE;
371 }
372
373 /* EOF */