DIB Engine: fixes clipping, text and more
[wine/hacks.git] / dlls / winedib.drv / primitives_bitblt.c
blob7feeb49ddef34e89aef685b8d7795a0025bbad3a
1 /*
2 * DIB Engine BitBlt Primitives
4 * Copyright 2009 Massimo Del Fedele
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
24 #include "dibdrv.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
28 /* shrinks a line -- srcWidth >= dstWidth */
29 static void ShrinkLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth)
31 int srcPos, dstPos;
32 int delta;
34 srcPos = 0;
35 dstPos = 0;
36 delta = 0;
37 while(dstPos < dstWidth)
39 *dst++ = *src;
40 while(delta < srcWidth)
42 srcPos++;
43 src++;
44 delta += dstWidth;
46 delta -= srcWidth;
47 dstPos++;
51 /* expands a line -- srcWidth <= dstWidth */
52 static void ExpandLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth)
54 int srcPos;
55 int delta;
57 srcPos = 0;
58 delta = 0;
59 while(srcPos < srcWidth)
61 while(delta < dstWidth)
63 *dst++ = *src;
64 delta += srcWidth;
66 delta -= dstWidth;
67 src++;
68 srcPos++;
72 /* stretch a line */
73 static void StretchLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth)
75 if(srcWidth > dstWidth)
76 ShrinkLine(dst, dstWidth, src, srcWidth);
77 else if(srcWidth < dstWidth)
78 ExpandLine(dst, dstWidth, src, srcWidth);
79 else
80 memcpy(dst, src, 4 * srcWidth);
83 /* premultiply alpha channel on a line by a constant alpha
84 note : it seems that pixels are already premultiplied
85 by alpha channel content */
86 static void PemultiplyLine(DWORD *dst, int width, BYTE constAlpha)
88 int i = width;
89 BYTE *alphaPnt = (BYTE *)dst + 3;
91 /* small optimization for 0 and 255 values of constAlpha */
93 /* fully transparent -- just sets all pix to 0 */
94 if(constAlpha == 0)
96 while(i--)
97 *dst++ = 0;
98 return;
101 /* fully opaque, just do nothing */
102 if(constAlpha == 255)
103 return;
105 /* intermediate -- premultiply alpha values */
106 while(i--)
108 *alphaPnt = MulDiv(*alphaPnt, constAlpha, 255);
109 alphaPnt += 4;
111 return;
115 /* alpha blends a source line onto a destination line
116 preconditions :
117 1) source and dest widths must be the same
118 2) source line should be already premultiplied by constant alpha */
119 static void BlendLine(DWORD *dst, DWORD *src, int width)
121 int i = width;
122 BYTE *blueDst = (BYTE *)dst;
123 BYTE *greenDst = blueDst + 1;
124 BYTE *redDst = greenDst + 1;
125 BYTE *blueSrc = (BYTE *)src;
126 BYTE *greenSrc = blueSrc + 1;
127 BYTE *redSrc = greenSrc + 1;
128 BYTE *alphaSrc = redSrc + 1;
129 BYTE alpha;
131 /* still don't know if it must take in account an eventual dest
132 alpha channel..... */
133 while(i--)
135 alpha = 255 - *alphaSrc;
137 *blueDst = *blueSrc + MulDiv(*blueDst, alpha, 255);
138 *greenDst = *greenSrc + MulDiv(*greenDst, alpha, 255);
139 *redDst = *redSrc + MulDiv(*redDst, alpha, 255);
141 blueSrc += 4;
142 greenSrc += 4;
143 redSrc += 4;
144 alphaSrc += 4;
145 blueDst += 4;
146 greenDst += 4;
147 redDst += 4;
152 /* ------------------------------------------------------------*/
153 /* ALPHABLEND PRIMITIVES */
154 BOOL _DIBDRV_AlphaBlend_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
155 INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc,
156 INT xSrc, INT ySrc, int widthSrc, int heightSrc, BLENDFUNCTION blendFn)
158 /* flags indicating wether source should be stretched */
159 BOOL horStretch = (widthSrc != widthDst);
160 BOOL verStretch = (heightSrc != heightDst);
162 /* constant alpha value */
163 BYTE constAlpha = blendFn.SourceConstantAlpha;
165 /* source and dest bitmaps */
166 const DIBDRVBITMAP *srcBmp = &physDevSrc->physBitmap;
167 DIBDRVBITMAP *dstBmp = &physDevDst->physBitmap;
169 /* source and destination line buffers */
170 DWORD *sBuf = HeapAlloc(GetProcessHeap(), 0, abs(srcBmp->stride));
171 DWORD *dBuf = HeapAlloc(GetProcessHeap(), 0, abs(dstBmp->stride));
173 int ys = ySrc;
174 int yd = yDst;
175 int iLine;
176 int delta;
178 /* in order to optimize a bit, we divide the routine in 4 parts,
179 depending on stretching modes */
180 if(!horStretch && !verStretch)
182 /* simplest case, no stretching needed */
183 MAYBE(TRACE("No stretching\n"));
184 for(iLine = 0; iLine < heightSrc; iLine++, ys++, yd++)
186 /* load source and dest lines */
187 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
188 dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
190 /* premultiply source by constant and pixel alpha */
191 PemultiplyLine(sBuf, widthSrc, constAlpha);
193 /* blends source on dest */
194 BlendLine(dBuf, sBuf, widthSrc);
196 /* puts dest line back */
197 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
200 else if (horStretch && !verStretch)
202 /* just horizontal stretching needed */
203 DWORD *strBuf = HeapAlloc(GetProcessHeap(), 0, abs(dstBmp->stride));
204 MAYBE(TRACE("Horizontal stretching\n"));
206 for(iLine = 0; iLine < heightSrc; iLine++, ys++, yd++)
208 /* load source and dest lines */
209 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
210 dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
212 /* stretch source line to match dest one */
213 StretchLine(strBuf, widthDst, sBuf, widthSrc);
215 /* premultiply source by constant and pixel alpha */
216 PemultiplyLine(strBuf, widthDst, constAlpha);
218 /* blends source on dest */
219 BlendLine(dBuf, strBuf, widthDst);
221 /* puts dest line back */
222 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
224 HeapFree(GetProcessHeap(), 0, strBuf);
226 else if (!horStretch && verStretch)
228 /* just vertical stretching needed */
229 MAYBE(TRACE("Vertical stretching\n"));
231 if(heightSrc > heightDst)
233 iLine = 0;
234 delta = 0;
235 while(iLine < heightDst)
237 /* load source and dest lines */
238 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
239 dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
241 /* premultiply source by constant and pixel alpha */
242 PemultiplyLine(sBuf, widthSrc, constAlpha);
244 /* blends source on dest */
245 BlendLine(dBuf, sBuf, widthDst);
247 /* puts dest line back */
248 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
250 while(delta < heightSrc)
252 ys++;
253 delta += heightDst;
255 delta -= heightSrc;
256 yd++;
257 iLine++;
260 else if(heightSrc < heightDst)
262 iLine = 0;
263 delta = 0;
264 while(iLine < heightSrc)
266 /* load source line */
267 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
269 /* premultiply source by constant and pixel alpha */
270 PemultiplyLine(sBuf, widthSrc, constAlpha);
272 while(delta < heightDst)
274 /* load dest line */
275 dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
277 /* blends source on dest */
278 BlendLine(dBuf, sBuf, widthDst);
280 /* puts dest line back */
281 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
282 yd++;
283 delta += heightSrc;
285 delta -= heightDst;
286 ys++;
287 iLine++;
291 else
293 DWORD *strBuf = HeapAlloc(GetProcessHeap(), 0, abs(dstBmp->stride));
294 /* both stretching needed -- generic case */
295 MAYBE(TRACE("Horizontal and vertical stretching\n"));
297 if(heightSrc > heightDst)
299 iLine = 0;
300 delta = 0;
301 while(iLine < heightDst)
303 /* load source and dest lines */
304 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
305 dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
307 /* stretch source line to match dest one */
308 StretchLine(strBuf, widthDst, sBuf, widthSrc);
310 /* premultiply source by constant and pixel alpha */
311 PemultiplyLine(strBuf, widthDst, constAlpha);
313 /* blends source on dest */
314 BlendLine(dBuf, strBuf, widthDst);
316 /* puts dest line back */
317 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
319 while(delta < heightSrc)
321 ys++;
322 delta += heightDst;
324 delta -= heightSrc;
325 yd++;
326 iLine++;
329 else if(heightSrc < heightDst)
331 iLine = 0;
332 delta = 0;
333 while(iLine < heightSrc)
335 /* load source line */
336 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
338 /* stretch source line to match dest one */
339 StretchLine(strBuf, widthDst, sBuf, widthSrc);
341 /* premultiply source by constant and pixel alpha */
342 PemultiplyLine(strBuf, widthDst, constAlpha);
344 while(delta < heightDst)
346 /* load dest line */
347 dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
349 /* blends source on dest */
350 BlendLine(dBuf, strBuf, widthDst);
352 /* puts dest line back */
353 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
354 yd++;
355 delta += heightSrc;
357 delta -= heightDst;
358 ys++;
359 iLine++;
362 HeapFree(GetProcessHeap(), 0, strBuf);
365 HeapFree(GetProcessHeap(), 0, sBuf);
366 HeapFree(GetProcessHeap(), 0, dBuf);
367 return TRUE;
370 /* ------------------------------------------------------------*/
371 /* BLITTING PRIMITIVES */
372 BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
373 INT width, INT height, const DIBDRVPHYSDEV *physDevSrc,
374 INT xSrc, INT ySrc, DWORD rop)
376 int ys, yd;
377 int i;
378 DWORD *dwBuf;
379 DIBDRVBITMAP *dstBmp, *patBmp;
380 const DIBDRVBITMAP *srcBmp;
381 DWORD *wDstPnt, *wSrcPnt, *wPatPnt;
382 BOOL usePat, useSrc, useDst;
383 DWORD patColor;
384 BOOL res = FALSE;
386 /* 32 bit RGB source and destination buffer, if needed */
387 DWORD *sBuf = 0, *dBuf = 0, *pBuf = 0;
389 /* get elements usage */
390 usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000));
391 useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
392 useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
394 /* sanity check -- MSN messenger crashes without */
395 if(useSrc && !physDevSrc)
396 return FALSE;
398 /* gets source, dest and pattern bitmaps, if available */
399 if(usePat && physDevDst->isBrushBitmap)
400 patBmp = &physDevDst->brushBmpCache;
401 else
402 patBmp = NULL;
404 if(useSrc)
405 srcBmp = &physDevSrc->physBitmap;
406 else
407 srcBmp = NULL;
408 dstBmp = &physDevDst->physBitmap;
410 /* gets pattern color, in case it's needed */
411 if(usePat)
412 patColor = physDevDst->brushColor;
413 else
414 patColor = 0;
416 /* allocate 32 bit RGB destination buffer */
417 if(!(dBuf = (DWORD *)HeapAlloc( GetProcessHeap(), 0, width * 4)))
418 goto error;
420 MAYBE(TRACE("dstBmp:%p(%s), xDst:%d, yDst:%d, width:%d, height:%d, srcBmp:%p(%s), xSrc:%d, ySrc:%d, rop:%8x\n",
421 dstBmp, _DIBDRVBITMAP_GetFormatName(dstBmp), xDst, yDst, width, height,
422 srcBmp, _DIBDRVBITMAP_GetFormatName(srcBmp), xSrc, ySrc, rop));
424 /* some simple ROPs optimizations */
425 switch(rop)
427 case BLACKNESS:
428 MAYBE(TRACE("BLACKNESS\n"));
429 memset(dBuf, 0x00, width * 4);
430 for(yd = yDst; yd < yDst+height; yd++)
431 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
432 break;
434 case WHITENESS:
435 MAYBE(TRACE("WHITENESS\n"));
436 for(dwBuf = dBuf, i = width; i; i--)
437 *dwBuf++ = 0x00ffffff;
438 for(yd = yDst; yd < yDst+height; yd++)
439 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
440 break;
442 case SRCCOPY:
443 MAYBE(TRACE("SRCCOPY\n"));
444 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
446 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
447 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
449 break;
451 /* fallback for generic ROP operation */
452 default:
453 rop >>= 16;
454 if(useSrc && useDst && usePat && physDevDst->isBrushBitmap)
456 MAYBE(TRACE("BitBlt use: src+dst+pat - pattern brush\n"));
457 if(!(sBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
458 goto error;
459 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
460 goto error;
461 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
463 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, sBuf);
464 dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf);
465 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
466 wDstPnt = dBuf;
467 wSrcPnt = sBuf;
468 wPatPnt = pBuf;
469 for(i = width; i > 0 ; i--)
471 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
472 wDstPnt++;
474 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
477 else if(useSrc && useDst)
479 if(usePat)
480 MAYBE(TRACE("BitBlt use: src+dst+pat - solid brush\n"));
481 else
482 MAYBE(TRACE("BitBlt use: src+dst\n"));
483 if(!(sBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
484 goto error;
485 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
487 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, sBuf);
488 dstBmp->funcs->GetLine(dstBmp, yd, xDst, width, dBuf);
489 wDstPnt = dBuf;
490 wSrcPnt = sBuf;
491 for(i = width; i > 0 ; i--)
493 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
494 wDstPnt++;
496 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
499 else if(useSrc && usePat && physDevDst->isBrushBitmap)
501 MAYBE(TRACE("BitBlt use: src+pat -- pattern brush\n"));
502 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
503 goto error;
504 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
506 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
507 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
508 wDstPnt = dBuf;
509 wSrcPnt = dBuf;
510 wPatPnt = pBuf;
511 for(i = width; i > 0 ; i--)
513 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
514 wDstPnt++;
516 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
519 else if(useSrc)
521 if(usePat)
522 MAYBE(TRACE("BitBlt use: src+pat - solid brush\n"));
523 else
524 MAYBE(TRACE("BitBlt use: src\n"));
525 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
527 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
528 wDstPnt = dBuf;
529 wSrcPnt = dBuf;
530 for(i = width; i > 0 ; i--)
532 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
533 wDstPnt++;
535 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
538 else if(useDst && usePat && physDevDst->isBrushBitmap)
540 MAYBE(TRACE("BitBlt use: dst+pat -- pattern brush\n"));
541 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
542 goto error;
543 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
545 dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf);
546 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
547 wDstPnt = dBuf;
548 wPatPnt = pBuf;
549 for(i = width; i > 0 ; i--)
551 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
552 wDstPnt++;
554 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
557 else if(useDst)
559 if(usePat)
560 MAYBE(TRACE("BitBlt use: dst+pat - solid brush\n"));
561 else
562 MAYBE(TRACE("BitBlt use: dst\n"));
563 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
565 dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf);
566 wDstPnt = dBuf;
567 for(i = width; i > 0 ; i--)
569 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
570 wDstPnt++;
572 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
575 else if(usePat && physDevDst->isBrushBitmap)
577 MAYBE(TRACE("BitBlt use: pat -- pattern brush\n"));
578 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
579 goto error;
580 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
582 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
583 wDstPnt = dBuf;
584 wPatPnt = pBuf;
585 for(i = width; i > 0 ; i--)
587 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
588 wDstPnt++;
590 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
593 else if(usePat)
595 MAYBE(TRACE("BitBlt use: pat -- solid brush -- rop is %02x, color is %08x\n", rop, patColor));
596 MAYBE(TRACE("Dest BMP is a '%s'\n", _DIBDRVBITMAP_GetFormatName(dstBmp)));
597 MAYBE(TRACE("xDst = %d, yDst = %d, width = %d, height = %d\n", xDst, yDst, width, height));
598 for(yd = yDst; yd < yDst+height; yd++)
600 wDstPnt = dBuf;
601 for(i = width; i > 0 ; i--)
603 *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
604 wDstPnt++;
606 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
609 else
610 ERR("What happened ?????? \n");
611 break;
612 } /* switch */
613 res = TRUE;
614 error:
615 if(sBuf) HeapFree( GetProcessHeap(), 0, sBuf );
616 if(dBuf) HeapFree( GetProcessHeap(), 0, dBuf );
617 if(pBuf) HeapFree( GetProcessHeap(), 0, pBuf );
618 return res;
621 /* ------------------------------------------------------------*/
622 /* STRETCHING PRIMITIVES */
623 BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
624 INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc,
625 INT xSrc, INT ySrc, int widthSrc, int heightSrc, DWORD rop)
627 int ys, yd;
628 int i, delta;
629 DWORD *dwBuf;
630 DIBDRVBITMAP *dstBmp, *patBmp;
631 const DIBDRVBITMAP *srcBmp;
632 DWORD *wDstPnt, *wSrcPnt, *wPatPnt;
633 BOOL usePat, useSrc, useDst;
634 DWORD patColor;
635 BOOL res = FALSE;
637 /* 32 bit RGB source and destination buffer, if needed */
638 DWORD *sBufOrig = 0, *sBufStr = 0, *dBuf = 0, *pBuf = 0;
640 /* get elements usage */
641 usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000));
642 useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
643 useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
645 /* sanity check -- MSN messenger crashes without */
646 if(useSrc && !physDevSrc)
647 return FALSE;
649 /* gets source, dest and pattern bitmaps, if available */
650 if(usePat && physDevDst->isBrushBitmap)
651 patBmp = &physDevDst->brushBmpCache;
652 else
653 patBmp = NULL;
655 if(useSrc)
656 srcBmp = &physDevSrc->physBitmap;
657 else
658 srcBmp = NULL;
659 dstBmp = &physDevDst->physBitmap;
661 /* gets pattern color, in case it's needed */
662 if(usePat)
663 patColor = physDevDst->brushColor;
664 else
665 patColor = 0;
667 /* allocate 32 bit RGB destination buffer */
668 if(!(dBuf = (DWORD *)HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
669 goto error;
671 MAYBE(TRACE("dstBmp:%p(%s), xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, srcBmp:%p(%s), xSrc:%d, ySrc:%d, , widthSrc:%d, heightSrc:%drop:%8x\n",
672 dstBmp, _DIBDRVBITMAP_GetFormatName(dstBmp), xDst, yDst, widthDst, heightDst,
673 srcBmp, _DIBDRVBITMAP_GetFormatName(srcBmp), xSrc, ySrc, widthSrc, heightSrc, rop));
675 /* some simple ROPs optimizations */
676 switch(rop)
678 case BLACKNESS:
679 MAYBE(TRACE("BLACKNESS\n"));
680 memset(dBuf, 0x00, widthDst * 4);
681 for(yd = yDst; yd < yDst+heightDst; yd++)
682 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
683 break;
685 case WHITENESS:
686 MAYBE(TRACE("WHITENESS\n"));
687 for(dwBuf = dBuf, i = widthDst; i; i--)
688 *dwBuf++ = 0x00ffffff;
689 for(yd = yDst; yd < yDst+heightDst; yd++)
690 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
691 break;
693 case SRCCOPY:
694 MAYBE(TRACE("SRCCOPY\n"));
695 sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4);
696 if(heightSrc > heightDst)
698 ys = 0;
699 yd = 0;
700 delta = 0;
701 while(yd < heightDst)
703 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
704 StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
705 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
706 while(delta < heightSrc)
708 ys++;
709 delta += heightDst;
711 delta -= heightSrc;
712 yd++;
715 else if(heightSrc < heightDst)
717 ys = 0;
718 yd = 0;
719 delta = 0;
720 while(ys < heightSrc)
722 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
723 StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
724 while(delta < heightDst)
726 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
727 yd++;
728 delta += heightSrc;
730 delta -= heightDst;
731 ys++;
734 else
736 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
738 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
739 StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
740 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
743 break;
745 /* fallback for generic ROP operation */
746 default:
747 rop >>= 16;
748 if(useSrc && useDst && usePat && physDevDst->isBrushBitmap)
750 MAYBE(TRACE("StretchBlt use: src+dst+pat - pattern brush\n"));
751 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
752 goto error;
753 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
754 goto error;
755 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
756 goto error;
757 if(heightSrc > heightDst)
759 ys = 0;
760 yd = 0;
761 delta = 0;
762 while(yd < heightDst)
764 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
765 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
766 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
767 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
768 wDstPnt = dBuf;
769 wSrcPnt = sBufStr;
770 wPatPnt = pBuf;
771 for(i = widthDst; i > 0 ; i--)
773 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
774 wDstPnt++;
776 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
777 while(delta < heightSrc)
779 ys++;
780 delta += heightDst;
782 delta -= heightSrc;
783 yd++;
786 else if(heightSrc < heightDst)
788 ys = 0;
789 yd = 0;
790 delta = 0;
791 while(ys < heightSrc)
793 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
794 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
795 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
796 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
797 while(delta < heightDst)
799 wDstPnt = dBuf;
800 wSrcPnt = sBufStr;
801 wPatPnt = pBuf;
802 for(i = widthDst; i > 0 ; i--)
804 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
805 wDstPnt++;
807 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
808 yd++;
809 delta += heightSrc;
811 delta -= heightDst;
812 ys++;
815 else
817 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
819 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
820 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
821 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
822 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
823 wDstPnt = dBuf;
824 wSrcPnt = sBufStr;
825 wPatPnt = pBuf;
826 for(i = widthDst; i > 0 ; i--)
828 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
829 wDstPnt++;
831 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
835 else if(useSrc && useDst)
837 if(usePat)
838 MAYBE(TRACE("StretchBlt use: src+dst+pat - solid brush\n"));
839 else
840 MAYBE(TRACE("StretchBlt use: src+dst\n"));
841 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
842 goto error;
843 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
844 goto error;
845 if(heightSrc > heightDst)
847 ys = 0;
848 yd = 0;
849 delta = 0;
850 while(yd < heightDst)
852 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
853 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
854 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
855 wDstPnt = dBuf;
856 wSrcPnt = sBufStr;
857 for(i = widthDst; i > 0 ; i--)
859 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
860 wDstPnt++;
862 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
863 while(delta < heightSrc)
865 ys++;
866 delta += heightDst;
868 delta -= heightSrc;
869 yd++;
872 else if(heightSrc < heightDst)
874 ys = 0;
875 yd = 0;
876 delta = 0;
877 while(ys < heightSrc)
879 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
880 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
881 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
882 while(delta < heightDst)
884 wDstPnt = dBuf;
885 wSrcPnt = sBufStr;
886 for(i = widthDst; i > 0 ; i--)
888 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
889 wDstPnt++;
891 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
892 yd++;
893 delta += heightSrc;
895 delta -= heightDst;
896 ys++;
899 else
901 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
903 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
904 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
905 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
906 wDstPnt = dBuf;
907 wSrcPnt = sBufStr;
908 for(i = widthDst; i > 0 ; i--)
910 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
911 wDstPnt++;
913 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
917 else if(useSrc && usePat && physDevDst->isBrushBitmap)
919 MAYBE(TRACE("StretchBlt use: src+pat -- pattern brush\n"));
920 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
921 goto error;
922 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
923 goto error;
924 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
925 goto error;
926 if(heightSrc > heightDst)
928 ys = 0;
929 yd = 0;
930 delta = 0;
931 while(yd < heightDst)
933 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
934 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
935 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
936 wDstPnt = dBuf;
937 wSrcPnt = sBufStr;
938 wPatPnt = pBuf;
939 for(i = widthDst; i > 0 ; i--)
941 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
942 wDstPnt++;
944 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
945 while(delta < heightSrc)
947 ys++;
948 delta += heightDst;
950 delta -= heightSrc;
951 yd++;
954 else if(heightSrc < heightDst)
956 ys = 0;
957 yd = 0;
958 delta = 0;
959 while(ys < heightSrc)
961 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
962 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
963 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
964 while(delta < heightDst)
966 wDstPnt = dBuf;
967 wSrcPnt = sBufStr;
968 wPatPnt = pBuf;
969 for(i = widthDst; i > 0 ; i--)
971 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
972 wDstPnt++;
974 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
975 yd++;
976 delta += heightSrc;
978 delta -= heightDst;
979 ys++;
982 else
984 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
986 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
987 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
988 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
989 wDstPnt = dBuf;
990 wSrcPnt = sBufStr;
991 wPatPnt = pBuf;
992 for(i = widthDst; i > 0 ; i--)
994 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
995 wDstPnt++;
997 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1001 else if(useSrc)
1003 if(usePat)
1004 MAYBE(TRACE("StretchBlt use: src+pat - solid brush\n"));
1005 else
1006 MAYBE(TRACE("StretchBlt use: src\n"));
1007 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
1008 goto error;
1009 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
1010 goto error;
1011 if(heightSrc > heightDst)
1013 ys = 0;
1014 yd = 0;
1015 delta = 0;
1016 while(yd < heightDst)
1018 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
1019 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
1020 wDstPnt = dBuf;
1021 wSrcPnt = sBufStr;
1022 for(i = widthDst; i > 0 ; i--)
1024 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
1025 wDstPnt++;
1027 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1028 while(delta < heightSrc)
1030 ys++;
1031 delta += heightDst;
1033 delta -= heightSrc;
1034 yd++;
1037 else if(heightSrc < heightDst)
1039 ys = 0;
1040 yd = 0;
1041 delta = 0;
1042 while(ys < heightSrc)
1044 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
1045 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
1046 while(delta < heightDst)
1048 wDstPnt = dBuf;
1049 wSrcPnt = sBufStr;
1050 for(i = widthDst; i > 0 ; i--)
1052 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
1053 wDstPnt++;
1055 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1056 yd++;
1057 delta += heightSrc;
1059 delta -= heightDst;
1060 ys++;
1063 else
1065 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
1067 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
1068 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
1069 wDstPnt = dBuf;
1070 wSrcPnt = sBufStr;
1071 for(i = widthDst; i > 0 ; i--)
1073 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
1074 wDstPnt++;
1076 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1080 else if(useDst && usePat && physDevDst->isBrushBitmap)
1082 MAYBE(TRACE("StretchBlt use: dst+pat -- pattern brush\n"));
1083 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
1084 goto error;
1085 if(heightSrc > heightDst)
1087 ys = 0;
1088 yd = 0;
1089 delta = 0;
1090 while(yd < heightDst)
1092 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1093 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
1094 wDstPnt = dBuf;
1095 wPatPnt = pBuf;
1096 for(i = widthDst; i > 0 ; i--)
1098 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
1099 wDstPnt++;
1101 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1102 while(delta < heightSrc)
1104 ys++;
1105 delta += heightDst;
1107 delta -= heightSrc;
1108 yd++;
1111 else if(heightSrc < heightDst)
1113 ys = 0;
1114 yd = 0;
1115 delta = 0;
1116 while(ys < heightSrc)
1118 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1119 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
1120 while(delta < heightDst)
1122 wDstPnt = dBuf;
1123 wPatPnt = pBuf;
1124 for(i = widthDst; i > 0 ; i--)
1126 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
1127 wDstPnt++;
1129 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1130 yd++;
1131 delta += heightSrc;
1133 delta -= heightDst;
1134 ys++;
1137 else
1139 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
1141 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
1142 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
1143 wDstPnt = dBuf;
1144 wPatPnt = pBuf;
1145 for(i = widthDst; i > 0 ; i--)
1147 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
1148 wDstPnt++;
1150 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1154 else if(useDst)
1156 if(usePat)
1157 MAYBE(TRACE("StretchBlt use: dst+pat - solid brush\n"));
1158 else
1159 MAYBE(TRACE("StretchBlt use: dst\n"));
1160 if(heightSrc > heightDst)
1162 ys = 0;
1163 yd = 0;
1164 delta = 0;
1165 while(yd < heightDst)
1167 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1168 wDstPnt = dBuf;
1169 for(i = widthDst; i > 0 ; i--)
1171 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
1172 wDstPnt++;
1174 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1175 while(delta < heightSrc)
1177 ys++;
1178 delta += heightDst;
1180 delta -= heightSrc;
1181 yd++;
1184 else if(heightSrc < heightDst)
1186 ys = 0;
1187 yd = 0;
1188 delta = 0;
1189 while(ys < heightSrc)
1191 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1192 while(delta < heightDst)
1194 wDstPnt = dBuf;
1195 for(i = widthDst; i > 0 ; i--)
1197 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
1198 wDstPnt++;
1200 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1201 yd++;
1202 delta += heightSrc;
1204 delta -= heightDst;
1205 ys++;
1208 else
1210 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
1212 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
1213 wDstPnt = dBuf;
1214 for(i = widthDst; i > 0 ; i--)
1216 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
1217 wDstPnt++;
1219 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1223 else if(usePat && physDevDst->isBrushBitmap)
1225 MAYBE(TRACE("StretchBlt use: pat -- pattern brush\n"));
1226 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
1227 goto error;
1228 if(heightSrc > heightDst)
1230 ys = 0;
1231 yd = 0;
1232 delta = 0;
1233 while(yd < heightDst)
1235 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
1236 wDstPnt = dBuf;
1237 wPatPnt = pBuf;
1238 for(i = widthDst; i > 0 ; i--)
1240 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
1241 wDstPnt++;
1243 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1244 while(delta < heightSrc)
1246 ys++;
1247 delta += heightDst;
1249 delta -= heightSrc;
1250 yd++;
1253 else if(heightSrc < heightDst)
1255 ys = 0;
1256 yd = 0;
1257 delta = 0;
1258 while(ys < heightSrc)
1260 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
1261 while(delta < heightDst)
1263 wDstPnt = dBuf;
1264 wPatPnt = pBuf;
1265 for(i = widthDst; i > 0 ; i--)
1267 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
1268 wDstPnt++;
1270 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1271 yd++;
1272 delta += heightSrc;
1274 delta -= heightDst;
1275 ys++;
1278 else
1280 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
1282 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
1283 wDstPnt = dBuf;
1284 wPatPnt = pBuf;
1285 for(i = widthDst; i > 0 ; i--)
1287 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
1288 wDstPnt++;
1290 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1294 else if(usePat)
1296 MAYBE(TRACE("StretchBlt use: pat -- solid brush -- rop is %02x, color is %08x\n", rop, patColor));
1297 MAYBE(TRACE("Dest BMP is a '%s'\n", _DIBDRVBITMAP_GetFormatName(dstBmp)));
1298 MAYBE(TRACE("xDst = %d, yDst = %d, widthDst = %d, heightDst = %d\n", xDst, yDst, widthDst, heightDst));
1299 if(heightSrc > heightDst)
1301 ys = 0;
1302 yd = 0;
1303 delta = 0;
1304 while(yd < heightDst)
1306 wDstPnt = dBuf;
1307 for(i = widthDst; i > 0 ; i--)
1309 *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
1310 wDstPnt++;
1312 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1313 while(delta < heightSrc)
1315 ys++;
1316 delta += heightDst;
1318 delta -= heightSrc;
1319 yd++;
1322 else if(heightSrc < heightDst)
1324 ys = 0;
1325 yd = 0;
1326 delta = 0;
1327 while(ys < heightSrc)
1329 while(delta < heightDst)
1331 wDstPnt = dBuf;
1332 for(i = widthDst; i > 0 ; i--)
1334 *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
1335 wDstPnt++;
1337 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1338 yd++;
1339 delta += heightSrc;
1341 delta -= heightDst;
1342 ys++;
1345 else
1347 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
1349 wDstPnt = dBuf;
1350 for(i = widthDst; i > 0 ; i--)
1352 *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
1353 wDstPnt++;
1355 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1359 else
1360 ERR("What happened ?????? \n");
1361 break;
1362 } /* switch */
1363 res = TRUE;
1364 error:
1365 if(sBufOrig) HeapFree( GetProcessHeap(), 0, sBufOrig );
1366 if(sBufStr) HeapFree( GetProcessHeap(), 0, sBufStr );
1367 if(dBuf) HeapFree( GetProcessHeap(), 0, dBuf );
1368 if(pBuf) HeapFree( GetProcessHeap(), 0, pBuf );
1369 return res;