Implement (Int)EngAlphaBlend and 8, 16, 24 and 32 bpp DIB AlphaBlend functions. Alpha...
[reactos.git] / reactos / subsys / win32k / dib / dib24bpp.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_24BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
28 {
29 PBYTE addr = (PBYTE)SurfObj->pvScan0 + (y * SurfObj->lDelta) + (x << 1) + x;
30 *(PUSHORT)(addr) = c & 0xFFFF;
31 *(addr + 2) = (c >> 16) & 0xFF;
32 }
33
34 ULONG
35 DIB_24BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
36 {
37 PBYTE addr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + (x << 1) + x;
38 return *(PUSHORT)(addr) + (*(addr + 2) << 16);
39 }
40
41 VOID
42 DIB_24BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
43 {
44 PBYTE addr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + (x1 << 1) + x1;
45 ULONG Count = x2 - x1;
46 #ifndef _M_IX86
47 ULONG MultiCount;
48 ULONG Fill[3];
49 #endif
50
51 if (Count < 8)
52 {
53 /* For small fills, don't bother doing anything fancy */
54 while (Count--)
55 {
56 *(PUSHORT)(addr) = c;
57 addr += 2;
58 *(addr) = c >> 16;
59 addr += 1;
60 }
61 }
62 else
63 {
64 /* Align to 4-byte address */
65 while (0 != ((ULONG_PTR) addr & 0x3))
66 {
67 *(PUSHORT)(addr) = c;
68 addr += 2;
69 *(addr) = c >> 16;
70 addr += 1;
71 Count--;
72 }
73 /* If the color we need to fill with is 0ABC, then the final mem pattern
74 * (note little-endianness) would be:
75 *
76 * |C.B.A|C.B.A|C.B.A|C.B.A| <- pixel borders
77 * |C.B.A.C|B.A.C.B|A.C.B.A| <- ULONG borders
78 *
79 * So, taking endianness into account again, we need to fill with these
80 * ULONGs: CABC BCAB ABCA */
81 #ifdef _M_IX86
82 /* This is about 30% faster than the generic C code below */
83 __asm__ __volatile__ (
84 " movl %1, %%ecx\n"
85 " andl $0xffffff, %%ecx\n" /* 0ABC */
86 " movl %%ecx, %%ebx\n" /* Construct BCAB in ebx */
87 " shrl $8, %%ebx\n"
88 " movl %%ecx, %%eax\n"
89 " shll $16, %%eax\n"
90 " orl %%eax, %%ebx\n"
91 " movl %%ecx, %%edx\n" /* Construct ABCA in edx */
92 " shll $8, %%edx\n"
93 " movl %%ecx, %%eax\n"
94 " shrl $16, %%eax\n"
95 " orl %%eax, %%edx\n"
96 " movl %%ecx, %%eax\n" /* Construct CABC in eax */
97 " shll $24, %%eax\n"
98 " orl %%ecx, %%eax\n"
99 " movl %2, %%ecx\n" /* Load count */
100 " shr $2, %%ecx\n"
101 " movl %3, %%edi\n" /* Load dest */
102 "0:\n"
103 " movl %%eax, (%%edi)\n" /* Store 4 pixels, 12 bytes */
104 " movl %%ebx, 4(%%edi)\n"
105 " movl %%edx, 8(%%edi)\n"
106 " addl $12, %%edi\n"
107 " dec %%ecx\n"
108 " jnz 0b\n"
109 " movl %%edi, %0\n"
110 : "=m"(addr)
111 : "m"(c), "m"(Count), "m"(addr)
112 : "%eax", "%ebx", "%ecx", "%edx", "%edi");
113 #else
114 c = c & 0xffffff; /* 0ABC */
115 Fill[0] = c | (c << 24); /* CABC */
116 Fill[1] = (c >> 8) | (c << 16); /* BCAB */
117 Fill[2] = (c << 8) | (c >> 16); /* ABCA */
118 MultiCount = Count / 4;
119 do
120 {
121 *(PULONG)addr = Fill[0];
122 addr += 4;
123 *(PULONG)addr = Fill[1];
124 addr += 4;
125 *(PULONG)addr = Fill[2];
126 addr += 4;
127 }
128 while (0 != --MultiCount);
129 #endif
130 Count = Count & 0x03;
131 while (0 != Count--)
132 {
133 *(PUSHORT)(addr) = c;
134 addr += 2;
135 *(addr) = c >> 16;
136 addr += 1;
137 }
138 }
139 }
140
141 VOID
142 DIB_24BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
143 {
144 PBYTE addr = (PBYTE)SurfObj->pvScan0 + y1 * SurfObj->lDelta + (x << 1) + x;
145 LONG lDelta = SurfObj->lDelta;
146
147 c &= 0xFFFFFF;
148 while(y1++ < y2) {
149 *(PUSHORT)(addr) = c & 0xFFFF;
150 *(addr + 2) = c >> 16;
151
152 addr += lDelta;
153 }
154 }
155
156 BOOLEAN
157 DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
158 {
159 LONG i, j, sx, sy, xColor, f1;
160 PBYTE SourceBits, DestBits, SourceLine, DestLine;
161 PBYTE SourceBits_4BPP, SourceLine_4BPP;
162 PWORD SourceBits_16BPP, SourceLine_16BPP;
163
164 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left * 3;
165
166 switch(BltInfo->SourceSurface->iBitmapFormat)
167 {
168 case BMF_1BPP:
169 sx = BltInfo->SourcePoint.x;
170 sy = BltInfo->SourcePoint.y;
171
172 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
173 {
174 sx = BltInfo->SourcePoint.x;
175 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
176 {
177 if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
178 {
179 DIB_24BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0));
180 } else {
181 DIB_24BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
182 }
183 sx++;
184 }
185 sy++;
186 }
187 break;
188
189 case BMF_4BPP:
190 SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1);
191
192 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
193 {
194 SourceLine_4BPP = SourceBits_4BPP;
195 DestLine = DestBits;
196 sx = BltInfo->SourcePoint.x;
197 f1 = sx & 1;
198
199 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
200 {
201 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest,
202 (*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1)));
203 *DestLine++ = xColor & 0xff;
204 *(PWORD)DestLine = xColor >> 8;
205 DestLine += 2;
206 if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
207 sx++;
208 }
209
210 SourceBits_4BPP += BltInfo->SourceSurface->lDelta;
211 DestBits += BltInfo->DestSurface->lDelta;
212 }
213 break;
214
215 case BMF_8BPP:
216 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
217 DestLine = DestBits;
218
219 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
220 {
221 SourceBits = SourceLine;
222 DestBits = DestLine;
223
224 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
225 {
226 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits);
227 *DestBits = xColor & 0xff;
228 *(PWORD)(DestBits + 1) = xColor >> 8;
229 SourceBits += 1;
230 DestBits += 3;
231 }
232
233 SourceLine += BltInfo->SourceSurface->lDelta;
234 DestLine += BltInfo->DestSurface->lDelta;
235 }
236 break;
237
238 case BMF_16BPP:
239 SourceBits_16BPP = (PWORD)((PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x);
240
241 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
242 {
243 SourceLine_16BPP = SourceBits_16BPP;
244 DestLine = DestBits;
245
246 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
247 {
248 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceLine_16BPP);
249 *DestLine++ = xColor & 0xff;
250 *(PWORD)DestLine = xColor >> 8;
251 DestLine += 2;
252 SourceLine_16BPP++;
253 }
254
255 SourceBits_16BPP = (PWORD)((PBYTE)SourceBits_16BPP + BltInfo->SourceSurface->lDelta);
256 DestBits += BltInfo->DestSurface->lDelta;
257 }
258 break;
259
260 case BMF_24BPP:
261 if (NULL == BltInfo->XlateSourceToDest || 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))
262 {
263 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
264 {
265 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
266 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
267 {
268 RtlMoveMemory(DestBits, SourceBits, 3 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
269 SourceBits += BltInfo->SourceSurface->lDelta;
270 DestBits += BltInfo->DestSurface->lDelta;
271 }
272 }
273 else
274 {
275 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
276 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 3 * BltInfo->DestRect.left;
277 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
278 {
279 RtlMoveMemory(DestBits, SourceBits, 3 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
280 SourceBits -= BltInfo->SourceSurface->lDelta;
281 DestBits -= BltInfo->DestSurface->lDelta;
282 }
283 }
284 }
285 else
286 {
287 /* FIXME */
288 DPRINT1("DIB_24BPP_Bitblt: Unhandled BltInfo->XlateSourceToDest for 16 -> 16 copy\n");
289 return FALSE;
290 }
291 break;
292
293 case BMF_32BPP:
294 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
295 DestLine = DestBits;
296
297 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
298 {
299 SourceBits = SourceLine;
300 DestBits = DestLine;
301
302 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
303 {
304 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *((PDWORD) SourceBits));
305 *DestBits = xColor & 0xff;
306 *(PWORD)(DestBits + 1) = xColor >> 8;
307 SourceBits += 4;
308 DestBits += 3;
309 }
310
311 SourceLine += BltInfo->SourceSurface->lDelta;
312 DestLine += BltInfo->DestSurface->lDelta;
313 }
314 break;
315
316 default:
317 DbgPrint("DIB_24BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
318 return FALSE;
319 }
320
321 return TRUE;
322 }
323
324 BOOLEAN
325 DIB_24BPP_BitBlt(PBLTINFO BltInfo)
326 {
327 ULONG DestX, DestY;
328 ULONG SourceX, SourceY;
329 ULONG PatternY = 0;
330 ULONG Dest, Source = 0, Pattern = 0;
331 BOOL UsesSource;
332 BOOL UsesPattern;
333 PBYTE DestBits;
334
335 UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);
336 UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);
337
338 SourceY = BltInfo->SourcePoint.y;
339 DestBits = (PBYTE)(
340 (PBYTE)BltInfo->DestSurface->pvScan0 +
341 (BltInfo->DestRect.left << 1) + BltInfo->DestRect.left +
342 BltInfo->DestRect.top * BltInfo->DestSurface->lDelta);
343
344 if (UsesPattern)
345 {
346 if (BltInfo->PatternSurface)
347 {
348 PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) %
349 BltInfo->PatternSurface->sizlBitmap.cy;
350 }
351 else
352 {
353 Pattern = BltInfo->Brush->iSolidColor;
354 }
355 }
356
357 for (DestY = BltInfo->DestRect.top; DestY < BltInfo->DestRect.bottom; DestY++)
358 {
359 SourceX = BltInfo->SourcePoint.x;
360
361 for (DestX = BltInfo->DestRect.left; DestX < BltInfo->DestRect.right; DestX++, DestBits += 3, SourceX++)
362 {
363 Dest = *((PUSHORT)DestBits) + (*(DestBits + 2) << 16);
364
365 if (UsesSource)
366 {
367 Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest);
368 }
369
370 if (BltInfo->PatternSurface)
371 {
372 Pattern = DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest);
373 }
374
375 Dest = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern) & 0xFFFFFF;
376 *(PUSHORT)(DestBits) = Dest & 0xFFFF;
377 *(DestBits + 2) = Dest >> 16;
378 }
379
380 SourceY++;
381 if (BltInfo->PatternSurface)
382 {
383 PatternY++;
384 PatternY %= BltInfo->PatternSurface->sizlBitmap.cy;
385 }
386 DestBits -= (BltInfo->DestRect.right - BltInfo->DestRect.left) * 3;
387 DestBits += BltInfo->DestSurface->lDelta;
388 }
389
390 return TRUE;
391 }
392
393 /* BitBlt Optimize */
394 BOOLEAN
395 DIB_24BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
396 {
397 ULONG DestY;
398
399 #ifdef _M_IX86
400 PBYTE xaddr = (PBYTE)DestSurface->pvScan0 + DestRect->top * DestSurface->lDelta + (DestRect->left << 1) + DestRect->left;
401 PBYTE addr;
402 ULONG Count;
403 ULONG xCount=DestRect->right - DestRect->left;
404
405 for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
406 {
407 Count = xCount;
408 addr = xaddr;
409 xaddr = (PBYTE)((ULONG_PTR)addr + DestSurface->lDelta);
410
411 if (Count < 8)
412 {
413 /* For small fills, don't bother doing anything fancy */
414 while (Count--)
415 {
416 *(PUSHORT)(addr) = color;
417 addr += 2;
418 *(addr) = color >> 16;
419 addr += 1;
420 }
421 }
422 else
423 {
424 /* Align to 4-byte address */
425 while (0 != ((ULONG_PTR) addr & 0x3))
426 {
427 *(PUSHORT)(addr) = color;
428 addr += 2;
429 *(addr) = color >> 16;
430 addr += 1;
431 Count--;
432 }
433 /* If the color we need to fill with is 0ABC, then the final mem pattern
434 * (note little-endianness) would be:
435 *
436 * |C.B.A|C.B.A|C.B.A|C.B.A| <- pixel borders
437 * |C.B.A.C|B.A.C.B|A.C.B.A| <- ULONG borders
438 *
439 * So, taking endianness into account again, we need to fill with these
440 * ULONGs: CABC BCAB ABCA */
441
442 /* This is about 30% faster than the generic C code below */
443 __asm__ __volatile__ (
444 " movl %1, %%ecx\n"
445 " andl $0xffffff, %%ecx\n" /* 0ABC */
446 " movl %%ecx, %%ebx\n" /* Construct BCAB in ebx */
447 " shrl $8, %%ebx\n"
448 " movl %%ecx, %%eax\n"
449 " shll $16, %%eax\n"
450 " orl %%eax, %%ebx\n"
451 " movl %%ecx, %%edx\n" /* Construct ABCA in edx */
452 " shll $8, %%edx\n"
453 " movl %%ecx, %%eax\n"
454 " shrl $16, %%eax\n"
455 " orl %%eax, %%edx\n"
456 " movl %%ecx, %%eax\n" /* Construct CABC in eax */
457 " shll $24, %%eax\n"
458 " orl %%ecx, %%eax\n"
459 " movl %2, %%ecx\n" /* Load count */
460 " shr $2, %%ecx\n"
461 " movl %3, %%edi\n" /* Load dest */
462 ".FL1:\n"
463 " movl %%eax, (%%edi)\n" /* Store 4 pixels, 12 bytes */
464 " movl %%ebx, 4(%%edi)\n"
465 " movl %%edx, 8(%%edi)\n"
466 " addl $12, %%edi\n"
467 " dec %%ecx\n"
468 " jnz .FL1\n"
469 " movl %%edi, %0\n"
470 : "=m"(addr)
471 : "m"(color), "m"(Count), "m"(addr)
472 : "%eax", "%ebx", "%ecx", "%edx", "%edi");
473 Count = Count & 0x03;
474 while (0 != Count--)
475 {
476 *(PUSHORT)(addr) = color;
477 addr += 2;
478 *(addr) = color >> 16;
479 addr += 1;
480 }
481 }
482 }
483 #else
484
485 for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
486 {
487 DIB_24BPP_HLine(DestSurface, DestRect->left, DestRect->right, DestY, color);
488 }
489 #endif
490 return TRUE;
491 }
492
493 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
494 BOOLEAN DIB_24BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
495 RECTL* DestRect, RECTL *SourceRect,
496 POINTL* MaskOrigin, POINTL BrushOrigin,
497 CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
498 ULONG Mode)
499 {
500 int SrcSizeY;
501 int SrcSizeX;
502 int DesSizeY;
503 int DesSizeX;
504 int sx;
505 int sy;
506 int DesX;
507 int DesY;
508 int color;
509 int zoomX;
510 int zoomY;
511 int count;
512 int saveX;
513 int saveY;
514 BOOLEAN DesIsBiggerY=FALSE;
515
516 SrcSizeY = SourceRect->bottom - SourceRect->top;
517 SrcSizeX = SourceRect->right - SourceRect->left;
518
519 DesSizeY = DestRect->bottom - DestRect->top;
520 DesSizeX = DestRect->right - DestRect->left;
521
522 zoomX = DesSizeX / SrcSizeX;
523 if (zoomX==0) zoomX=1;
524
525 zoomY = DesSizeY / SrcSizeY;
526 if (zoomY==0) zoomY=1;
527
528 if (DesSizeY>SrcSizeY)
529 DesIsBiggerY = TRUE;
530
531 switch(SourceSurf->iBitmapFormat)
532 {
533 case BMF_1BPP:
534 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
535 /* This is a reference implementation, it hasn't been optimized for speed */
536 if (zoomX>1)
537 {
538 /* Draw one Hline on X - Led to the Des Zoom In*/
539 if (DesSizeX>SrcSizeX)
540 {
541 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
542 {
543 if (DesIsBiggerY)
544 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
545 else
546 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
547
548 if (sy > SourceRect->bottom) break;
549
550 saveY = DesY+zoomY;
551
552 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
553 {
554 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
555
556 if (sx > SourceRect->right) break;
557
558 saveX = DesX + zoomX;
559
560 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
561 for (count=DesY;count<saveY;count++)
562 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, 0);
563 else
564 for (count=DesY;count<saveY;count++)
565 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, 1);
566
567 }
568 }
569 }
570 else
571 {
572 /* Draw one Hline on X - Led to the Des Zoom Out*/
573
574 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
575 {
576 if (DesIsBiggerY)
577 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
578 else
579 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
580
581 if (sy > SourceRect->bottom) break;
582
583 saveY = DesY+zoomY;
584
585 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
586 {
587 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
588
589 if (sx > SourceRect->right) break;
590
591 saveX = DesX + zoomX;
592
593 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
594 for (count=DesY;count<saveY;count++)
595 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, 0);
596 else
597 for (count=DesY;count<saveY;count++)
598 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, 1);
599
600 }
601 }
602 }
603 }
604 else
605 {
606
607 if (DesSizeX>SrcSizeX)
608 {
609 /* Draw one pixel on X - Led to the Des Zoom In*/
610 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
611 {
612 if (DesIsBiggerY)
613 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
614 else
615 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
616
617 if (sy > SourceRect->bottom) break;
618
619 saveY = DesY+zoomY;
620
621 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
622 {
623 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
624
625 if (sx > SourceRect->right) break;
626
627 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
628 for (count=DesY;count<saveY;count++)
629 DIB_24BPP_PutPixel(DestSurf, DesX, count, 0);
630 else
631 for (count=DesY;count<saveY;count++)
632 DIB_24BPP_PutPixel(DestSurf, DesX, count, 1);
633
634
635 }
636 }
637 }
638 else
639 {
640 /* Draw one pixel on X - Led to the Des Zoom Out*/
641 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
642 {
643 if (DesIsBiggerY)
644 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
645 else
646 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
647
648 if (sy > SourceRect->bottom) break;
649
650 saveY = DesY+zoomY;
651
652 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
653 {
654 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
655
656 if (sx > SourceRect->right) break;
657
658 if (DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
659 for (count=DesY;count<saveY;count++)
660 DIB_24BPP_PutPixel(DestSurf, DesX, count, 0);
661 else
662 for (count=DesY;count<saveY;count++)
663 DIB_24BPP_PutPixel(DestSurf, DesX, count, 1);
664
665 }
666 }
667 }
668 }
669 break;
670
671 case BMF_4BPP:
672 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
673 /* This is a reference implementation, it hasn't been optimized for speed */
674 if (zoomX>1)
675 {
676 /* Draw one Hline on X - Led to the Des Zoom In*/
677 if (DesSizeX>SrcSizeX)
678 {
679 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
680 {
681 if (DesIsBiggerY)
682 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
683 else
684 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
685
686 if (sy > SourceRect->bottom) break;
687
688 saveY = DesY+zoomY;
689
690 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
691 {
692 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
693
694 if (sx > SourceRect->right) break;
695
696 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
697
698 saveX = DesX + zoomX;
699 for (count=DesY;count<saveY;count++)
700 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
701 }
702 }
703 }
704 else
705 {
706 /* Draw one Hline on X - Led to the Des Zoom Out*/
707
708 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
709 {
710 if (DesIsBiggerY)
711 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
712 else
713 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
714
715 if (sy > SourceRect->bottom) break;
716
717 saveY = DesY+zoomY;
718
719 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
720 {
721 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
722
723 if (sx > SourceRect->right) break;
724
725 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
726
727 saveX = DesX + zoomX;
728 for (count=DesY;count<saveY;count++)
729 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
730 }
731 }
732 }
733 }
734
735 else
736 {
737
738 if (DesSizeX>SrcSizeX)
739 {
740 /* Draw one pixel on X - Led to the Des Zoom In*/
741 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
742 {
743 if (DesIsBiggerY)
744 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
745 else
746 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
747
748 if (sy > SourceRect->bottom) break;
749
750 saveY = DesY+zoomY;
751
752 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
753 {
754 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
755
756 if (sx > SourceRect->right) break;
757
758 color = XLATEOBJ_iXlate(ColorTranslation, DIB_4BPP_GetPixel(SourceSurf, sx, sy));
759
760 for (count=DesY;count<saveY;count++)
761 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
762 }
763 }
764 }
765 else
766 {
767 /* Draw one pixel on X - Led to the Des Zoom Out*/
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 for (count=DesY;count<saveY;count++)
788 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
789 }
790 }
791 }
792 }
793 break;
794
795 case BMF_8BPP:
796 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
797 /* This is a reference implementation, it hasn't been optimized for speed */
798 if (zoomX>1)
799 {
800 /* Draw one Hline on X - Led to the Des Zoom In*/
801 if (DesSizeX>SrcSizeX)
802 {
803 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
804 {
805 if (DesIsBiggerY)
806 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
807 else
808 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
809
810 if (sy > SourceRect->bottom) break;
811
812 saveY = DesY+zoomY;
813
814 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
815 {
816 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
817
818 if (sx > SourceRect->right) break;
819
820 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
821
822 saveX = DesX + zoomX;
823 for (count=DesY;count<saveY;count++)
824 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
825 }
826 }
827 }
828 else
829 {
830 /* Draw one Hline on X - Led to the Des Zoom Out*/
831
832 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
833 {
834 if (DesIsBiggerY)
835 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
836 else
837 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
838
839 if (sy > SourceRect->bottom) break;
840
841 saveY = DesY+zoomY;
842
843 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
844 {
845 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
846
847 if (sx > SourceRect->right) break;
848
849 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
850
851 saveX = DesX + zoomX;
852 for (count=DesY;count<saveY;count++)
853 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
854 }
855 }
856 }
857 }
858
859 else
860 {
861
862 if (DesSizeX>SrcSizeX)
863 {
864 /* Draw one pixel on X - Led to the Des Zoom In*/
865 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
866 {
867 if (DesIsBiggerY)
868 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
869 else
870 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
871
872 if (sy > SourceRect->bottom) break;
873
874 saveY = DesY+zoomY;
875
876 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
877 {
878 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
879
880 if (sx > SourceRect->right) break;
881
882 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
883
884 for (count=DesY;count<saveY;count++)
885 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
886 }
887 }
888 }
889 else
890 {
891 /* Draw one pixel on X - Led to the Des Zoom Out*/
892 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
893 {
894 if (DesIsBiggerY)
895 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
896 else
897 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
898
899 if (sy > SourceRect->bottom) break;
900
901 saveY = DesY+zoomY;
902
903 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
904 {
905 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
906
907 if (sx > SourceRect->right) break;
908
909 color = XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy));
910
911 for (count=DesY;count<saveY;count++)
912 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
913 }
914 }
915 }
916 }
917 break;
918
919 case BMF_16BPP:
920 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
921 /* This is a reference implementation, it hasn't been optimized for speed */
922 if (zoomX>1)
923 {
924 /* Draw one Hline on X - Led to the Des Zoom In*/
925 if (DesSizeX>SrcSizeX)
926 {
927 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
928 {
929 if (DesIsBiggerY)
930 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
931 else
932 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
933
934 if (sy > SourceRect->bottom) break;
935
936 saveY = DesY+zoomY;
937
938 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
939 {
940 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
941
942 if (sx > SourceRect->right) break;
943
944 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
945
946 saveX = DesX + zoomX;
947 for (count=DesY;count<saveY;count++)
948 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
949 }
950 }
951 }
952 else
953 {
954 /* Draw one Hline on X - Led to the Des Zoom Out*/
955
956 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
957 {
958 if (DesIsBiggerY)
959 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
960 else
961 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
962
963 if (sy > SourceRect->bottom) break;
964
965 saveY = DesY+zoomY;
966
967 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
968 {
969 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
970
971 if (sx > SourceRect->right) break;
972
973 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
974
975 saveX = DesX + zoomX;
976 for (count=DesY;count<saveY;count++)
977 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
978 }
979 }
980 }
981 }
982
983 else
984 {
985
986 if (DesSizeX>SrcSizeX)
987 {
988 /* Draw one pixel on X - Led to the Des Zoom In*/
989 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
990 {
991 if (DesIsBiggerY)
992 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
993 else
994 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
995
996 if (sy > SourceRect->bottom) break;
997
998 saveY = DesY+zoomY;
999
1000 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1001 {
1002 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1003
1004 if (sx > SourceRect->right) break;
1005
1006 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
1007
1008 for (count=DesY;count<saveY;count++)
1009 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
1010 }
1011 }
1012 }
1013 else
1014 {
1015 /* Draw one pixel on X - Led to the Des Zoom Out*/
1016 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1017 {
1018 if (DesIsBiggerY)
1019 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1020 else
1021 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1022
1023 if (sy > SourceRect->bottom) break;
1024
1025 saveY = DesY+zoomY;
1026
1027 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1028 {
1029 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1030
1031 if (sx > SourceRect->right) break;
1032
1033 color = XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy));
1034
1035 for (count=DesY;count<saveY;count++)
1036 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
1037 }
1038 }
1039 }
1040 }
1041 break;
1042
1043 case BMF_24BPP:
1044 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
1045 /* This is a reference implementation, it hasn't been optimized for speed */
1046 if (zoomX>1)
1047 {
1048 /* Draw one Hline on X - Led to the Des Zoom In*/
1049 if (DesSizeX>SrcSizeX)
1050 {
1051 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1052 {
1053 if (DesIsBiggerY)
1054 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1055 else
1056 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1057
1058 if (sy > SourceRect->bottom) break;
1059
1060 saveY = DesY+zoomY;
1061
1062 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1063 {
1064 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1065
1066 if (sx > SourceRect->right) break;
1067
1068 color = DIB_24BPP_GetPixel(SourceSurf, sx, sy);
1069
1070 saveX = DesX + zoomX;
1071 for (count=DesY;count<saveY;count++)
1072 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
1073 }
1074 }
1075 }
1076 else
1077 {
1078 /* Draw one Hline on X - Led to the Des Zoom Out*/
1079
1080 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1081 {
1082 if (DesIsBiggerY)
1083 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1084 else
1085 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1086
1087 if (sy > SourceRect->bottom) break;
1088
1089 saveY = DesY+zoomY;
1090
1091 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1092 {
1093 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1094
1095 if (sx > SourceRect->right) break;
1096
1097 color = DIB_24BPP_GetPixel(SourceSurf, sx, sy);
1098
1099 saveX = DesX + zoomX;
1100 for (count=DesY;count<saveY;count++)
1101 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
1102 }
1103 }
1104 }
1105 }
1106
1107 else
1108 {
1109
1110 if (DesSizeX>SrcSizeX)
1111 {
1112 /* Draw one pixel on X - Led to the Des Zoom In*/
1113 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1114 {
1115 if (DesIsBiggerY)
1116 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1117 else
1118 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1119
1120 if (sy > SourceRect->bottom) break;
1121
1122 saveY = DesY+zoomY;
1123
1124 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1125 {
1126 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1127
1128 if (sx > SourceRect->right) break;
1129
1130 color = DIB_24BPP_GetPixel(SourceSurf, sx, sy);
1131
1132 for (count=DesY;count<saveY;count++)
1133 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
1134 }
1135 }
1136 }
1137 else
1138 {
1139 /* Draw one pixel on X - Led to the Des Zoom Out*/
1140 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1141 {
1142 if (DesIsBiggerY)
1143 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1144 else
1145 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1146
1147 if (sy > SourceRect->bottom) break;
1148
1149 saveY = DesY+zoomY;
1150
1151 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1152 {
1153 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1154
1155 if (sx > SourceRect->right) break;
1156
1157 color = DIB_24BPP_GetPixel(SourceSurf, sx, sy);
1158
1159 for (count=DesY;count<saveY;count++)
1160 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
1161 }
1162 }
1163 }
1164 }
1165 break;
1166
1167 case BMF_32BPP:
1168 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
1169 /* This is a reference implementation, it hasn't been optimized for speed */
1170 if (zoomX>1)
1171 {
1172 /* Draw one Hline on X - Led to the Des Zoom In*/
1173 if (DesSizeX>SrcSizeX)
1174 {
1175 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1176 {
1177 if (DesIsBiggerY)
1178 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1179 else
1180 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1181
1182 if (sy > SourceRect->bottom) break;
1183
1184 saveY = DesY+zoomY;
1185
1186 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1187 {
1188 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1189
1190 if (sx > SourceRect->right) break;
1191
1192 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1193
1194 saveX = DesX + zoomX;
1195 for (count=DesY;count<saveY;count++)
1196 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
1197 }
1198 }
1199 }
1200 else
1201 {
1202 /* Draw one Hline on X - Led to the Des Zoom Out*/
1203
1204 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1205 {
1206 if (DesIsBiggerY)
1207 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1208 else
1209 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1210
1211 if (sy > SourceRect->bottom) break;
1212
1213 saveY = DesY+zoomY;
1214
1215 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1216 {
1217 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1218
1219 if (sx > SourceRect->right) break;
1220
1221 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1222
1223 saveX = DesX + zoomX;
1224 for (count=DesY;count<saveY;count++)
1225 DIB_24BPP_HLine(DestSurf, DesX, saveX, count, color);
1226 }
1227 }
1228 }
1229 }
1230
1231 else
1232 {
1233
1234 if (DesSizeX>SrcSizeX)
1235 {
1236 /* Draw one pixel on X - Led to the Des Zoom In*/
1237 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1238 {
1239 if (DesIsBiggerY)
1240 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1241 else
1242 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1243
1244 if (sy > SourceRect->bottom) break;
1245
1246 saveY = DesY+zoomY;
1247
1248 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1249 {
1250 sx = (int) ((ULONG) SrcSizeX * (ULONG) DesX) / ((ULONG) DesSizeX);
1251
1252 if (sx > SourceRect->right) break;
1253
1254 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1255
1256 for (count=DesY;count<saveY;count++)
1257 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
1258 }
1259 }
1260 }
1261 else
1262 {
1263 /* Draw one pixel on X - Led to the Des Zoom Out*/
1264 for (DesY=DestRect->bottom-zoomY; DesY>=0; DesY-=zoomY)
1265 {
1266 if (DesIsBiggerY)
1267 sy = (int) ((ULONG) SrcSizeY * (ULONG) DesY) / ((ULONG) DesSizeY);
1268 else
1269 sy = (int) ((ULONG) DesSizeY * (ULONG) DesY) / ((ULONG) SrcSizeY);
1270
1271 if (sy > SourceRect->bottom) break;
1272
1273 saveY = DesY+zoomY;
1274
1275 for (DesX=DestRect->right-zoomX; DesX>=0; DesX-=zoomX)
1276 {
1277 sx = (int) ((ULONG) DesSizeX * (ULONG) DesX) / ((ULONG) SrcSizeX);
1278
1279 if (sx > SourceRect->right) break;
1280
1281 color = XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy));
1282
1283 for (count=DesY;count<saveY;count++)
1284 DIB_24BPP_PutPixel(DestSurf, DesX, count, color);
1285 }
1286 }
1287 }
1288 }
1289 break;
1290
1291 default:
1292 //DPRINT1("DIB_24BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf->iBitmapFormat));
1293 return FALSE;
1294 }
1295
1296 return TRUE;
1297 }
1298
1299 BOOLEAN
1300 DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
1301 RECTL* DestRect, POINTL *SourcePoint,
1302 XLATEOBJ *ColorTranslation, ULONG iTransColor)
1303 {
1304 ULONG X, Y, SourceX, SourceY, Source, wd, Dest;
1305 BYTE *DestBits;
1306
1307 SourceY = SourcePoint->y;
1308 DestBits = (BYTE*)((PBYTE)DestSurf->pvScan0 +
1309 (DestRect->left << 2) +
1310 DestRect->top * DestSurf->lDelta);
1311 wd = DestSurf->lDelta - ((DestRect->right - DestRect->left) << 2);
1312
1313 for(Y = DestRect->top; Y < DestRect->bottom; Y++)
1314 {
1315 SourceX = SourcePoint->x;
1316 for(X = DestRect->left; X < DestRect->right; X++, DestBits += 3, SourceX++)
1317 {
1318 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
1319 if(Source != iTransColor)
1320 {
1321 Dest = XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFFFF;
1322 *(PUSHORT)(DestBits) = Dest & 0xFFFF;
1323 *(DestBits + 2) = Dest >> 16;
1324 }
1325 }
1326
1327 SourceY++;
1328 DestBits = (BYTE*)((ULONG_PTR)DestBits + wd);
1329 }
1330
1331 return TRUE;
1332 }
1333
1334 typedef union {
1335 ULONG ul;
1336 struct {
1337 UCHAR red;
1338 UCHAR green;
1339 UCHAR blue;
1340 UCHAR alpha;
1341 } col;
1342 } NICEPIXEL32;
1343
1344 STATIC inline UCHAR
1345 Clamp8(ULONG val)
1346 {
1347 return (val > 255) ? 255 : val;
1348 }
1349
1350 BOOLEAN
1351 DIB_24BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
1352 RECTL* SourceRect, CLIPOBJ* ClipRegion,
1353 XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
1354 {
1355 INT Rows, Cols, SrcX, SrcY;
1356 register PUCHAR Dst;
1357 ULONG DstDelta;
1358 BLENDFUNCTION BlendFunc;
1359 register NICEPIXEL32 DstPixel, SrcPixel;
1360 UCHAR Alpha, SrcBpp;
1361
1362 DPRINT("DIB_24BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
1363 SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
1364 DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
1365
1366 ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top &&
1367 DestRect->right - DestRect->left == SourceRect->right - SourceRect->left);
1368
1369 BlendFunc = BlendObj->BlendFunction;
1370 if (BlendFunc.BlendOp != AC_SRC_OVER)
1371 {
1372 DPRINT1("BlendOp != AC_SRC_OVER\n");
1373 return FALSE;
1374 }
1375 if (BlendFunc.BlendFlags != 0)
1376 {
1377 DPRINT1("BlendFlags != 0\n");
1378 return FALSE;
1379 }
1380 if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0)
1381 {
1382 DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat);
1383 return FALSE;
1384 }
1385 if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 &&
1386 BitsPerFormat(Source->iBitmapFormat) != 32)
1387 {
1388 DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
1389 return FALSE;
1390 }
1391
1392 Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
1393 (DestRect->left * 3));
1394 DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) * 3);
1395 SrcBpp = BitsPerFormat(Source->iBitmapFormat);
1396
1397 Rows = DestRect->bottom - DestRect->top;
1398 SrcY = SourceRect->top;
1399 while (--Rows >= 0)
1400 {
1401 Cols = DestRect->right - DestRect->left;
1402 SrcX = SourceRect->left;
1403 while (--Cols >= 0)
1404 {
1405 SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
1406 SrcPixel.col.red = SrcPixel.col.red * BlendFunc.SourceConstantAlpha / 255;
1407 SrcPixel.col.green = SrcPixel.col.green * BlendFunc.SourceConstantAlpha / 255;
1408 SrcPixel.col.blue = SrcPixel.col.blue * BlendFunc.SourceConstantAlpha / 255;
1409 SrcPixel.col.alpha = (SrcBpp == 32) ? (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha;
1410
1411 Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
1412 SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha;
1413
1414 DstPixel.ul = *Dst;
1415 DstPixel.col.red = Clamp8(DstPixel.col.red * (255 - Alpha) / 255 + SrcPixel.col.red);
1416 DstPixel.col.green = Clamp8(DstPixel.col.green * (255 - Alpha) / 255 + SrcPixel.col.green);
1417 DstPixel.col.blue = Clamp8(DstPixel.col.blue * (255 - Alpha) / 255 + SrcPixel.col.blue);
1418 *Dst = DstPixel.ul;
1419 Dst = (PUCHAR)((ULONG_PTR)Dst + 3);
1420 }
1421 Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta);
1422 SrcY++;
1423 }
1424
1425 return TRUE;
1426 }
1427
1428 /* EOF */