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