use a common header for most files in win32k to make use of precompiled headers
[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.26 2004/05/10 17:07:17 weiden Exp $ */
20 #include <w32k.h>
21
22 VOID
23 DIB_24BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
24 {
25 PBYTE addr = SurfObj->pvScan0 + (y * SurfObj->lDelta) + (x << 1) + x;
26 *(PUSHORT)(addr) = c & 0xFFFF;
27 *(addr + 2) = (c >> 16) & 0xFF;
28 }
29
30 ULONG
31 DIB_24BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
32 {
33 PBYTE addr = SurfObj->pvScan0 + y * SurfObj->lDelta + (x << 1) + x;
34 return *(PUSHORT)(addr) + (*(addr + 2) << 16);
35 }
36
37 VOID
38 DIB_24BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
39 {
40 PBYTE addr = SurfObj->pvScan0 + y * SurfObj->lDelta + (x1 << 1) + x1;
41 LONG cx = x1;
42
43 c &= 0xFFFFFF;
44 while(cx < x2) {
45 *(PUSHORT)(addr) = c & 0xFFFF;
46 addr += 2;
47 *(addr) = c >> 16;
48 addr += 1;
49 ++cx;
50 }
51 }
52
53 VOID
54 DIB_24BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
55 {
56 PBYTE addr = SurfObj->pvScan0 + y1 * SurfObj->lDelta + (x << 1) + x;
57 LONG lDelta = SurfObj->lDelta;
58
59 c &= 0xFFFFFF;
60 while(y1++ < y2) {
61 *(PUSHORT)(addr) = c & 0xFFFF;
62 *(addr + 2) = c >> 16;
63
64 addr += lDelta;
65 }
66 }
67
68 BOOLEAN
69 DIB_24BPP_BitBltSrcCopy( SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
70 SURFGDI *DestGDI, SURFGDI *SourceGDI,
71 PRECTL DestRect, POINTL *SourcePoint,
72 XLATEOBJ *ColorTranslation)
73 {
74 LONG i, j, sx, sy, xColor, f1;
75 PBYTE SourceBits, DestBits, SourceLine, DestLine;
76 PBYTE SourceBits_4BPP, SourceLine_4BPP;
77 PWORD SourceBits_16BPP, SourceLine_16BPP;
78
79 DestBits = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + DestRect->left * 3;
80
81 switch(SourceGDI->BitsPerPixel)
82 {
83 case 1:
84 sx = SourcePoint->x;
85 sy = SourcePoint->y;
86
87 for (j=DestRect->top; j<DestRect->bottom; j++)
88 {
89 sx = SourcePoint->x;
90 for (i=DestRect->left; i<DestRect->right; i++)
91 {
92 if(DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
93 {
94 DIB_24BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 0));
95 } else {
96 DIB_24BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 1));
97 }
98 sx++;
99 }
100 sy++;
101 }
102 break;
103
104 case 4:
105 SourceBits_4BPP = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + (SourcePoint->x >> 1);
106
107 for (j=DestRect->top; j<DestRect->bottom; j++)
108 {
109 SourceLine_4BPP = SourceBits_4BPP;
110 DestLine = DestBits;
111 sx = SourcePoint->x;
112 f1 = sx & 1;
113
114 for (i=DestRect->left; i<DestRect->right; i++)
115 {
116 xColor = XLATEOBJ_iXlate(ColorTranslation,
117 (*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1)));
118 *DestLine++ = xColor & 0xff;
119 *(PWORD)DestLine = xColor >> 8;
120 DestLine += 2;
121 if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
122 sx++;
123 }
124
125 SourceBits_4BPP += SourceSurf->lDelta;
126 DestBits += DestSurf->lDelta;
127 }
128 break;
129
130 case 8:
131 SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x;
132 DestLine = DestBits;
133
134 for (j = DestRect->top; j < DestRect->bottom; j++)
135 {
136 SourceBits = SourceLine;
137 DestBits = DestLine;
138
139 for (i = DestRect->left; i < DestRect->right; i++)
140 {
141 xColor = XLATEOBJ_iXlate(ColorTranslation, *SourceBits);
142 *DestBits = xColor & 0xff;
143 *(PWORD)(DestBits + 1) = xColor >> 8;
144 SourceBits += 1;
145 DestBits += 3;
146 }
147
148 SourceLine += SourceSurf->lDelta;
149 DestLine += DestSurf->lDelta;
150 }
151 break;
152
153 case 16:
154 SourceBits_16BPP = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 2 * SourcePoint->x;
155
156 for (j=DestRect->top; j<DestRect->bottom; j++)
157 {
158 SourceLine_16BPP = SourceBits_16BPP;
159 DestLine = DestBits;
160
161 for (i=DestRect->left; i<DestRect->right; i++)
162 {
163 xColor = XLATEOBJ_iXlate(ColorTranslation, *SourceLine_16BPP);
164 *DestLine++ = xColor & 0xff;
165 *(PWORD)DestLine = xColor >> 8;
166 DestLine += 2;
167 SourceLine_16BPP++;
168 }
169
170 SourceBits_16BPP = (PWORD)((PBYTE)SourceBits_16BPP + SourceSurf->lDelta);
171 DestBits += DestSurf->lDelta;
172 }
173 break;
174
175 case 24:
176 if (NULL == ColorTranslation || 0 != (ColorTranslation->flXlate & XO_TRIVIAL))
177 {
178 if (DestRect->top < SourcePoint->y)
179 {
180 SourceBits = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 3 * SourcePoint->x;
181 for (j = DestRect->top; j < DestRect->bottom; j++)
182 {
183 RtlMoveMemory(DestBits, SourceBits, 3 * (DestRect->right - DestRect->left));
184 SourceBits += SourceSurf->lDelta;
185 DestBits += DestSurf->lDelta;
186 }
187 }
188 else
189 {
190 SourceBits = SourceSurf->pvScan0 + ((SourcePoint->y + DestRect->bottom - DestRect->top - 1) * SourceSurf->lDelta) + 3 * SourcePoint->x;
191 DestBits = DestSurf->pvScan0 + ((DestRect->bottom - 1) * DestSurf->lDelta) + 3 * DestRect->left;
192 for (j = DestRect->bottom - 1; DestRect->top <= j; j--)
193 {
194 RtlMoveMemory(DestBits, SourceBits, 3 * (DestRect->right - DestRect->left));
195 SourceBits -= SourceSurf->lDelta;
196 DestBits -= DestSurf->lDelta;
197 }
198 }
199 }
200 else
201 {
202 /* FIXME */
203 DPRINT1("DIB_24BPP_Bitblt: Unhandled ColorTranslation for 16 -> 16 copy");
204 return FALSE;
205 }
206 break;
207
208 case 32:
209 SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 4 * SourcePoint->x;
210 DestLine = DestBits;
211
212 for (j = DestRect->top; j < DestRect->bottom; j++)
213 {
214 SourceBits = SourceLine;
215 DestBits = DestLine;
216
217 for (i = DestRect->left; i < DestRect->right; i++)
218 {
219 xColor = XLATEOBJ_iXlate(ColorTranslation, *((PDWORD) SourceBits));
220 *DestBits = xColor & 0xff;
221 *(PWORD)(DestBits + 1) = xColor >> 8;
222 SourceBits += 4;
223 DestBits += 3;
224 }
225
226 SourceLine += SourceSurf->lDelta;
227 DestLine += DestSurf->lDelta;
228 }
229 break;
230
231 default:
232 DbgPrint("DIB_24BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
233 return FALSE;
234 }
235
236 return TRUE;
237 }
238
239 BOOLEAN
240 DIB_24BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
241 SURFGDI *DestGDI, SURFGDI *SourceGDI,
242 PRECTL DestRect, POINTL *SourcePoint,
243 BRUSHOBJ *Brush, POINTL BrushOrigin,
244 XLATEOBJ *ColorTranslation, ULONG Rop4)
245 {
246 ULONG X, Y;
247 ULONG SourceX, SourceY;
248 ULONG Dest, Source, Pattern = 0, PatternY;
249 PBYTE DestBits;
250 BOOL UsesSource;
251 BOOL UsesPattern;
252 /* Pattern brushes */
253 PGDIBRUSHOBJ GdiBrush;
254 HBITMAP PatternSurface = NULL;
255 SURFOBJ *PatternObj;
256 ULONG PatternWidth, PatternHeight;
257
258 if (Rop4 == SRCCOPY)
259 {
260 return DIB_24BPP_BitBltSrcCopy(
261 DestSurf,
262 SourceSurf,
263 DestGDI,
264 SourceGDI,
265 DestRect,
266 SourcePoint,
267 ColorTranslation);
268 }
269
270 UsesSource = ((Rop4 & 0xCC0000) >> 2) != (Rop4 & 0x330000);
271 UsesPattern = (((Rop4 & 0xF00000) >> 4) != (Rop4 & 0x0F0000)) && Brush;
272
273 if (UsesPattern)
274 {
275 if (Brush->iSolidColor == 0xFFFFFFFF)
276 {
277 PBITMAPOBJ PatternBitmap;
278
279 GdiBrush = CONTAINING_RECORD(
280 Brush,
281 GDIBRUSHOBJ,
282 BrushObject);
283
284 PatternBitmap = BITMAPOBJ_LockBitmap(GdiBrush->hbmPattern);
285 PatternSurface = BitmapToSurf(PatternBitmap, NULL);
286 BITMAPOBJ_UnlockBitmap(GdiBrush->hbmPattern);
287
288 PatternObj = (SURFOBJ*)AccessUserObject((ULONG)PatternSurface);
289 PatternWidth = PatternObj->sizlBitmap.cx;
290 PatternHeight = PatternObj->sizlBitmap.cy;
291
292 UsesPattern = TRUE;
293 }
294 else
295 {
296 UsesPattern = FALSE;
297 Pattern = Brush->iSolidColor;
298 }
299 }
300
301 SourceY = SourcePoint->y;
302 DestBits = (PBYTE)(
303 DestSurf->pvScan0 +
304 (DestRect->left << 1) + DestRect->left +
305 DestRect->top * DestSurf->lDelta);
306
307 for (Y = DestRect->top; Y < DestRect->bottom; Y++)
308 {
309 SourceX = SourcePoint->x;
310
311 if(UsesPattern)
312 PatternY = (Y + BrushOrigin.y) % PatternHeight;
313
314 for (X = DestRect->left; X < DestRect->right; X++, DestBits += 3, SourceX++)
315 {
316 Dest = *((PUSHORT)DestBits) + (*(DestBits + 2) << 16);
317
318 if (UsesSource)
319 {
320 Source = DIB_GetSource(SourceSurf, SourceGDI, SourceX, SourceY, ColorTranslation);
321 }
322
323 if (UsesPattern)
324 {
325 Pattern = DIB_1BPP_GetPixel(PatternObj, (X + BrushOrigin.x) % PatternWidth, PatternY) ? GdiBrush->crFore : GdiBrush->crBack;
326 }
327
328 Dest = DIB_DoRop(Rop4, Dest, Source, Pattern) & 0xFFFFFF;
329 *(PUSHORT)(DestBits) = Dest & 0xFFFF;
330 *(DestBits + 2) = Dest >> 16;
331 }
332
333 SourceY++;
334 DestBits -= (DestRect->right - DestRect->left) * 3;
335 DestBits += DestSurf->lDelta;
336 }
337
338 if (PatternSurface != NULL)
339 EngDeleteSurface((HSURF)PatternSurface);
340
341 return TRUE;
342 }
343
344 BOOLEAN DIB_24BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
345 SURFGDI *DestGDI, SURFGDI *SourceGDI,
346 RECTL* DestRect, RECTL *SourceRect,
347 POINTL* MaskOrigin, POINTL BrushOrigin,
348 XLATEOBJ *ColorTranslation, ULONG Mode)
349 {
350 DbgPrint("DIB_24BPP_StretchBlt: Source BPP: %u\n", SourceGDI->BitsPerPixel);
351 return FALSE;
352 }
353
354 BOOLEAN
355 DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
356 PSURFGDI DestGDI, PSURFGDI SourceGDI,
357 RECTL* DestRect, POINTL *SourcePoint,
358 XLATEOBJ *ColorTranslation, ULONG iTransColor)
359 {
360 ULONG X, Y, SourceX, SourceY, Source, wd, Dest;
361 BYTE *DestBits;
362
363 SourceY = SourcePoint->y;
364 DestBits = (BYTE*)(DestSurf->pvScan0 +
365 (DestRect->left << 2) +
366 DestRect->top * DestSurf->lDelta);
367 wd = DestSurf->lDelta - ((DestRect->right - DestRect->left) << 2);
368
369 for(Y = DestRect->top; Y < DestRect->bottom; Y++)
370 {
371 SourceX = SourcePoint->x;
372 for(X = DestRect->left; X < DestRect->right; X++, DestBits += 3, SourceX++)
373 {
374 Source = DIB_GetSourceIndex(SourceSurf, SourceGDI, SourceX, SourceY);
375 if(Source != iTransColor)
376 {
377 Dest = XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFFFF;
378 *(PUSHORT)(DestBits) = Dest & 0xFFFF;
379 *(DestBits + 2) = Dest >> 16;
380 }
381 }
382
383 SourceY++;
384 DestBits = (BYTE*)((ULONG_PTR)DestBits + wd);
385 }
386
387 return TRUE;
388 }
389
390 /* EOF */