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