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