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