Optimze DIB32_bitblt for both DGB=0 and DGB=1
[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 /* Optimze BitBlt */
349 BOOLEAN
350 DIB_8BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
351 {
352 ULONG DestY;
353 for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
354 {
355 DIB_32BPP_HLine (DestSurface, DestRect->left, DestRect->right, DestY, color);
356 }
357
358 return TRUE;
359 }
360 /*
361 =======================================
362 Stretching functions goes below
363 Some parts of code are based on an
364 article "Bresenhame image scaling"
365 Dr. Dobb Journal, May 2002
366 =======================================
367 */
368
369 typedef unsigned char PIXEL;
370
371 /* 16-bit HiColor (565 format) */
372 inline PIXEL average8(PIXEL a, PIXEL b)
373 {
374 return a; // FIXME: Depend on SetStretchMode
375 }
376
377 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
378 void ScaleLineAvg8(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth)
379 {
380 int NumPixels = TgtWidth;
381 int IntPart = SrcWidth / TgtWidth;
382 int FractPart = SrcWidth % TgtWidth;
383 int Mid = TgtWidth >> 1;
384 int E = 0;
385 int skip;
386 PIXEL p;
387
388 skip = (TgtWidth < SrcWidth) ? 0 : (TgtWidth / (2*SrcWidth) + 1);
389 NumPixels -= skip;
390
391 while (NumPixels-- > 0) {
392 p = *Source;
393 if (E >= Mid)
394 p = average8(p, *(Source+1));
395 *Target++ = p;
396 Source += IntPart;
397 E += FractPart;
398 if (E >= TgtWidth) {
399 E -= TgtWidth;
400 Source++;
401 } /* if */
402 } /* while */
403 while (skip-- > 0)
404 *Target++ = *Source;
405 }
406
407 static BOOLEAN
408 FinalCopy8(PIXEL *Target, PIXEL *Source, PSPAN ClipSpans, UINT ClipSpansCount, UINT *SpanIndex,
409 UINT DestY, RECTL *DestRect)
410 {
411 LONG Left, Right;
412
413 while (ClipSpans[*SpanIndex].Y < DestY
414 || (ClipSpans[*SpanIndex].Y == DestY
415 && ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width < DestRect->left))
416 {
417 (*SpanIndex)++;
418 if (ClipSpansCount <= *SpanIndex)
419 {
420 /* No more spans, everything else is clipped away, we're done */
421 return FALSE;
422 }
423 }
424 while (ClipSpans[*SpanIndex].Y == DestY)
425 {
426 if (ClipSpans[*SpanIndex].X < DestRect->right)
427 {
428 Left = max(ClipSpans[*SpanIndex].X, DestRect->left);
429 Right = min(ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width, DestRect->right);
430 memcpy(Target + Left - DestRect->left, Source + Left - DestRect->left,
431 (Right - Left) * sizeof(PIXEL));
432 }
433 (*SpanIndex)++;
434 if (ClipSpansCount <= *SpanIndex)
435 {
436 /* No more spans, everything else is clipped away, we're done */
437 return FALSE;
438 }
439 }
440
441 return TRUE;
442 }
443
444 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
445 BOOLEAN ScaleRectAvg8(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
446 RECTL* DestRect, RECTL *SourceRect,
447 POINTL* MaskOrigin, POINTL BrushOrigin,
448 CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
449 ULONG Mode)
450 {
451 int NumPixels = DestRect->bottom - DestRect->top;
452 int IntPart = (((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * SourceSurf->lDelta); //((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * (SourceRect->right - SourceRect->left);
453 int FractPart = (SourceRect->bottom - SourceRect->top) % (DestRect->bottom - DestRect->top);
454 int Mid = (DestRect->bottom - DestRect->top) >> 1;
455 int E = 0;
456 int skip;
457 PIXEL *ScanLine, *ScanLineAhead;
458 PIXEL *PrevSource = NULL;
459 PIXEL *PrevSourceAhead = NULL;
460 PIXEL *Target = (PIXEL *) (DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + DestRect->left);
461 PIXEL *Source = (PIXEL *) (SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + SourceRect->left);
462 PSPAN ClipSpans;
463 UINT ClipSpansCount;
464 UINT SpanIndex;
465 LONG DestY;
466
467 if (! ClipobjToSpans(&ClipSpans, &ClipSpansCount, ClipRegion, DestRect))
468 {
469 return FALSE;
470 }
471 if (0 == ClipSpansCount)
472 {
473 /* No clip spans == empty clipping region, everything clipped away */
474 ASSERT(NULL == ClipSpans);
475 return TRUE;
476 }
477 skip = (DestRect->bottom - DestRect->top < SourceRect->bottom - SourceRect->top) ? 0 : ((DestRect->bottom - DestRect->top) / (2 * (SourceRect->bottom - SourceRect->top)) + 1);
478 NumPixels -= skip;
479
480 ScanLine = (PIXEL*)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
481 ScanLineAhead = (PIXEL *)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
482
483 DestY = DestRect->top;
484 SpanIndex = 0;
485 while (NumPixels-- > 0) {
486 if (Source != PrevSource) {
487 if (Source == PrevSourceAhead) {
488 /* the next scan line has already been scaled and stored in
489 * ScanLineAhead; swap the buffers that ScanLine and ScanLineAhead
490 * point to
491 */
492 PIXEL *tmp = ScanLine;
493 ScanLine = ScanLineAhead;
494 ScanLineAhead = tmp;
495 } else {
496 ScaleLineAvg8(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
497 } /* if */
498 PrevSource = Source;
499 } /* if */
500
501 if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + SourceSurf->lDelta)) {
502 int x;
503 ScaleLineAvg8(ScanLineAhead, (PIXEL *)((BYTE *)Source + SourceSurf->lDelta), SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
504 for (x = 0; x < DestRect->right - DestRect->left; x++)
505 ScanLine[x] = average8(ScanLine[x], ScanLineAhead[x]);
506 PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceSurf->lDelta);
507 } /* if */
508
509 if (! FinalCopy8(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
510 {
511 /* No more spans, everything else is clipped away, we're done */
512 ExFreePool(ClipSpans);
513 ExFreePool(ScanLine);
514 ExFreePool(ScanLineAhead);
515 return TRUE;
516 }
517 DestY++;
518 Target = (PIXEL *)((BYTE *)Target + DestSurf->lDelta);
519 Source += IntPart;
520 E += FractPart;
521 if (E >= DestRect->bottom - DestRect->top) {
522 E -= DestRect->bottom - DestRect->top;
523 Source = (PIXEL *)((BYTE *)Source + SourceSurf->lDelta);
524 } /* if */
525 } /* while */
526
527 if (skip > 0 && Source != PrevSource)
528 ScaleLineAvg8(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
529 while (skip-- > 0) {
530 if (! FinalCopy8(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
531 {
532 /* No more spans, everything else is clipped away, we're done */
533 ExFreePool(ClipSpans);
534 ExFreePool(ScanLine);
535 ExFreePool(ScanLineAhead);
536 return TRUE;
537 }
538 DestY++;
539 Target = (PIXEL *)((BYTE *)Target + DestSurf->lDelta);
540 } /* while */
541
542 ExFreePool(ClipSpans);
543 ExFreePool(ScanLine);
544 ExFreePool(ScanLineAhead);
545
546 return TRUE;
547 }
548
549 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
550 BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
551 RECTL* DestRect, RECTL *SourceRect,
552 POINTL* MaskOrigin, POINTL BrushOrigin,
553 CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
554 ULONG Mode)
555 {
556 int SrcSizeY;
557 int SrcSizeX;
558 int DesSizeY;
559 int DesSizeX;
560 int sx;
561 int sy;
562 int DesX;
563 int DesY;
564 int color;
565 int zoomX;
566 int zoomY;
567 int count;
568 int saveX;
569 int saveY;
570 BOOLEAN DesIsBiggerY=FALSE;
571
572 DPRINT("DIB_8BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
573 BitsPerFormat(SourceSurf->iBitmapFormat), SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
574 DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
575
576 SrcSizeY = SourceRect->bottom;
577 SrcSizeX = SourceRect->right;
578
579 DesSizeY = DestRect->bottom;
580 DesSizeX = DestRect->right;
581
582 zoomX = DesSizeX / SrcSizeX;
583 if (zoomX==0) zoomX=1;
584
585 zoomY = DesSizeY / SrcSizeY;
586 if (zoomY==0) zoomY=1;
587
588 if (DesSizeY>SrcSizeY)
589 DesIsBiggerY = TRUE;
590
591 switch(SourceSurf->iBitmapFormat)
592 {
593 case BMF_1BPP:
594 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
595 /* This is a reference implementation, it hasn't been optimized for speed */
596 if (zoomX>1)
597 {
598 /* Draw one Hline on X - Led to the Des Zoom In*/
599 if (DesSizeX>SrcSizeX)
600 {
601 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
602 {
603 if (DesIsBiggerY)
604 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
605 else
606 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
607
608 if (sy > SourceRect->bottom) break;
609
610 saveY = DesY+zoomY;
611
612 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
613 {
614 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
615
616 if (sx > SourceRect->right) break;
617
618 saveX = DesX + zoomX;
619
620 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
621 for (count=DesY;count<saveY;count++)
622 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, 0);
623 else
624 for (count=DesY;count<saveY;count++)
625 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, 1);
626
627 }
628 }
629 }
630 else
631 {
632 /* Draw one Hline on X - Led to the Des Zoom Out*/
633
634 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
635 {
636 if (DesIsBiggerY)
637 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
638 else
639 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
640
641 if (sy > SourceRect->bottom) break;
642
643 saveY = DesY+zoomY;
644
645 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
646 {
647 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
648
649 if (sx > SourceRect->right) break;
650
651 saveX = DesX + zoomX;
652
653 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
654 for (count=DesY;count<saveY;count++)
655 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, 0);
656 else
657 for (count=DesY;count<saveY;count++)
658 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, 1);
659
660 }
661 }
662 }
663 }
664 else
665 {
666
667 if (DesSizeX>SrcSizeX)
668 {
669 /* Draw one pixel on X - Led to the Des Zoom In*/
670 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
671 {
672 if (DesIsBiggerY)
673 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
674 else
675 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
676
677 if (sy > SourceRect->bottom) break;
678
679 saveY = DesY+zoomY;
680
681 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
682 {
683 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
684
685 if (sx > SourceRect->right) break;
686
687 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
688 for (count=DesY;count<saveY;count++)
689 DIB_8BPP_PutPixel(DestSurf, DesX, count, 0);
690 else
691 for (count=DesY;count<saveY;count++)
692 DIB_8BPP_PutPixel(DestSurf, DesX, count, 1);
693
694
695 }
696 }
697 }
698 else
699 {
700 /* Draw one pixel on X - Led to the Des Zoom Out*/
701 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
702 {
703 if (DesIsBiggerY)
704 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
705 else
706 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
707
708 if (sy > SourceRect->bottom) break;
709
710 saveY = DesY+zoomY;
711
712 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
713 {
714 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
715
716 if (sx > SourceRect->right) break;
717
718 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
719 for (count=DesY;count<saveY;count++)
720 DIB_8BPP_PutPixel(DestSurf, DesX, count, 0);
721 else
722 for (count=DesY;count<saveY;count++)
723 DIB_8BPP_PutPixel(DestSurf, DesX, count, 1);
724
725 }
726 }
727 }
728 }
729 break;
730
731 case BMF_4BPP:
732 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
733 /* This is a reference implementation, it hasn't been optimized for speed */
734 if (zoomX>1)
735 {
736 /* Draw one Hline on X - Led to the Des Zoom In*/
737 if (DesSizeX>SrcSizeX)
738 {
739 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
740 {
741 if (DesIsBiggerY)
742 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
743 else
744 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
745
746 if (sy > SourceRect->bottom) break;
747
748 saveY = DesY+zoomY;
749
750 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
751 {
752 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
753
754 if (sx > SourceRect->right) break;
755
756 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
757
758 saveX = DesX + zoomX;
759 for (count=DesY;count<saveY;count++)
760 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
761 }
762 }
763 }
764 else
765 {
766 /* Draw one Hline on X - Led to the Des Zoom Out*/
767
768 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
769 {
770 if (DesIsBiggerY)
771 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
772 else
773 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
774
775 if (sy > SourceRect->bottom) break;
776
777 saveY = DesY+zoomY;
778
779 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
780 {
781 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
782
783 if (sx > SourceRect->right) break;
784
785 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
786
787 saveX = DesX + zoomX;
788 for (count=DesY;count<saveY;count++)
789 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
790 }
791 }
792 }
793 }
794
795 else
796 {
797
798 if (DesSizeX>SrcSizeX)
799 {
800 /* Draw one pixel on X - Led to the Des Zoom In*/
801 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
802 {
803 if (DesIsBiggerY)
804 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
805 else
806 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
807
808 if (sy > SourceRect->bottom) break;
809
810 saveY = DesY+zoomY;
811
812 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
813 {
814 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
815
816 if (sx > SourceRect->right) break;
817
818 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
819
820 for (count=DesY;count<saveY;count++)
821 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
822 }
823 }
824 }
825 else
826 {
827 /* Draw one pixel on X - Led to the Des Zoom Out*/
828 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
829 {
830 if (DesIsBiggerY)
831 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
832 else
833 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
834
835 if (sy > SourceRect->bottom) break;
836
837 saveY = DesY+zoomY;
838
839 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
840 {
841 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
842
843 if (sx > SourceRect->right) break;
844
845 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
846
847 for (count=DesY;count<saveY;count++)
848 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
849 }
850 }
851 }
852 }
853 break;
854
855 case BMF_8BPP:
856 return ScaleRectAvg8(DestSurf, SourceSurf, DestRect, SourceRect, MaskOrigin, BrushOrigin,
857 ClipRegion, ColorTranslation, Mode);
858 break;
859
860 case BMF_16BPP:
861 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
862 /* This is a reference implementation, it hasn't been optimized for speed */
863 if (zoomX>1)
864 {
865 /* Draw one Hline on X - Led to the Des Zoom In*/
866 if (DesSizeX>SrcSizeX)
867 {
868 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
869 {
870 if (DesIsBiggerY)
871 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
872 else
873 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
874
875 if (sy > SourceRect->bottom) break;
876
877 saveY = DesY+zoomY;
878
879 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
880 {
881 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
882
883 if (sx > SourceRect->right) break;
884
885 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
886
887 saveX = DesX + zoomX;
888 for (count=DesY;count<saveY;count++)
889 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
890 }
891 }
892 }
893 else
894 {
895 /* Draw one Hline on X - Led to the Des Zoom Out*/
896
897 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
898 {
899 if (DesIsBiggerY)
900 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
901 else
902 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
903
904 if (sy > SourceRect->bottom) break;
905
906 saveY = DesY+zoomY;
907
908 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
909 {
910 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
911
912 if (sx > SourceRect->right) break;
913
914 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
915
916 saveX = DesX + zoomX;
917 for (count=DesY;count<saveY;count++)
918 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
919 }
920 }
921 }
922 }
923
924 else
925 {
926
927 if (DesSizeX>SrcSizeX)
928 {
929 /* Draw one pixel on X - Led to the Des Zoom In*/
930 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
931 {
932 if (DesIsBiggerY)
933 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
934 else
935 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
936
937 if (sy > SourceRect->bottom) break;
938
939 saveY = DesY+zoomY;
940
941 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
942 {
943 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
944
945 if (sx > SourceRect->right) break;
946
947 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
948
949 for (count=DesY;count<saveY;count++)
950 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
951 }
952 }
953 }
954 else
955 {
956 /* Draw one pixel on X - Led to the Des Zoom Out*/
957 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
958 {
959 if (DesIsBiggerY)
960 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
961 else
962 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
963
964 if (sy > SourceRect->bottom) break;
965
966 saveY = DesY+zoomY;
967
968 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
969 {
970 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
971
972 if (sx > SourceRect->right) break;
973
974 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
975
976 for (count=DesY;count<saveY;count++)
977 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
978 }
979 }
980 }
981 }
982 break;
983
984 case BMF_24BPP:
985 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
986 /* This is a reference implementation, it hasn't been optimized for speed */
987 if (zoomX>1)
988 {
989 /* Draw one Hline on X - Led to the Des Zoom In*/
990 if (DesSizeX>SrcSizeX)
991 {
992 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
993 {
994 if (DesIsBiggerY)
995 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
996 else
997 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
998
999 if (sy > SourceRect->bottom) break;
1000
1001 saveY = DesY+zoomY;
1002
1003 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1004 {
1005 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1006
1007 if (sx > SourceRect->right) break;
1008
1009 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
1010
1011 saveX = DesX + zoomX;
1012 for (count=DesY;count<saveY;count++)
1013 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
1014 }
1015 }
1016 }
1017 else
1018 {
1019 /* Draw one Hline on X - Led to the Des Zoom Out*/
1020
1021 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1022 {
1023 if (DesIsBiggerY)
1024 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1025 else
1026 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1027
1028 if (sy > SourceRect->bottom) break;
1029
1030 saveY = DesY+zoomY;
1031
1032 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1033 {
1034 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1035
1036 if (sx > SourceRect->right) break;
1037
1038 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
1039
1040 saveX = DesX + zoomX;
1041 for (count=DesY;count<saveY;count++)
1042 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
1043 }
1044 }
1045 }
1046 }
1047
1048 else
1049 {
1050
1051 if (DesSizeX>SrcSizeX)
1052 {
1053 /* Draw one pixel on X - Led to the Des Zoom In*/
1054 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1055 {
1056 if (DesIsBiggerY)
1057 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1058 else
1059 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1060
1061 if (sy > SourceRect->bottom) break;
1062
1063 saveY = DesY+zoomY;
1064
1065 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1066 {
1067 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1068
1069 if (sx > SourceRect->right) break;
1070
1071 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
1072
1073 for (count=DesY;count<saveY;count++)
1074 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
1075 }
1076 }
1077 }
1078 else
1079 {
1080 /* Draw one pixel on X - Led to the Des Zoom Out*/
1081 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1082 {
1083 if (DesIsBiggerY)
1084 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1085 else
1086 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1087
1088 if (sy > SourceRect->bottom) break;
1089
1090 saveY = DesY+zoomY;
1091
1092 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1093 {
1094 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1095
1096 if (sx > SourceRect->right) break;
1097
1098 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
1099
1100 for (count=DesY;count<saveY;count++)
1101 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
1102 }
1103 }
1104 }
1105 }
1106 break;
1107
1108 case BMF_32BPP:
1109 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
1110 /* This is a reference implementation, it hasn't been optimized for speed */
1111 if (zoomX>1)
1112 {
1113 /* Draw one Hline on X - Led to the Des Zoom In*/
1114 if (DesSizeX>SrcSizeX)
1115 {
1116 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1117 {
1118 if (DesIsBiggerY)
1119 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1120 else
1121 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1122
1123 if (sy > SourceRect->bottom) break;
1124
1125 saveY = DesY+zoomY;
1126
1127 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1128 {
1129 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1130
1131 if (sx > SourceRect->right) break;
1132
1133 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1134
1135 saveX = DesX + zoomX;
1136 for (count=DesY;count<saveY;count++)
1137 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
1138 }
1139 }
1140 }
1141 else
1142 {
1143 /* Draw one Hline on X - Led to the Des Zoom Out*/
1144
1145 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1146 {
1147 if (DesIsBiggerY)
1148 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1149 else
1150 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1151
1152 if (sy > SourceRect->bottom) break;
1153
1154 saveY = DesY+zoomY;
1155
1156 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1157 {
1158 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1159
1160 if (sx > SourceRect->right) break;
1161
1162 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1163
1164 saveX = DesX + zoomX;
1165 for (count=DesY;count<saveY;count++)
1166 DIB_8BPP_HLine(DestSurf, DesX, saveX, count, color);
1167 }
1168 }
1169 }
1170 }
1171
1172 else
1173 {
1174
1175 if (DesSizeX>SrcSizeX)
1176 {
1177 /* Draw one pixel on X - Led to the Des Zoom In*/
1178 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1179 {
1180 if (DesIsBiggerY)
1181 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1182 else
1183 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1184
1185 if (sy > SourceRect->bottom) break;
1186
1187 saveY = DesY+zoomY;
1188
1189 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1190 {
1191 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1192
1193 if (sx > SourceRect->right) break;
1194
1195 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1196
1197 for (count=DesY;count<saveY;count++)
1198 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
1199 }
1200 }
1201 }
1202 else
1203 {
1204 /* Draw one pixel on X - Led to the Des Zoom Out*/
1205 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1206 {
1207 if (DesIsBiggerY)
1208 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1209 else
1210 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1211
1212 if (sy > SourceRect->bottom) break;
1213
1214 saveY = DesY+zoomY;
1215
1216 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1217 {
1218 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1219
1220 if (sx > SourceRect->right) break;
1221
1222 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1223
1224 for (count=DesY;count<saveY;count++)
1225 DIB_8BPP_PutPixel(DestSurf, DesX, count, color);
1226 }
1227 }
1228 }
1229 }
1230 break;
1231
1232
1233 default:
1234 DPRINT1("DIB_8BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf->iBitmapFormat));
1235 return FALSE;
1236 }
1237
1238 return TRUE;
1239 }
1240
1241 BOOLEAN
1242 DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
1243 RECTL* DestRect, POINTL *SourcePoint,
1244 XLATEOBJ *ColorTranslation, ULONG iTransColor)
1245 {
1246 ULONG RoundedRight, X, Y, SourceX, SourceY, Source, wd, Dest;
1247 ULONG *DestBits;
1248
1249 RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x3);
1250 SourceY = SourcePoint->y;
1251 DestBits = (ULONG*)(DestSurf->pvScan0 + DestRect->left +
1252 (DestRect->top * DestSurf->lDelta));
1253 wd = DestSurf->lDelta - (DestRect->right - DestRect->left);
1254
1255 for(Y = DestRect->top; Y < DestRect->bottom; Y++)
1256 {
1257 DestBits = (ULONG*)(DestSurf->pvScan0 + DestRect->left +
1258 (Y * DestSurf->lDelta));
1259 SourceX = SourcePoint->x;
1260 for (X = DestRect->left; X < RoundedRight; X += 4, DestBits++)
1261 {
1262 Dest = *DestBits;
1263
1264 Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
1265 if(Source != iTransColor)
1266 {
1267 Dest &= 0xFFFFFF00;
1268 Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF);
1269 }
1270
1271 Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
1272 if(Source != iTransColor)
1273 {
1274 Dest &= 0xFFFF00FF;
1275 Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 8) & 0xFF00);
1276 }
1277
1278 Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
1279 if(Source != iTransColor)
1280 {
1281 Dest &= 0xFF00FFFF;
1282 Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 16) & 0xFF0000);
1283 }
1284
1285 Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
1286 if(Source != iTransColor)
1287 {
1288 Dest &= 0x00FFFFFF;
1289 Dest |= ((XLATEOBJ_iXlate(ColorTranslation, Source) << 24) & 0xFF000000);
1290 }
1291
1292 *DestBits = Dest;
1293 }
1294
1295 if(X < DestRect->right)
1296 {
1297 for (; X < DestRect->right; X++)
1298 {
1299 Source = DIB_GetSourceIndex(SourceSurf, SourceX++, SourceY);
1300 if(Source != iTransColor)
1301 {
1302 *((BYTE*)DestBits) = (BYTE)(XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFF);
1303 }
1304 DestBits = (PULONG)((ULONG_PTR)DestBits + 1);
1305 }
1306 }
1307 SourceY++;
1308 }
1309
1310 return TRUE;
1311 }
1312
1313 /* EOF */