1 /*
2 * PROJECT: Win32 subsystem
3 * LICENSE: See COPYING in the top level directory
4 * FILE: win32ss/gdi/dib/dib8bpp.c
5 * PURPOSE: Device Independant Bitmap functions, 8bpp
6 * PROGRAMMERS: Jason Filby
7 * Thomas Bluemel
8 * Gregor Anich
9 * Doug Lyons
10 */
11
12 #include <win32k.h>
13
14 #define NDEBUG
15 #include <debug.h>
16
17 #define DEC_OR_INC(var, decTrue, amount) \
18 ((var) = (decTrue) ? ((var) - (amount)) : ((var) + (amount)))
19
20 VOID
DIB_8BPP_PutPixel(SURFOBJ * SurfObj,LONG x,LONG y,ULONG c)21 DIB_8BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
22 {
23 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + x;
24
25 *byteaddr = (BYTE)c;
26 }
27
28 ULONG
DIB_8BPP_GetPixel(SURFOBJ * SurfObj,LONG x,LONG y)29 DIB_8BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
30 {
31 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + x;
32
33 return (ULONG)(*byteaddr);
34 }
35
36 VOID
DIB_8BPP_HLine(SURFOBJ * SurfObj,LONG x1,LONG x2,LONG y,ULONG c)37 DIB_8BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
38 {
39 memset((PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + x1, (BYTE) c, x2 - x1);
40 }
41
42 VOID
DIB_8BPP_VLine(SURFOBJ * SurfObj,LONG x,LONG y1,LONG y2,ULONG c)43 DIB_8BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
44 {
45 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y1 * SurfObj->lDelta;
46 PBYTE addr = byteaddr + x;
47 LONG lDelta = SurfObj->lDelta;
48
49 byteaddr = addr;
50 while(y1++ < y2)
51 {
52 *addr = (BYTE)c;
53
54 addr += lDelta;
55 }
56 }
57
58 BOOLEAN
DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo)59 DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo)
60 {
61 LONG i, j, sx, sy, xColor, f1;
62 PBYTE SourceBits, DestBits, SourceLine, DestLine;
63 PBYTE SourceBits_4BPP, SourceLine_4BPP;
64 BOOLEAN bTopToBottom, bLeftToRight;
65
66 DPRINT("DIB_8BPP_BitBltSrcCopy: SrcSurf cx/cy (%d/%d), DestSuft cx/cy (%d/%d) dstRect: (%d,%d)-(%d,%d)\n",
67 BltInfo->SourceSurface->sizlBitmap.cx, BltInfo->SourceSurface->sizlBitmap.cy,
68 BltInfo->DestSurface->sizlBitmap.cx, BltInfo->DestSurface->sizlBitmap.cy,
69 BltInfo->DestRect.left, BltInfo->DestRect.top, BltInfo->DestRect.right, BltInfo->DestRect.bottom);
70
71 /* Get back left to right flip here */
72 bLeftToRight = (BltInfo->DestRect.left > BltInfo->DestRect.right);
73
74 /* Check for top to bottom flip needed. */
75 bTopToBottom = BltInfo->DestRect.top > BltInfo->DestRect.bottom;
76
77 DPRINT("bTopToBottom is '%d' and bLeftToRight is '%d'.\n", bTopToBottom, bLeftToRight);
78
79 /* Make WellOrdered by making top < bottom and left < right */
80 RECTL_vMakeWellOrdered(&BltInfo->DestRect);
81
82 DPRINT("BPP is '%d' & BltInfo->SourcePoint.x is '%d' & BltInfo->SourcePoint.y is '%d'.\n",
83 BltInfo->SourceSurface->iBitmapFormat, BltInfo->SourcePoint.x, BltInfo->SourcePoint.y);
84
85 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left;
86
87 switch(BltInfo->SourceSurface->iBitmapFormat)
88 {
89 case BMF_1BPP:
90 DPRINT("1BPP Case Selected with DestRect Width of '%d'.\n",
91 BltInfo->DestRect.right - BltInfo->DestRect.left);
92
93 sx = BltInfo->SourcePoint.x;
94
95 /* This sets sy to the top line */
96 sy = BltInfo->SourcePoint.y;
97
98 if (bTopToBottom)
99 {
100 /* This sets sy to the bottom line */
101 sy += BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1;
102 }
103
104 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
105 {
106 sx = BltInfo->SourcePoint.x;
107
108 if (bLeftToRight)
109 {
110 /* This sets the sx to the rightmost pixel */
111 sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
112 }
113
114 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
115 {
116 if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
117 {
118 DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0));
119 }
120 else
121 {
122 DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
123 }
124 DEC_OR_INC(sx, bLeftToRight, 1);
125 }
126 DEC_OR_INC(sy, bTopToBottom, 1);
127 }
128 break;
129
130 case BMF_4BPP:
131 DPRINT("4BPP Case Selected with DestRect Width of '%d'.\n",
132 BltInfo->DestRect.right - BltInfo->DestRect.left);
133
134 /* This sets SourceBits_4BPP to the top line */
135 SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1);
136
137 if (bTopToBottom)
138 {
139 /* This sets SourceBits_4BPP to the bottom line */
140 SourceBits_4BPP += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta;
141 }
142
143 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
144 {
145 SourceLine_4BPP = SourceBits_4BPP;
146 sx = BltInfo->SourcePoint.x;
147
148 if (bLeftToRight)
149 {
150 /* This sets sx to the rightmost pixel */
151 sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
152 }
153
154 f1 = sx & 1;
155
156 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
157 {
158 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest,
159 (*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1)));
160 DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, xColor);
161 if(f1 == 1)
162 {
163 DEC_OR_INC(SourceLine_4BPP, bLeftToRight, 1);
164 f1 = 0;
165 }
166 else
167 {
168 f1 = 1;
169 }
170
171 DEC_OR_INC(sx, bLeftToRight, 1);
172 }
173 DEC_OR_INC(SourceBits_4BPP, bTopToBottom, BltInfo->SourceSurface->lDelta);
174 }
175 break;
176
177 case BMF_8BPP:
178 DPRINT("8BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n",
179 BltInfo->DestRect.left, BltInfo->DestRect.top,
180 BltInfo->DestRect.right, BltInfo->DestRect.bottom,
181 BltInfo->DestRect.right - BltInfo->DestRect.left);
182
183 if ((BltInfo->XlateSourceToDest == NULL ||
184 (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL) != 0) &&
185 (!bTopToBottom && !bLeftToRight))
186 {
187 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
188 {
189 DPRINT("BltInfo->DestRect.top < BltInfo->SourcePoint.y.\n");
190 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
191 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
192 {
193 RtlMoveMemory(DestBits, SourceBits, BltInfo->DestRect.right - BltInfo->DestRect.left);
194 SourceBits += BltInfo->SourceSurface->lDelta;
195 DestBits += BltInfo->DestSurface->lDelta;
196 }
197 }
198 else
199 {
200 DPRINT("BltInfo->DestRect.top >= BltInfo->SourcePoint.y.\n");
201 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
202 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left;
203 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
204 {
205 RtlMoveMemory(DestBits, SourceBits, BltInfo->DestRect.right - BltInfo->DestRect.left);
206 SourceBits -= BltInfo->SourceSurface->lDelta;
207 DestBits -= BltInfo->DestSurface->lDelta;
208 }
209 }
210 }
211 else
212 {
213 DPRINT("XO_TRIVIAL is NOT TRUE or we have flips.\n");
214
215 if (!bTopToBottom && !bLeftToRight)
216 /* **Note: Indent is purposefully less than desired to keep reviewable differences to a minimum for PR** */
217 {
218 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
219 {
220 DPRINT("Dest.top < SourcePoint.y.\n");
221 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
222 DestLine = DestBits;
223 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
224 {
225 SourceBits = SourceLine;
226 DestBits = DestLine;
227 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
228 {
229 *DestBits++ = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits++);
230 }
231 SourceLine += BltInfo->SourceSurface->lDelta;
232 DestLine += BltInfo->DestSurface->lDelta;
233 }
234 }
235 else
236 {
237 DPRINT("Dest.top >= SourcePoint.y.\n");
238 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
239 DestLine = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left;
240 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
241 {
242 SourceBits = SourceLine;
243 DestBits = DestLine;
244 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
245 {
246 *DestBits++ = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits++);
247 }
248 SourceLine -= BltInfo->SourceSurface->lDelta;
249 DestLine -= BltInfo->DestSurface->lDelta;
250 }
251 }
252 }
253 else
254 {
255 /* Buffering for source and destination flip overlaps. Fixes KHMZ MirrorTest CORE-16642 */
256 BOOL OneDone = FALSE;
257
258 if (bLeftToRight)
259 {
260 DPRINT("Flip is bLeftToRight.\n");
261
262 /* Allocate enough pixels for a row in BYTE's */
263 BYTE *store = ExAllocatePoolWithTag(NonPagedPool,
264 BltInfo->DestRect.right - BltInfo->DestRect.left + 1, TAG_DIB);
265 if (store == NULL)
266 {
267 DPRINT1("Storage Allocation Failed.\n");
268 return FALSE;
269 }
270 WORD Index;
271
272 /* This sets SourceLine to the top line */
273 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 +
274 (BltInfo->SourcePoint.y *
275 BltInfo->SourceSurface->lDelta) +
276 BltInfo->SourcePoint.x;
277
278 /* This set the DestLine to the top line */
279 DestLine = (PBYTE)BltInfo->DestSurface->pvScan0 +
280 (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) +
281 BltInfo->DestRect.left;
282
283 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
284 {
285 SourceBits = SourceLine;
286 DestBits = DestLine;
287
288 /* This sets SourceBits to the rightmost pixel */
289 SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
290
291 Index = 0;
292
293 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
294 {
295 store[Index] = (BYTE)XLATEOBJ_iXlate(
296 BltInfo->XlateSourceToDest,
297 *SourceBits);
298 SourceBits--;
299 Index++;
300 }
301
302 Index = 0;
303
304 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
305 {
306 *DestBits = store[Index];
307 DestBits++;
308 Index++;
309 }
310
311 SourceLine += BltInfo->SourceSurface->lDelta;
312 DestLine += BltInfo->DestSurface->lDelta;
313 }
314 ExFreePoolWithTag(store, TAG_DIB);
315 OneDone = TRUE;
316 }
317
318 if (bTopToBottom)
319 {
320 DPRINT("Flip is bTopToBottom.\n");
321
322 DWORD Index;
323
324 /* Allocate enough pixels for a column in BYTE's */
325 BYTE *store = ExAllocatePoolWithTag(NonPagedPool,
326 BltInfo->DestRect.bottom - BltInfo->DestRect.top + 1, TAG_DIB);
327 if (store == NULL)
328 {
329 DPRINT1("Storage Allocation Failed.\n");
330 return FALSE;
331 }
332
333 /* The OneDone flag indicates that we are flipping for bTopToBottom and bLeftToRight
334 * and have already completed the bLeftToRight. So we will lose our first flip output
335 * unless we work with its output which is at the destination site. So in this case
336 * our new Source becomes the previous outputs Destination. */
337
338 if (OneDone)
339 {
340 /* This sets SourceLine to the bottom line of our previous destination */
341 SourceLine = (PBYTE)BltInfo->DestSurface->pvScan0 +
342 (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left +
343 (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->DestSurface->lDelta;
344 }
345 else
346 {
347 /* This sets SourceLine to the bottom line */
348 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 +
349 ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1)
350 * BltInfo->SourceSurface->lDelta) +
351 BltInfo->SourcePoint.x;
352 }
353
354 /* This set the DestLine to the top line */
355 DestLine = (PBYTE)BltInfo->DestSurface->pvScan0 +
356 (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) +
357 BltInfo->DestRect.left;
358
359 /* Read columns */
360 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
361 {
362
363 DestBits = DestLine;
364 SourceBits = SourceLine;
365
366 Index = 0;
367
368 /* Read up the column and store the pixels */
369 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
370 {
371 store[Index] = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits);
372 /* Go up a line */
373 SourceBits -= BltInfo->SourceSurface->lDelta;
374 Index++;
375 }
376
377 Index = 0;
378
379 /* Get the stored pixel and copy then down the column */
380 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
381 {
382 *DestBits = store[Index];
383 /* Go down a line */
384 DestBits += BltInfo->SourceSurface->lDelta;
385 Index++;
386 }
387 /* Index to next column */
388 SourceLine += 1;
389 DestLine += 1;
390 }
391 ExFreePoolWithTag(store, TAG_DIB);
392 }
393
394 }
395 }
396 break;
397
398 case BMF_16BPP:
399 DPRINT("16BPP Case Selected with DestRect Width of '%d'.\n",
400 BltInfo->DestRect.right - BltInfo->DestRect.left);
401
402 DPRINT("BMF_16BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n",
403 BltInfo->DestRect.left, BltInfo->DestRect.top,
404 BltInfo->DestRect.right, BltInfo->DestRect.bottom,
405 BltInfo->DestRect.right - BltInfo->DestRect.left);
406
407 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
408
409 if (bTopToBottom)
410 {
411 /* This sets SourceLine to the bottom line */
412 SourceLine += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta;;
413 }
414 DestLine = DestBits;
415
416 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
417 {
418 SourceBits = SourceLine;
419
420 if (bLeftToRight)
421 {
422 /* This sets SourceBits to the rightmost pixel */
423 SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 2;
424 }
425 DestBits = DestLine;
426
427 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
428 {
429 xColor = *((PWORD) SourceBits);
430 *DestBits = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
431
432 DEC_OR_INC(SourceBits, bLeftToRight, 2);
433 DestBits += 1;
434 }
435 DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
436 DestLine += BltInfo->DestSurface->lDelta;
437 }
438 break;
439
440 case BMF_24BPP:
441 DPRINT("24BPP-dstRect: (%d,%d)-(%d,%d) and Width of '%d'.\n",
442 BltInfo->DestRect.left, BltInfo->DestRect.top,
443 BltInfo->DestRect.right, BltInfo->DestRect.bottom,
444 BltInfo->DestRect.right - BltInfo->DestRect.left);
445
446 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
447 DestLine = DestBits;
448
449 if (bTopToBottom)
450 {
451 /* This sets SourceLine to the bottom line */
452 SourceLine += BltInfo->SourceSurface->lDelta * (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
453 }
454
455 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
456 {
457 SourceBits = SourceLine;
458 DestBits = DestLine;
459
460 if (bLeftToRight)
461 {
462 /* This sets the SourceBits to the rightmost pixel */
463 SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 3;
464 }
465
466 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
467 {
468 xColor = (*(SourceBits + 2) << 0x10) +
469 (*(SourceBits + 1) << 0x08) +
470 (*(SourceBits));
471 *DestBits = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
472 DEC_OR_INC(SourceBits, bLeftToRight, 3);
473 DestBits += 1;
474 }
475 DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
476 DestLine += BltInfo->DestSurface->lDelta;
477 }
478 break;
479
480 case BMF_32BPP:
481 DPRINT("32BPP Case Selected with DestRect Width of '%d'.\n",
482 BltInfo->DestRect.right - BltInfo->DestRect.left);
483
484 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
485
486 if (bTopToBottom)
487 {
488 /* This sets SourceLine to the bottom line */
489 SourceLine += BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1;
490 }
491 DestLine = DestBits;
492
493 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
494 {
495 SourceBits = SourceLine;
496 DestBits = DestLine;
497
498 if (bLeftToRight)
499 {
500 /* This sets SourceBits to the rightmost pixel */
501 SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 4;
502 }
503
504 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
505 {
506 xColor = *((PDWORD) SourceBits);
507 *DestBits = (BYTE)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
508
509 DEC_OR_INC(SourceBits, bLeftToRight, 4);
510 DestBits += 1;
511 }
512 DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
513 DestLine += BltInfo->DestSurface->lDelta;
514 }
515 break;
516
517 default:
518 DPRINT1("DIB_8BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
519 return FALSE;
520 }
521
522 return TRUE;
523 }
524
525 /* BitBlt Optimize */
526 BOOLEAN
DIB_8BPP_ColorFill(SURFOBJ * DestSurface,RECTL * DestRect,ULONG color)527 DIB_8BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
528 {
529 LONG DestY;
530
531 /* Make WellOrdered by making top < bottom and left < right */
532 RECTL_vMakeWellOrdered(DestRect);
533
534 for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
535 {
536 DIB_8BPP_HLine(DestSurface, DestRect->left, DestRect->right, DestY, color);
537 }
538 return TRUE;
539 }
540
541
542 BOOLEAN
DIB_8BPP_TransparentBlt(SURFOBJ * DestSurf,SURFOBJ * SourceSurf,RECTL * DestRect,RECTL * SourceRect,XLATEOBJ * ColorTranslation,ULONG iTransColor)543 DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
544 RECTL* DestRect, RECTL *SourceRect,
545 XLATEOBJ *ColorTranslation, ULONG iTransColor)
546 {
547 LONG RoundedRight, X, Y, SourceX = 0, SourceY = 0;
548 ULONG *DestBits, Source, Dest;
549
550 LONG DstHeight;
551 LONG DstWidth;
552 LONG SrcHeight;
553 LONG SrcWidth;
554
555 DstHeight = DestRect->bottom - DestRect->top;
556 DstWidth = DestRect->right - DestRect->left;
557 SrcHeight = SourceRect->bottom - SourceRect->top;
558 SrcWidth = SourceRect->right - SourceRect->left;
559
560 RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x3);
561 DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestRect->left +
562 (DestRect->top * DestSurf->lDelta));
563
564 for(Y = DestRect->top; Y < DestRect->bottom; Y++)
565 {
566 DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestRect->left +
567 (Y * DestSurf->lDelta));
568 SourceY = SourceRect->top+(Y - DestRect->top) * SrcHeight / DstHeight;
569 for (X = DestRect->left; X < RoundedRight; X += 4, DestBits++)
570 {
571 Dest = *DestBits;
572
573 SourceX = SourceRect->left+(X - DestRect->left) * SrcWidth / DstWidth;
574 if (SourceX >= 0 && SourceY >= 0 &&
575 SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
576 {
577 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
578 if(Source != iTransColor)
579 {
580 Dest &= 0xFFFFFF00;
581 Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF);
582 }
583 }
584
585 SourceX = SourceRect->left+(X+1 - DestRect->left) * SrcWidth / DstWidth;
586 if (SourceX >= 0 && SourceY >= 0 &&
587 SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
588 {
589 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
590 if(Source != iTransColor)
591 {
592 Dest &= 0xFFFF00FF;
593 Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 8) & 0xFF00);
594 }
595 }
596
597 SourceX = SourceRect->left+(X+2 - DestRect->left) * SrcWidth / DstWidth;
598 if (SourceX >= 0 && SourceY >= 0 &&
599 SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
600 {
601 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
602 if(Source != iTransColor)
603 {
604 Dest &= 0xFF00FFFF;
605 Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 16) & 0xFF0000);
606 }
607 }
608
609 SourceX = SourceRect->left+(X+3 - DestRect->left) * SrcWidth / DstWidth;
610 if (SourceX >= 0 && SourceY >= 0 &&
611 SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
612 {
613 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
614 if(Source != iTransColor)
615 {
616 Dest &= 0x00FFFFFF;
617 Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 24) & 0xFF000000);
618 }
619 }
620
621 *DestBits = Dest;
622 }
623
624 if(X < DestRect->right)
625 {
626 for (; X < DestRect->right; X++)
627 {
628 SourceX = SourceRect->left+(X - DestRect->left) * SrcWidth / DstWidth;
629 if (SourceX >= 0 && SourceY >= 0 &&
630 SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
631 {
632 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
633 if(Source != iTransColor)
634 {
635 *((BYTE*)DestBits) = (BYTE)(XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF);
636 }
637 }
638 DestBits = (PULONG)((ULONG_PTR)DestBits + 1);
639 }
640 }
641 }
642
643 return TRUE;
644 }
645
646 /* EOF */
647