Add generation of 32bpp DIB code
[reactos.git] / reactos / subsys / win32k / dib / dib32bpp.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
21 #include <w32k.h>
22
23 #define NDEBUG
24 #include <debug.h>
25
26 VOID
27 DIB_32BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
28 {
29 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta;
30 PDWORD addr = (PDWORD)byteaddr + x;
31
32 *addr = c;
33 }
34
35 ULONG
36 DIB_32BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
37 {
38 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta;
39 PDWORD addr = (PDWORD)byteaddr + x;
40
41 return (ULONG)(*addr);
42 }
43
44
45 #ifdef _M_IX86
46 VOID
47 DIB_32BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
48 {
49 LONG cx = (x2 - x1) ;
50 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta;
51 PDWORD addr = (PDWORD)byteaddr + x1;
52
53 __asm__ __volatile__ (
54 " cld\n"
55 " mov %0, %%eax\n"
56 " mov %2, %%edi\n"
57 " test $0x03, %%edi\n" /* Align to fullword boundary */
58 " jnz 0f\n"
59 " mov %1,%%ecx\n" /* Setup count of fullwords to fill */
60 " rep stosl\n" /* The actual fill */
61 " jmp 1f\n"
62 "0:\n"
63 " stosw\n"
64 " ror $0x10,%%eax\n"
65 " mov %1,%%ecx\n" /* Setup count of fullwords to fill */
66 " dec %%ecx\n"
67 " rep stosl\n" /* The actual fill */
68 " shr $0x10,%%eax\n"
69 " stosw\n"
70 "1:\n"
71 : /* no output */
72 : "m"(c), "r"(cx), "m"(addr)
73 : "%eax", "%ecx", "%edi");
74
75
76 }
77 #else
78 VOID
79 DIB_32BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
80 {
81 PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta;
82 PDWORD addr = (PDWORD)byteaddr + x1;
83 LONG cx = x1;
84 while(cx < x2)
85 {
86 *addr = (DWORD)c;
87 ++addr;
88 ++cx;
89 }
90 }
91 #endif
92
93 VOID
94 DIB_32BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
95 {
96
97
98 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y1 * SurfObj->lDelta;
99 PDWORD addr = (PDWORD)byteaddr + x;
100 LONG lDelta = SurfObj->lDelta >> 2; // >> 2 == / sizeof(DWORD)
101
102 byteaddr = (PBYTE)addr;
103 while(y1++ < y2)
104 {
105 *addr = (DWORD)c;
106 addr += lDelta;
107 }
108
109 }
110
111 BOOLEAN
112 DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
113 {
114 LONG i, j, sx, sy, xColor, f1;
115 PBYTE SourceBits, DestBits, SourceLine, DestLine;
116 PBYTE SourceBits_4BPP, SourceLine_4BPP;
117 PDWORD Source32, Dest32;
118
119 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + 4 * BltInfo->DestRect.left;
120
121 switch(BltInfo->SourceSurface->iBitmapFormat)
122 {
123 case BMF_1BPP:
124
125 sx = BltInfo->SourcePoint.x;
126 sy = BltInfo->SourcePoint.y;
127
128 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
129 {
130 sx = BltInfo->SourcePoint.x;
131 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
132 {
133 if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
134 {
135 DIB_32BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0));
136 } else {
137 DIB_32BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
138 }
139 sx++;
140 }
141 sy++;
142 }
143 break;
144
145 case BMF_4BPP:
146 SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1);
147
148 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
149 {
150 SourceLine_4BPP = SourceBits_4BPP;
151 sx = BltInfo->SourcePoint.x;
152 f1 = sx & 1;
153
154 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
155 {
156 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest,
157 (*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1)));
158 DIB_32BPP_PutPixel(BltInfo->DestSurface, i, j, xColor);
159 if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
160 sx++;
161 }
162
163 SourceBits_4BPP += BltInfo->SourceSurface->lDelta;
164 }
165 break;
166
167 case BMF_8BPP:
168 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
169 DestLine = DestBits;
170
171 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
172 {
173 SourceBits = SourceLine;
174 DestBits = DestLine;
175
176 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
177 {
178 xColor = *SourceBits;
179 *((PDWORD) DestBits) = (DWORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
180 SourceBits += 1;
181 DestBits += 4;
182 }
183
184 SourceLine += BltInfo->SourceSurface->lDelta;
185 DestLine += BltInfo->DestSurface->lDelta;
186 }
187 break;
188
189 case BMF_16BPP:
190 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
191 DestLine = DestBits;
192
193 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
194 {
195 SourceBits = SourceLine;
196 DestBits = DestLine;
197
198 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
199 {
200 xColor = *((PWORD) SourceBits);
201 *((PDWORD) DestBits) = (DWORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
202 SourceBits += 2;
203 DestBits += 4;
204 }
205
206 SourceLine += BltInfo->SourceSurface->lDelta;
207 DestLine += BltInfo->DestSurface->lDelta;
208 }
209 break;
210
211 case BMF_24BPP:
212 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
213 DestLine = DestBits;
214
215 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
216 {
217 SourceBits = SourceLine;
218 DestBits = DestLine;
219
220 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
221 {
222 xColor = (*(SourceBits + 2) << 0x10) +
223 (*(SourceBits + 1) << 0x08) +
224 (*(SourceBits));
225 *((PDWORD)DestBits) = (DWORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
226 SourceBits += 3;
227 DestBits += 4;
228 }
229
230 SourceLine += BltInfo->SourceSurface->lDelta;
231 DestLine += BltInfo->DestSurface->lDelta;
232 }
233 break;
234
235 case BMF_32BPP:
236 if (NULL == BltInfo->XlateSourceToDest || 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))
237 {
238 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
239 {
240 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
241 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
242 {
243 RtlMoveMemory(DestBits, SourceBits, 4 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
244 SourceBits += BltInfo->SourceSurface->lDelta;
245 DestBits += BltInfo->DestSurface->lDelta;
246 }
247 }
248 else
249 {
250 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
251 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 4 * BltInfo->DestRect.left;
252 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
253 {
254 RtlMoveMemory(DestBits, SourceBits, 4 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
255 SourceBits -= BltInfo->SourceSurface->lDelta;
256 DestBits -= BltInfo->DestSurface->lDelta;
257 }
258 }
259 }
260 else
261 {
262 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
263 {
264 SourceBits = ((PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x);
265 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
266 {
267 if (BltInfo->DestRect.left < BltInfo->SourcePoint.x)
268 {
269 Dest32 = (DWORD *) DestBits;
270 Source32 = (DWORD *) SourceBits;
271 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
272 {
273 *Dest32++ = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32++);
274 }
275 }
276 else
277 {
278 Dest32 = (DWORD *) DestBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
279 Source32 = (DWORD *) SourceBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
280 for (i = BltInfo->DestRect.right - 1; BltInfo->DestRect.left <= i; i--)
281 {
282 *Dest32-- = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32--);
283 }
284 }
285 SourceBits += BltInfo->SourceSurface->lDelta;
286 DestBits += BltInfo->DestSurface->lDelta;
287 }
288 }
289 else
290 {
291 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
292 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 4 * BltInfo->DestRect.left;
293 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
294 {
295 if (BltInfo->DestRect.left < BltInfo->SourcePoint.x)
296 {
297 Dest32 = (DWORD *) DestBits;
298 Source32 = (DWORD *) SourceBits;
299 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
300 {
301 *Dest32++ = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32++);
302 }
303 }
304 else
305 {
306 Dest32 = (DWORD *) DestBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
307 Source32 = (DWORD *) SourceBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
308 for (i = BltInfo->DestRect.right; BltInfo->DestRect.left < i; i--)
309 {
310 *Dest32-- = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32--);
311 }
312 }
313 SourceBits -= BltInfo->SourceSurface->lDelta;
314 DestBits -= BltInfo->DestSurface->lDelta;
315 }
316 }
317 }
318 break;
319
320 default:
321 DPRINT1("DIB_32BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
322 return FALSE;
323 }
324
325 return TRUE;
326 }
327
328 BOOLEAN
329 DIB_32BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
330 {
331 ULONG DestY;
332
333 for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
334 {
335 DIB_32BPP_HLine (DestSurface, DestRect->left, DestRect->right, DestY, color);
336 }
337
338
339 return TRUE;
340 }
341 /*
342 =======================================
343 Stretching functions goes below
344 Some parts of code are based on an
345 article "Bresenhame image scaling"
346 Dr. Dobb Journal, May 2002
347 =======================================
348 */
349
350 typedef unsigned long PIXEL;
351
352 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
353
354 /* 32-bit Color (___ format) */
355 inline PIXEL average32(PIXEL a, PIXEL b)
356 {
357 return a; // FIXME: Temp hack to remove "PCB-effect" from the image
358 }
359
360 void ScaleLineAvg32(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth)
361 {
362 int NumPixels = TgtWidth;
363 int IntPart = SrcWidth / TgtWidth;
364 int FractPart = SrcWidth % TgtWidth;
365 int Mid = TgtWidth >> 1;
366 int E = 0;
367 int skip;
368 PIXEL p;
369
370 skip = (TgtWidth < SrcWidth) ? 0 : (TgtWidth / (2*SrcWidth) + 1);
371 NumPixels -= skip;
372
373 while (NumPixels-- > 0) {
374 p = *Source;
375 if (E >= Mid)
376 p = average32(p, *(Source+1));
377 *Target++ = p;
378 Source += IntPart;
379 E += FractPart;
380 if (E >= TgtWidth) {
381 E -= TgtWidth;
382 Source++;
383 } /* if */
384 } /* while */
385 while (skip-- > 0)
386 *Target++ = *Source;
387 }
388
389 static BOOLEAN
390 FinalCopy32(PIXEL *Target, PIXEL *Source, PSPAN ClipSpans, UINT ClipSpansCount, UINT *SpanIndex,
391 UINT DestY, RECTL *DestRect)
392 {
393 LONG Left, Right;
394
395 while (ClipSpans[*SpanIndex].Y < DestY
396 || (ClipSpans[*SpanIndex].Y == DestY
397 && ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width < DestRect->left))
398 {
399 (*SpanIndex)++;
400 if (ClipSpansCount <= *SpanIndex)
401 {
402 /* No more spans, everything else is clipped away, we're done */
403 return FALSE;
404 }
405 }
406 while (ClipSpans[*SpanIndex].Y == DestY)
407 {
408 if (ClipSpans[*SpanIndex].X < DestRect->right)
409 {
410 Left = max(ClipSpans[*SpanIndex].X, DestRect->left);
411 Right = min(ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width, DestRect->right);
412 memcpy(Target + Left - DestRect->left, Source + Left - DestRect->left,
413 (Right - Left) * sizeof(PIXEL));
414 }
415 (*SpanIndex)++;
416 if (ClipSpansCount <= *SpanIndex)
417 {
418 /* No more spans, everything else is clipped away, we're done */
419 return FALSE;
420 }
421 }
422
423 return TRUE;
424 }
425
426 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
427 BOOLEAN ScaleRectAvg32(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
428 RECTL* DestRect, RECTL *SourceRect,
429 POINTL* MaskOrigin, POINTL BrushOrigin,
430 CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
431 ULONG Mode)
432 {
433 int NumPixels = DestRect->bottom - DestRect->top;
434 int IntPart = (((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * SourceSurf->lDelta) / 4;
435 int FractPart = (SourceRect->bottom - SourceRect->top) % (DestRect->bottom - DestRect->top);
436 int Mid = (DestRect->bottom - DestRect->top) >> 1;
437 int E = 0;
438 int skip;
439 PIXEL *ScanLine, *ScanLineAhead;
440 PIXEL *PrevSource = NULL;
441 PIXEL *PrevSourceAhead = NULL;
442 PIXEL *Target = (PIXEL *) ((PBYTE)DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + 4 * DestRect->left);
443 PIXEL *Source = (PIXEL *) ((PBYTE)SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + 4 * SourceRect->left);
444 PSPAN ClipSpans;
445 UINT ClipSpansCount;
446 UINT SpanIndex;
447 LONG DestY;
448
449 if (! ClipobjToSpans(&ClipSpans, &ClipSpansCount, ClipRegion, DestRect))
450 {
451 return FALSE;
452 }
453 if (0 == ClipSpansCount)
454 {
455 /* No clip spans == empty clipping region, everything clipped away */
456 ASSERT(NULL == ClipSpans);
457 return TRUE;
458 }
459 skip = (DestRect->bottom - DestRect->top < SourceRect->bottom - SourceRect->top) ? 0 : ((DestRect->bottom - DestRect->top) / (2 * (SourceRect->bottom - SourceRect->top)) + 1);
460 NumPixels -= skip;
461
462 ScanLine = (PIXEL*)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
463 ScanLineAhead = (PIXEL *)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
464
465 DestY = DestRect->top;
466 SpanIndex = 0;
467 while (NumPixels-- > 0) {
468 if (Source != PrevSource) {
469 if (Source == PrevSourceAhead) {
470 /* the next scan line has already been scaled and stored in
471 * ScanLineAhead; swap the buffers that ScanLine and ScanLineAhead
472 * point to
473 */
474 PIXEL *tmp = ScanLine;
475 ScanLine = ScanLineAhead;
476 ScanLineAhead = tmp;
477 } else {
478 ScaleLineAvg32(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
479 } /* if */
480 PrevSource = Source;
481 } /* if */
482
483 if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + SourceSurf->lDelta)) {
484 int x;
485 ScaleLineAvg32(ScanLineAhead, (PIXEL *)((BYTE *)Source + SourceSurf->lDelta), SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
486 for (x = 0; x < DestRect->right - DestRect->left; x++)
487 ScanLine[x] = average32(ScanLine[x], ScanLineAhead[x]);
488 PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceSurf->lDelta);
489 } /* if */
490
491 if (! FinalCopy32(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
492 {
493 /* No more spans, everything else is clipped away, we're done */
494 ExFreePool(ClipSpans);
495 ExFreePool(ScanLine);
496 ExFreePool(ScanLineAhead);
497 return TRUE;
498 }
499 DestY++;
500 Target = (PIXEL *)((BYTE *)Target + DestSurf->lDelta);
501 Source += IntPart;
502 E += FractPart;
503 if (E >= DestRect->bottom - DestRect->top) {
504 E -= DestRect->bottom - DestRect->top;
505 Source = (PIXEL *)((BYTE *)Source + SourceSurf->lDelta);
506 } /* if */
507 } /* while */
508
509 if (skip > 0 && Source != PrevSource)
510 ScaleLineAvg32(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
511 while (skip-- > 0) {
512 if (! FinalCopy32(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
513 {
514 /* No more spans, everything else is clipped away, we're done */
515 ExFreePool(ClipSpans);
516 ExFreePool(ScanLine);
517 ExFreePool(ScanLineAhead);
518 return TRUE;
519 }
520 DestY++;
521 Target = (PIXEL *)((BYTE *)Target + DestSurf->lDelta);
522 } /* while */
523
524 ExFreePool(ClipSpans);
525 ExFreePool(ScanLine);
526 ExFreePool(ScanLineAhead);
527
528 return TRUE;
529 }
530
531
532 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
533 BOOLEAN DIB_32BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
534 RECTL* DestRect, RECTL *SourceRect,
535 POINTL* MaskOrigin, POINTL BrushOrigin,
536 CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
537 ULONG Mode)
538 {
539
540 int SrcSizeY;
541 int SrcSizeX;
542 int DesSizeY;
543 int DesSizeX;
544 int sx;
545 int sy;
546 int DesX;
547 int DesY;
548 int color;
549 int zoomX;
550 int zoomY;
551 int count;
552 int saveX;
553 int saveY;
554 BOOLEAN DesIsBiggerY=FALSE;
555
556 DPRINT("DIB_32BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
557 BitsPerFormat(SourceSurf->iBitmapFormat), SourceRect->left, SourceRect->top, SourceRect->right,
558 SourceRect->bottom, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
559
560 SrcSizeY = SourceRect->bottom;
561 SrcSizeX = SourceRect->right;
562
563 DesSizeY = DestRect->bottom;
564 DesSizeX = DestRect->right;
565
566 zoomX = DesSizeX / SrcSizeX;
567 if (zoomX==0) zoomX=1;
568
569 zoomY = DesSizeY / SrcSizeY;
570 if (zoomY==0) zoomY=1;
571
572 if (DesSizeY>SrcSizeY)
573 DesIsBiggerY = TRUE;
574
575 switch(SourceSurf->iBitmapFormat)
576 {
577 case BMF_1BPP:
578 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
579 /* This is a reference implementation, it hasn't been optimized for speed */
580 if (zoomX>1)
581 {
582 /* Draw one Hline on X - Led to the Des Zoom In*/
583 if (DesSizeX>SrcSizeX)
584 {
585 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
586 {
587 if (DesIsBiggerY)
588 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
589 else
590 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
591
592 if (sy > SourceRect->bottom) break;
593
594 saveY = DesY+zoomY;
595
596 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
597 {
598 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
599
600 if (sx > SourceRect->right) break;
601
602 saveX = DesX + zoomX;
603
604 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
605 for (count=DesY;count<saveY;count++)
606 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, 0);
607 else
608 for (count=DesY;count<saveY;count++)
609 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, 1);
610
611 }
612 }
613 }
614 else
615 {
616 /* Draw one Hline on X - Led to the Des Zoom Out*/
617
618 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
619 {
620 if (DesIsBiggerY)
621 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
622 else
623 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
624
625 if (sy > SourceRect->bottom) break;
626
627 saveY = DesY+zoomY;
628
629 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
630 {
631 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
632
633 if (sx > SourceRect->right) break;
634
635 saveX = DesX + zoomX;
636
637 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
638 for (count=DesY;count<saveY;count++)
639 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, 0);
640 else
641 for (count=DesY;count<saveY;count++)
642 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, 1);
643
644 }
645 }
646 }
647 }
648 else
649 {
650
651 if (DesSizeX>SrcSizeX)
652 {
653 /* Draw one pixel on X - Led to the Des Zoom In*/
654 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
655 {
656 if (DesIsBiggerY)
657 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
658 else
659 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
660
661 if (sy > SourceRect->bottom) break;
662
663 saveY = DesY+zoomY;
664
665 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
666 {
667 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
668
669 if (sx > SourceRect->right) break;
670
671 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
672 for (count=DesY;count<saveY;count++)
673 DIB_32BPP_PutPixel(DestSurf, DesX, count, 0);
674 else
675 for (count=DesY;count<saveY;count++)
676 DIB_32BPP_PutPixel(DestSurf, DesX, count, 1);
677
678
679 }
680 }
681 }
682 else
683 {
684 /* Draw one pixel on X - Led to the Des Zoom Out*/
685 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
686 {
687 if (DesIsBiggerY)
688 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
689 else
690 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
691
692 if (sy > SourceRect->bottom) break;
693
694 saveY = DesY+zoomY;
695
696 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
697 {
698 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
699
700 if (sx > SourceRect->right) break;
701
702 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
703 for (count=DesY;count<saveY;count++)
704 DIB_32BPP_PutPixel(DestSurf, DesX, count, 0);
705 else
706 for (count=DesY;count<saveY;count++)
707 DIB_32BPP_PutPixel(DestSurf, DesX, count, 1);
708
709 }
710 }
711 }
712 }
713 break;
714
715 case BMF_4BPP:
716 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
717 /* This is a reference implementation, it hasn't been optimized for speed */
718 if (zoomX>1)
719 {
720 /* Draw one Hline on X - Led to the Des Zoom In*/
721 if (DesSizeX>SrcSizeX)
722 {
723 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
724 {
725 if (DesIsBiggerY)
726 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
727 else
728 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
729
730 if (sy > SourceRect->bottom) break;
731
732 saveY = DesY+zoomY;
733
734 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
735 {
736 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
737
738 if (sx > SourceRect->right) break;
739
740 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
741
742 saveX = DesX + zoomX;
743 for (count=DesY;count<saveY;count++)
744 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
745 }
746 }
747 }
748 else
749 {
750 /* Draw one Hline on X - Led to the Des Zoom Out*/
751
752 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
753 {
754 if (DesIsBiggerY)
755 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
756 else
757 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
758
759 if (sy > SourceRect->bottom) break;
760
761 saveY = DesY+zoomY;
762
763 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
764 {
765 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
766
767 if (sx > SourceRect->right) break;
768
769 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
770
771 saveX = DesX + zoomX;
772 for (count=DesY;count<saveY;count++)
773 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
774 }
775 }
776 }
777 }
778
779 else
780 {
781
782 if (DesSizeX>SrcSizeX)
783 {
784 /* Draw one pixel on X - Led to the Des Zoom In*/
785 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
786 {
787 if (DesIsBiggerY)
788 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
789 else
790 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
791
792 if (sy > SourceRect->bottom) break;
793
794 saveY = DesY+zoomY;
795
796 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
797 {
798 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
799
800 if (sx > SourceRect->right) break;
801
802 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
803
804 for (count=DesY;count<saveY;count++)
805 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
806 }
807 }
808 }
809 else
810 {
811 /* Draw one pixel on X - Led to the Des Zoom Out*/
812 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
813 {
814 if (DesIsBiggerY)
815 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
816 else
817 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
818
819 if (sy > SourceRect->bottom) break;
820
821 saveY = DesY+zoomY;
822
823 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
824 {
825 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
826
827 if (sx > SourceRect->right) break;
828
829 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
830
831 for (count=DesY;count<saveY;count++)
832 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
833 }
834 }
835 }
836 }
837 break;
838
839 case BMF_8BPP:
840 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
841 /* This is a reference implementation, it hasn't been optimized for speed */
842 if (zoomX>1)
843 {
844 /* Draw one Hline on X - Led to the Des Zoom In*/
845 if (DesSizeX>SrcSizeX)
846 {
847 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
848 {
849 if (DesIsBiggerY)
850 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
851 else
852 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
853
854 if (sy > SourceRect->bottom) break;
855
856 saveY = DesY+zoomY;
857
858 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
859 {
860 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
861
862 if (sx > SourceRect->right) break;
863
864 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
865
866 saveX = DesX + zoomX;
867 for (count=DesY;count<saveY;count++)
868 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
869 }
870 }
871 }
872 else
873 {
874 /* Draw one Hline on X - Led to the Des Zoom Out*/
875
876 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
877 {
878 if (DesIsBiggerY)
879 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
880 else
881 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
882
883 if (sy > SourceRect->bottom) break;
884
885 saveY = DesY+zoomY;
886
887 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
888 {
889 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
890
891 if (sx > SourceRect->right) break;
892
893 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
894
895 saveX = DesX + zoomX;
896 for (count=DesY;count<saveY;count++)
897 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
898 }
899 }
900 }
901 }
902
903 else
904 {
905
906 if (DesSizeX>SrcSizeX)
907 {
908 /* Draw one pixel on X - Led to the Des Zoom In*/
909 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
910 {
911 if (DesIsBiggerY)
912 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
913 else
914 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
915
916 if (sy > SourceRect->bottom) break;
917
918 saveY = DesY+zoomY;
919
920 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
921 {
922 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
923
924 if (sx > SourceRect->right) break;
925
926 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
927
928 for (count=DesY;count<saveY;count++)
929 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
930 }
931 }
932 }
933 else
934 {
935 /* Draw one pixel on X - Led to the Des Zoom Out*/
936 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
937 {
938 if (DesIsBiggerY)
939 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
940 else
941 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
942
943 if (sy > SourceRect->bottom) break;
944
945 saveY = DesY+zoomY;
946
947 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
948 {
949 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
950
951 if (sx > SourceRect->right) break;
952
953 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
954
955 for (count=DesY;count<saveY;count++)
956 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
957 }
958 }
959 }
960 }
961 break;
962
963 case BMF_16BPP:
964 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
965 /* This is a reference implementation, it hasn't been optimized for speed */
966 if (zoomX>1)
967 {
968 /* Draw one Hline on X - Led to the Des Zoom In*/
969 if (DesSizeX>SrcSizeX)
970 {
971 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
972 {
973 if (DesIsBiggerY)
974 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
975 else
976 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
977
978 if (sy > SourceRect->bottom) break;
979
980 saveY = DesY+zoomY;
981
982 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
983 {
984 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
985
986 if (sx > SourceRect->right) break;
987
988 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
989
990 saveX = DesX + zoomX;
991 for (count=DesY;count<saveY;count++)
992 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
993 }
994 }
995 }
996 else
997 {
998 /* Draw one Hline on X - Led to the Des Zoom Out*/
999
1000 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1001 {
1002 if (DesIsBiggerY)
1003 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1004 else
1005 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1006
1007 if (sy > SourceRect->bottom) break;
1008
1009 saveY = DesY+zoomY;
1010
1011 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1012 {
1013 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1014
1015 if (sx > SourceRect->right) break;
1016
1017 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
1018
1019 saveX = DesX + zoomX;
1020 for (count=DesY;count<saveY;count++)
1021 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
1022 }
1023 }
1024 }
1025 }
1026
1027 else
1028 {
1029
1030 if (DesSizeX>SrcSizeX)
1031 {
1032 /* Draw one pixel on X - Led to the Des Zoom In*/
1033 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1034 {
1035 if (DesIsBiggerY)
1036 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1037 else
1038 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1039
1040 if (sy > SourceRect->bottom) break;
1041
1042 saveY = DesY+zoomY;
1043
1044 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1045 {
1046 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1047
1048 if (sx > SourceRect->right) break;
1049
1050 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
1051
1052 for (count=DesY;count<saveY;count++)
1053 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
1054 }
1055 }
1056 }
1057 else
1058 {
1059 /* Draw one pixel on X - Led to the Des Zoom Out*/
1060 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1061 {
1062 if (DesIsBiggerY)
1063 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1064 else
1065 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1066
1067 if (sy > SourceRect->bottom) break;
1068
1069 saveY = DesY+zoomY;
1070
1071 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1072 {
1073 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1074
1075 if (sx > SourceRect->right) break;
1076
1077 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
1078
1079 for (count=DesY;count<saveY;count++)
1080 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
1081 }
1082 }
1083 }
1084 }
1085 break;
1086
1087 case BMF_24BPP:
1088 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
1089 /* This is a reference implementation, it hasn't been optimized for speed */
1090 if (zoomX>1)
1091 {
1092 /* Draw one Hline on X - Led to the Des Zoom In*/
1093 if (DesSizeX>SrcSizeX)
1094 {
1095 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1096 {
1097 if (DesIsBiggerY)
1098 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1099 else
1100 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1101
1102 if (sy > SourceRect->bottom) break;
1103
1104 saveY = DesY+zoomY;
1105
1106 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1107 {
1108 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1109
1110 if (sx > SourceRect->right) break;
1111
1112 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
1113
1114 saveX = DesX + zoomX;
1115 for (count=DesY;count<saveY;count++)
1116 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
1117 }
1118 }
1119 }
1120 else
1121 {
1122 /* Draw one Hline on X - Led to the Des Zoom Out*/
1123
1124 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1125 {
1126 if (DesIsBiggerY)
1127 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1128 else
1129 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1130
1131 if (sy > SourceRect->bottom) break;
1132
1133 saveY = DesY+zoomY;
1134
1135 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1136 {
1137 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1138
1139 if (sx > SourceRect->right) break;
1140
1141 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
1142
1143 saveX = DesX + zoomX;
1144 for (count=DesY;count<saveY;count++)
1145 DIB_32BPP_HLine(DestSurf, DesX, saveX, count, color);
1146 }
1147 }
1148 }
1149 }
1150
1151 else
1152 {
1153
1154 if (DesSizeX>SrcSizeX)
1155 {
1156 /* Draw one pixel on X - Led to the Des Zoom In*/
1157 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1158 {
1159 if (DesIsBiggerY)
1160 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1161 else
1162 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1163
1164 if (sy > SourceRect->bottom) break;
1165
1166 saveY = DesY+zoomY;
1167
1168 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1169 {
1170 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1171
1172 if (sx > SourceRect->right) break;
1173
1174 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
1175
1176 for (count=DesY;count<saveY;count++)
1177 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
1178 }
1179 }
1180 }
1181 else
1182 {
1183 /* Draw one pixel on X - Led to the Des Zoom Out*/
1184 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1185 {
1186 if (DesIsBiggerY)
1187 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1188 else
1189 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1190
1191 if (sy > SourceRect->bottom) break;
1192
1193 saveY = DesY+zoomY;
1194
1195 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1196 {
1197 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1198
1199 if (sx > SourceRect->right) break;
1200
1201 color = XLATEOBJ_iXlate(ColorTranslation, DIB_24BPP_GetPixel(SourceSurf, sx, sy));
1202
1203 for (count=DesY;count<saveY;count++)
1204 DIB_32BPP_PutPixel(DestSurf, DesX, count, color);
1205 }
1206 }
1207 }
1208 }
1209 break;
1210
1211 case BMF_32BPP:
1212 return ScaleRectAvg32(DestSurf, SourceSurf, DestRect, SourceRect, MaskOrigin, BrushOrigin,
1213 ClipRegion, ColorTranslation, Mode);
1214 break;
1215
1216 default:
1217 //DPRINT1("DIB_32BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf->iBitmapFormat));
1218 return FALSE;
1219 }
1220
1221
1222
1223 return TRUE;
1224 }
1225
1226 BOOLEAN
1227 DIB_32BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
1228 RECTL* DestRect, POINTL *SourcePoint,
1229 XLATEOBJ *ColorTranslation, ULONG iTransColor)
1230 {
1231 ULONG X, Y, SourceX, SourceY, Source, wd;
1232 ULONG *DestBits;
1233
1234 SourceY = SourcePoint->y;
1235 DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 +
1236 (DestRect->left << 2) +
1237 DestRect->top * DestSurf->lDelta);
1238 wd = DestSurf->lDelta - ((DestRect->right - DestRect->left) << 2);
1239
1240 for(Y = DestRect->top; Y < DestRect->bottom; Y++)
1241 {
1242 SourceX = SourcePoint->x;
1243 for(X = DestRect->left; X < DestRect->right; X++, DestBits++, SourceX++)
1244 {
1245 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
1246 if(Source != iTransColor)
1247 {
1248 *DestBits = XLATEOBJ_iXlate(ColorTranslation, Source);
1249 }
1250 }
1251
1252 SourceY++;
1253 DestBits = (ULONG*)((ULONG_PTR)DestBits + wd);
1254 }
1255
1256 return TRUE;
1257 }
1258
1259 /* EOF */