implemented TransparentBlt() on 8bpp surfaces
[reactos.git] / reactos / 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: dib8bpp.c,v 1.19 2004/04/06 23:05:36 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_8BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c)
34 {
35 PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta + x;
36
37 *byteaddr = c;
38 }
39
40 ULONG
41 DIB_8BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y)
42 {
43 PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta + x;
44
45 return (ULONG)(*byteaddr);
46 }
47
48 VOID
49 DIB_8BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
50 {
51 PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta;
52 PBYTE addr = byteaddr + x1;
53 LONG cx = x1;
54
55 while(cx < x2) {
56 *addr = c;
57 ++addr;
58 ++cx;
59 }
60 }
61
62 VOID
63 DIB_8BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
64 {
65 PBYTE byteaddr = SurfObj->pvScan0 + y1 * SurfObj->lDelta;
66 PBYTE addr = byteaddr + x;
67 LONG lDelta = SurfObj->lDelta;
68
69 byteaddr = addr;
70 while(y1++ < y2) {
71 *addr = c;
72
73 addr += lDelta;
74 }
75 }
76
77 BOOLEAN
78 DIB_8BPP_BitBltSrcCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
79 SURFGDI *DestGDI, SURFGDI *SourceGDI,
80 PRECTL DestRect, POINTL *SourcePoint,
81 XLATEOBJ *ColorTranslation)
82 {
83 LONG i, j, sx, sy, xColor, f1;
84 PBYTE SourceBits, DestBits, SourceLine, DestLine;
85 PBYTE SourceBits_4BPP, SourceLine_4BPP;
86
87 DestBits = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + DestRect->left;
88
89 switch(SourceGDI->BitsPerPixel)
90 {
91 case 1:
92 sx = SourcePoint->x;
93 sy = SourcePoint->y;
94
95 for (j=DestRect->top; j<DestRect->bottom; j++)
96 {
97 sx = SourcePoint->x;
98 for (i=DestRect->left; i<DestRect->right; i++)
99 {
100 if(DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
101 {
102 DIB_8BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 0));
103 } else {
104 DIB_8BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 1));
105 }
106 sx++;
107 }
108 sy++;
109 }
110 break;
111
112 case 4:
113 SourceBits_4BPP = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + (SourcePoint->x >> 1);
114
115 for (j=DestRect->top; j<DestRect->bottom; j++)
116 {
117 SourceLine_4BPP = SourceBits_4BPP;
118 sx = SourcePoint->x;
119 f1 = sx & 1;
120
121 for (i=DestRect->left; i<DestRect->right; i++)
122 {
123 xColor = XLATEOBJ_iXlate(ColorTranslation,
124 (*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1)));
125 DIB_8BPP_PutPixel(DestSurf, i, j, xColor);
126 if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
127 sx++;
128 }
129
130 SourceBits_4BPP += SourceSurf->lDelta;
131 }
132 break;
133
134 case 8:
135 if (NULL == ColorTranslation || 0 != (ColorTranslation->flXlate & XO_TRIVIAL))
136 {
137 if (DestRect->top < SourcePoint->y)
138 {
139 SourceBits = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x;
140 for (j = DestRect->top; j < DestRect->bottom; j++)
141 {
142 RtlMoveMemory(DestBits, SourceBits, DestRect->right - DestRect->left);
143 SourceBits += SourceSurf->lDelta;
144 DestBits += DestSurf->lDelta;
145 }
146 }
147 else
148 {
149 SourceBits = SourceSurf->pvScan0 + ((SourcePoint->y + DestRect->bottom - DestRect->top - 1) * SourceSurf->lDelta) + SourcePoint->x;
150 DestBits = DestSurf->pvScan0 + ((DestRect->bottom - 1) * DestSurf->lDelta) + DestRect->left;
151 for (j = DestRect->bottom - 1; DestRect->top <= j; j--)
152 {
153 RtlMoveMemory(DestBits, SourceBits, DestRect->right - DestRect->left);
154 SourceBits -= SourceSurf->lDelta;
155 DestBits -= DestSurf->lDelta;
156 }
157 }
158 }
159 else
160 {
161 if (DestRect->top < SourcePoint->y)
162 {
163 SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x;
164 DestLine = DestBits;
165 for (j = DestRect->top; j < DestRect->bottom; j++)
166 {
167 SourceBits = SourceLine;
168 DestBits = DestLine;
169 for (i=DestRect->left; i<DestRect->right; i++)
170 {
171 *DestBits++ = XLATEOBJ_iXlate(ColorTranslation, *SourceBits++);
172 }
173 SourceLine += SourceSurf->lDelta;
174 DestLine += DestSurf->lDelta;
175 }
176 }
177 else
178 {
179 SourceLine = SourceSurf->pvScan0 + ((SourcePoint->y + DestRect->bottom - DestRect->top - 1) * SourceSurf->lDelta) + SourcePoint->x;
180 DestLine = DestSurf->pvScan0 + ((DestRect->bottom - 1) * DestSurf->lDelta) + DestRect->left;
181 for (j = DestRect->bottom - 1; DestRect->top <= j; j--)
182 {
183 SourceBits = SourceLine;
184 DestBits = DestLine;
185 for (i=DestRect->left; i<DestRect->right; i++)
186 {
187 *DestBits++ = XLATEOBJ_iXlate(ColorTranslation, *SourceBits++);
188 }
189 SourceLine -= SourceSurf->lDelta;
190 DestLine -= DestSurf->lDelta;
191 }
192 }
193 }
194 break;
195
196 case 16:
197 SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 2 * SourcePoint->x;
198 DestLine = DestBits;
199
200 for (j = DestRect->top; j < DestRect->bottom; j++)
201 {
202 SourceBits = SourceLine;
203 DestBits = DestLine;
204
205 for (i = DestRect->left; i < DestRect->right; i++)
206 {
207 xColor = *((PWORD) SourceBits);
208 *DestBits = XLATEOBJ_iXlate(ColorTranslation, xColor);
209 SourceBits += 2;
210 DestBits += 1;
211 }
212
213 SourceLine += SourceSurf->lDelta;
214 DestLine += DestSurf->lDelta;
215 }
216 break;
217
218 case 24:
219 SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 3 * 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 = (*(SourceBits + 2) << 0x10) +
230 (*(SourceBits + 1) << 0x08) +
231 (*(SourceBits));
232 *DestBits = XLATEOBJ_iXlate(ColorTranslation, xColor);
233 SourceBits += 3;
234 DestBits += 1;
235 }
236
237 SourceLine += SourceSurf->lDelta;
238 DestLine += DestSurf->lDelta;
239 }
240 break;
241
242 case 32:
243 SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 4 * SourcePoint->x;
244 DestLine = DestBits;
245
246 for (j = DestRect->top; j < DestRect->bottom; j++)
247 {
248 SourceBits = SourceLine;
249 DestBits = DestLine;
250
251 for (i = DestRect->left; i < DestRect->right; i++)
252 {
253 xColor = *((PDWORD) SourceBits);
254 *DestBits = XLATEOBJ_iXlate(ColorTranslation, xColor);
255 SourceBits += 4;
256 DestBits += 1;
257 }
258
259 SourceLine += SourceSurf->lDelta;
260 DestLine += DestSurf->lDelta;
261 }
262 break;
263
264 default:
265 DbgPrint("DIB_8BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
266 return FALSE;
267 }
268
269 return TRUE;
270 }
271
272 BOOLEAN
273 DIB_8BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
274 SURFGDI *DestGDI, SURFGDI *SourceGDI,
275 PRECTL DestRect, POINTL *SourcePoint,
276 PBRUSHOBJ Brush, PPOINTL BrushOrigin,
277 XLATEOBJ *ColorTranslation, ULONG Rop4)
278 {
279 LONG i, j, k, sx, sy;
280 ULONG Dest, Source, Pattern;
281 PULONG DestBits;
282 BOOL UsesSource;
283 BOOL UsesPattern;
284 LONG RoundedRight;
285 /* Pattern brushes */
286 PGDIBRUSHOBJ GdiBrush;
287 HBITMAP PatternSurface = NULL;
288 PSURFOBJ PatternObj;
289 ULONG PatternWidth, PatternHeight;
290
291 if (Rop4 == SRCCOPY)
292 {
293 return DIB_8BPP_BitBltSrcCopy(
294 DestSurf,
295 SourceSurf,
296 DestGDI,
297 SourceGDI,
298 DestRect,
299 SourcePoint,
300 ColorTranslation);
301 }
302
303 UsesSource = ((Rop4 & 0xCC0000) >> 2) != (Rop4 & 0x330000);
304 UsesPattern = ((Rop4 & 0xF00000) >> 4) != (Rop4 & 0x0F0000);
305
306 if (UsesPattern)
307 {
308 if (Brush == NULL)
309 {
310 UsesPattern = FALSE;
311 } else
312 if (Brush->iSolidColor == 0xFFFFFFFF)
313 {
314 PBITMAPOBJ PatternBitmap;
315
316 GdiBrush = CONTAINING_RECORD(
317 Brush,
318 GDIBRUSHOBJ,
319 BrushObject);
320
321 PatternBitmap = BITMAPOBJ_LockBitmap(GdiBrush->hbmPattern);
322 PatternSurface = BitmapToSurf(PatternBitmap, NULL);
323 BITMAPOBJ_UnlockBitmap(GdiBrush->hbmPattern);
324
325 PatternObj = (PSURFOBJ)AccessUserObject((ULONG)PatternSurface);
326 PatternWidth = PatternObj->sizlBitmap.cx;
327 PatternHeight = PatternObj->sizlBitmap.cy;
328 }
329 }
330
331 RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x3);
332 sy = SourcePoint->y;
333
334 for (j = DestRect->top; j < DestRect->bottom; j++)
335 {
336 sx = SourcePoint->x;
337 DestBits = (PULONG)(DestSurf->pvScan0 + DestRect->left + j * DestSurf->lDelta);
338
339 for (i = DestRect->left; i < RoundedRight; i += 4, DestBits++)
340 {
341 Dest = *DestBits;
342
343 if (UsesSource)
344 {
345 Source = 0;
346 for (k = 0; k < 4; k++)
347 Source |= (DIB_GetSource(SourceSurf, SourceGDI, sx + (i - DestRect->left) + k, sy, ColorTranslation) << (k * 8));
348 }
349
350 if (UsesPattern)
351 {
352 if (Brush->iSolidColor == 0xFFFFFFFF)
353 {
354 Pattern = DIB_1BPP_GetPixel(PatternObj, i % PatternWidth, j % PatternHeight) ? GdiBrush->crFore : GdiBrush->crBack;
355 Pattern |= (DIB_1BPP_GetPixel(PatternObj, (i + 1) % PatternWidth, j % PatternHeight) ? GdiBrush->crFore : GdiBrush->crBack) << 8;
356 Pattern |= (DIB_1BPP_GetPixel(PatternObj, (i + 2) % PatternWidth, j % PatternHeight) ? GdiBrush->crFore : GdiBrush->crBack) << 16;
357 Pattern |= (DIB_1BPP_GetPixel(PatternObj, (i + 3) % PatternWidth, j % PatternHeight) ? GdiBrush->crFore : GdiBrush->crBack) << 24;
358 }
359 else
360 {
361 Pattern = (Brush->iSolidColor & 0xFF) |
362 ((Brush->iSolidColor & 0xFF) << 8) |
363 ((Brush->iSolidColor & 0xFF) << 16) |
364 ((Brush->iSolidColor & 0xFF) << 24);
365 }
366 }
367 *DestBits = DIB_DoRop(Rop4, Dest, Source, Pattern);
368 }
369
370 if (i < DestRect->right)
371 {
372 Dest = *DestBits;
373 for (; i < DestRect->right; i++)
374 {
375 if (UsesSource)
376 {
377 Source = DIB_GetSource(SourceSurf, SourceGDI, sx + (i - DestRect->left), sy, ColorTranslation);
378 }
379
380 if (UsesPattern)
381 {
382 if (Brush->iSolidColor == 0xFFFFFFFF)
383 Pattern = DIB_1BPP_GetPixel(PatternObj, i % PatternWidth, j % PatternHeight) ? GdiBrush->crFore : GdiBrush->crBack;
384 else
385 Pattern = Brush->iSolidColor & 0xFF;
386 }
387
388 DIB_8BPP_PutPixel(DestSurf, i, j, DIB_DoRop(Rop4, Dest, Source, Pattern) & 0xFFFF);
389 Dest >>= 8;
390 }
391 }
392
393 sy++;
394 }
395
396 if (PatternSurface != NULL)
397 EngDeleteSurface(PatternSurface);
398
399 return TRUE;
400 }
401
402 /*
403 =======================================
404 Stretching functions goes below
405 Some parts of code are based on an
406 article "Bresenhame image scaling"
407 Dr. Dobb Journal, May 2002
408 =======================================
409 */
410
411 typedef unsigned char PIXEL;
412
413 /* 16-bit HiColor (565 format) */
414 inline PIXEL average8(PIXEL a, PIXEL b)
415 {
416 return a; // FIXME: Depend on SetStretchMode
417 }
418
419 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
420 void ScaleLineAvg8(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth)
421 {
422 int NumPixels = TgtWidth;
423 int IntPart = SrcWidth / TgtWidth;
424 int FractPart = SrcWidth % TgtWidth;
425 int Mid = TgtWidth >> 1;
426 int E = 0;
427 int skip;
428 PIXEL p;
429
430 skip = (TgtWidth < SrcWidth) ? 0 : (TgtWidth / (2*SrcWidth) + 1);
431 NumPixels -= skip;
432
433 while (NumPixels-- > 0) {
434 p = *Source;
435 if (E >= Mid)
436 p = average8(p, *(Source+1));
437 *Target++ = p;
438 Source += IntPart;
439 E += FractPart;
440 if (E >= TgtWidth) {
441 E -= TgtWidth;
442 Source++;
443 } /* if */
444 } /* while */
445 while (skip-- > 0)
446 *Target++ = *Source;
447 }
448
449 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
450 void ScaleRectAvg8(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight,
451 int TgtWidth, int TgtHeight, int srcPitch, int dstPitch)
452 {
453 int NumPixels = TgtHeight;
454 int IntPart = ((SrcHeight / TgtHeight) * srcPitch); //(SrcHeight / TgtHeight) * SrcWidth;
455 int FractPart = SrcHeight % TgtHeight;
456 int Mid = TgtHeight >> 1;
457 int E = 0;
458 int skip;
459 PIXEL *ScanLine, *ScanLineAhead;
460 PIXEL *PrevSource = NULL;
461 PIXEL *PrevSourceAhead = NULL;
462
463 skip = (TgtHeight < SrcHeight) ? 0 : (TgtHeight / (2*SrcHeight) + 1);
464 NumPixels -= skip;
465
466 ScanLine = (PIXEL*)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL)); // FIXME: Should we use PagedPool here?
467 ScanLineAhead = (PIXEL *)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL));
468
469 while (NumPixels-- > 0) {
470 if (Source != PrevSource) {
471 if (Source == PrevSourceAhead) {
472 /* the next scan line has already been scaled and stored in
473 * ScanLineAhead; swap the buffers that ScanLine and ScanLineAhead
474 * point to
475 */
476 PIXEL *tmp = ScanLine;
477 ScanLine = ScanLineAhead;
478 ScanLineAhead = tmp;
479 } else {
480 ScaleLineAvg8(ScanLine, Source, SrcWidth, TgtWidth);
481 } /* if */
482 PrevSource = Source;
483 } /* if */
484
485 if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + srcPitch)) {
486 int x;
487 ScaleLineAvg8(ScanLineAhead, (PIXEL *)((BYTE *)Source + srcPitch), SrcWidth, TgtWidth);
488 for (x = 0; x < TgtWidth; x++)
489 ScanLine[x] = average8(ScanLine[x], ScanLineAhead[x]);
490 PrevSourceAhead = (PIXEL *)((BYTE *)Source + srcPitch);
491 } /* if */
492
493 memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
494 Target = (PIXEL *)((BYTE *)Target + dstPitch);
495 Source += IntPart;
496 E += FractPart;
497 if (E >= TgtHeight) {
498 E -= TgtHeight;
499 Source = (PIXEL *)((BYTE *)Source + srcPitch);
500 } /* if */
501 } /* while */
502
503 if (skip > 0 && Source != PrevSource)
504 ScaleLineAvg8(ScanLine, Source, SrcWidth, TgtWidth);
505 while (skip-- > 0) {
506 memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL));
507 Target = (PIXEL *)((BYTE *)Target + dstPitch);
508 } /* while */
509
510 ExFreePool(ScanLine);
511 ExFreePool(ScanLineAhead);
512 }
513
514 BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
515 SURFGDI *DestGDI, SURFGDI *SourceGDI,
516 RECTL* DestRect, RECTL *SourceRect,
517 POINTL* MaskOrigin, POINTL* BrushOrigin,
518 XLATEOBJ *ColorTranslation, ULONG Mode)
519 {
520 BYTE *SourceLine, *DestLine;
521
522 DbgPrint("DIB_8BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
523 SourceGDI->BitsPerPixel, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
524 DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
525
526 switch(SourceGDI->BitsPerPixel)
527 {
528 case 1:
529 return FALSE;
530 break;
531
532 case 4:
533 return FALSE;
534 break;
535
536 case 8:
537 SourceLine = SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + SourceRect->left;
538 DestLine = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + DestRect->left;
539
540 ScaleRectAvg8((PIXEL *)DestLine, (PIXEL *)SourceLine,
541 SourceRect->right-SourceRect->left, SourceRect->bottom-SourceRect->top,
542 DestRect->right-DestRect->left, DestRect->bottom-DestRect->top, SourceSurf->lDelta, DestSurf->lDelta);
543 break;
544
545 case 16:
546 return FALSE;
547 break;
548
549 case 24:
550 return FALSE;
551 break;
552
553 case 32:
554 return FALSE;
555 break;
556
557 default:
558 DbgPrint("DIB_8BPP_StretchBlt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
559 return FALSE;
560 }
561
562 return TRUE;
563 }
564
565 BOOLEAN
566 DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
567 PSURFGDI DestGDI, PSURFGDI SourceGDI,
568 RECTL* DestRect, POINTL *SourcePoint,
569 XLATEOBJ *ColorTranslation, ULONG iTransColor)
570 {
571 ULONG RoundedRight, X, Y, SourceX, SourceY, Source, wd, Dest;
572 ULONG *DestBits;
573
574 RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x3);
575 SourceY = SourcePoint->y;
576 DestBits = (ULONG*)(DestSurf->pvScan0 + DestRect->left +
577 (DestRect->top * DestSurf->lDelta));
578 wd = DestSurf->lDelta - (DestRect->right - DestRect->left);
579
580 for(Y = DestRect->top; Y < DestRect->bottom; Y++)
581 {
582 DestBits = (ULONG*)(DestSurf->pvScan0 + DestRect->left +
583 (Y * DestSurf->lDelta));
584 SourceX = SourcePoint->x;
585 for (X = DestRect->left; X < RoundedRight; X += 4, DestBits++)
586 {
587 Dest = *DestBits;
588
589 Source = DIB_GetSourceIndex(SourceSurf, SourceGDI, SourceX++, SourceY);
590 if(Source != iTransColor)
591 {
592 Dest &= 0xFFFFFF00;
593 Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF);
594 }
595
596 Source = DIB_GetSourceIndex(SourceSurf, SourceGDI, SourceX++, SourceY);
597 if(Source != iTransColor)
598 {
599 Dest &= 0xFFFF00FF;
600 Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 8) & 0xFF00);
601 }
602
603 Source = DIB_GetSourceIndex(SourceSurf, SourceGDI, SourceX++, SourceY);
604 if(Source != iTransColor)
605 {
606 Dest &= 0xFF00FFFF;
607 Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 16) & 0xFF0000);
608 }
609
610 Source = DIB_GetSourceIndex(SourceSurf, SourceGDI, SourceX++, SourceY);
611 if(Source != iTransColor)
612 {
613 Dest &= 0x00FFFFFF;
614 Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 24) & 0xFF000000);
615 }
616
617 *DestBits = Dest;
618 }
619
620 if(X < DestRect->right)
621 {
622 for (; X < DestRect->right; X++)
623 {
624 Source = DIB_GetSourceIndex(SourceSurf, SourceGDI, SourceX++, SourceY);
625 if(Source != iTransColor)
626 {
627 *((BYTE*)DestBits) = (BYTE)(XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF);
628 }
629 DestBits = (PULONG)((ULONG_PTR)DestBits + 1);
630 }
631 }
632 SourceY++;
633 }
634
635 return TRUE;
636 }
637
638 /* EOF */