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