DIB Engine: fixes against wine tests
[wine/hacks.git] / dlls / winedib.drv / primitives_bitblt.c
blob27d573f74c0414ca7936f4bce8ef3a2928db6d5f
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 static inline COLORREF SwapColors(DWORD c)
30 return ((c & 0x0000ff) << 16) | (c & 0x00ff00) | ((c & 0xff0000) >> 16);
34 /* shrinks a line -- srcWidth >= dstWidth */
35 static void ShrinkLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth)
37 int srcPos, dstPos;
38 int delta;
40 srcPos = 0;
41 dstPos = 0;
42 delta = 0;
43 while(dstPos < dstWidth)
45 *dst++ = *src;
46 while(delta < srcWidth)
48 srcPos++;
49 src++;
50 delta += dstWidth;
52 delta -= srcWidth;
53 dstPos++;
57 /* expands a line -- srcWidth <= dstWidth */
58 static void ExpandLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth)
60 int srcPos;
61 int delta;
63 srcPos = 0;
64 delta = 0;
65 while(srcPos < srcWidth)
67 while(delta < dstWidth)
69 *dst++ = *src;
70 delta += srcWidth;
72 delta -= dstWidth;
73 src++;
74 srcPos++;
78 /* stretch a line */
79 static void StretchLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth)
81 if(srcWidth > dstWidth)
82 ShrinkLine(dst, dstWidth, src, srcWidth);
83 else if(srcWidth < dstWidth)
84 ExpandLine(dst, dstWidth, src, srcWidth);
85 else
86 memcpy(dst, src, 4 * srcWidth);
89 /* premultiply alpha channel on a line by a constant alpha
90 note : it seems that pixels are already premultiplied
91 by alpha channel content */
92 static void PemultiplyLine(DWORD *dst, int width, BYTE constAlpha)
94 int i = width;
95 BYTE *alphaPnt = (BYTE *)dst + 3;
97 /* small optimization for 0 and 255 values of constAlpha */
99 /* fully transparent -- just sets all pix to 0 */
100 if(constAlpha == 0)
102 while(i--)
103 *dst++ = 0;
104 return;
107 /* fully opaque, just do nothing */
108 if(constAlpha == 255)
109 return;
111 /* intermediate -- premultiply alpha values */
112 while(i--)
114 *alphaPnt = MulDiv(*alphaPnt, constAlpha, 255);
115 alphaPnt += 4;
117 return;
121 /* alpha blends a source line onto a destination line
122 preconditions :
123 1) source and dest widths must be the same
124 2) source line should be already premultiplied by constant alpha */
125 static void BlendLine(DWORD *dst, DWORD *src, int width)
127 int i = width;
128 BYTE *blueDst = (BYTE *)dst;
129 BYTE *greenDst = blueDst + 1;
130 BYTE *redDst = greenDst + 1;
131 BYTE *blueSrc = (BYTE *)src;
132 BYTE *greenSrc = blueSrc + 1;
133 BYTE *redSrc = greenSrc + 1;
134 BYTE *alphaSrc = redSrc + 1;
135 BYTE alpha;
137 /* still don't know if it must take in account an eventual dest
138 alpha channel..... */
139 while(i--)
141 alpha = 255 - *alphaSrc;
143 *blueDst = *blueSrc + MulDiv(*blueDst, alpha, 255);
144 *greenDst = *greenSrc + MulDiv(*greenDst, alpha, 255);
145 *redDst = *redSrc + MulDiv(*redDst, alpha, 255);
147 blueSrc += 4;
148 greenSrc += 4;
149 redSrc += 4;
150 alphaSrc += 4;
151 blueDst += 4;
152 greenDst += 4;
153 redDst += 4;
158 /* ------------------------------------------------------------*/
159 /* ALPHABLEND PRIMITIVES */
160 BOOL _DIBDRV_AlphaBlend_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
161 INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc,
162 INT xSrc, INT ySrc, int widthSrc, int heightSrc, BLENDFUNCTION blendFn)
164 /* flags indicating wether source should be stretched */
165 BOOL horStretch = (widthSrc != widthDst);
166 BOOL verStretch = (heightSrc != heightDst);
168 /* constant alpha value */
169 BYTE constAlpha = blendFn.SourceConstantAlpha;
171 /* source and dest bitmaps */
172 const DIBDRVBITMAP *srcBmp = &physDevSrc->physBitmap;
173 DIBDRVBITMAP *dstBmp = &physDevDst->physBitmap;
175 /* source and destination line buffers */
176 DWORD *sBuf = HeapAlloc(GetProcessHeap(), 0, abs(srcBmp->stride));
177 DWORD *dBuf = HeapAlloc(GetProcessHeap(), 0, abs(dstBmp->stride));
179 int ys = ySrc;
180 int yd = yDst;
181 int iLine;
182 int delta;
184 /* in order to optimize a bit, we divide the routine in 4 parts,
185 depending on stretching modes */
186 if(!horStretch && !verStretch)
188 /* simplest case, no stretching needed */
189 MAYBE(TRACE("No stretching\n"));
190 for(iLine = 0; iLine < heightSrc; iLine++, ys++, yd++)
192 /* load source and dest lines */
193 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
194 dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
196 /* premultiply source by constant and pixel alpha */
197 PemultiplyLine(sBuf, widthSrc, constAlpha);
199 /* blends source on dest */
200 BlendLine(dBuf, sBuf, widthSrc);
202 /* puts dest line back */
203 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
206 else if (horStretch && !verStretch)
208 /* just horizontal stretching needed */
209 DWORD *strBuf = HeapAlloc(GetProcessHeap(), 0, abs(dstBmp->stride));
210 MAYBE(TRACE("Horizontal stretching\n"));
212 for(iLine = 0; iLine < heightSrc; iLine++, ys++, yd++)
214 /* load source and dest lines */
215 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
216 dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
218 /* stretch source line to match dest one */
219 StretchLine(strBuf, widthDst, sBuf, widthSrc);
221 /* premultiply source by constant and pixel alpha */
222 PemultiplyLine(strBuf, widthDst, constAlpha);
224 /* blends source on dest */
225 BlendLine(dBuf, strBuf, widthDst);
227 /* puts dest line back */
228 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
230 HeapFree(GetProcessHeap(), 0, strBuf);
232 else if (!horStretch && verStretch)
234 /* just vertical stretching needed */
235 MAYBE(TRACE("Vertical stretching\n"));
237 if(heightSrc > heightDst)
239 iLine = 0;
240 delta = 0;
241 while(iLine < heightDst)
243 /* load source and dest lines */
244 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
245 dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
247 /* premultiply source by constant and pixel alpha */
248 PemultiplyLine(sBuf, widthSrc, constAlpha);
250 /* blends source on dest */
251 BlendLine(dBuf, sBuf, widthDst);
253 /* puts dest line back */
254 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
256 while(delta < heightSrc)
258 ys++;
259 delta += heightDst;
261 delta -= heightSrc;
262 yd++;
263 iLine++;
266 else if(heightSrc < heightDst)
268 iLine = 0;
269 delta = 0;
270 while(iLine < heightSrc)
272 /* load source line */
273 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
275 /* premultiply source by constant and pixel alpha */
276 PemultiplyLine(sBuf, widthSrc, constAlpha);
278 while(delta < heightDst)
280 /* load dest line */
281 dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
283 /* blends source on dest */
284 BlendLine(dBuf, sBuf, widthDst);
286 /* puts dest line back */
287 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
288 yd++;
289 delta += heightSrc;
291 delta -= heightDst;
292 ys++;
293 iLine++;
297 else
299 DWORD *strBuf = HeapAlloc(GetProcessHeap(), 0, abs(dstBmp->stride));
300 /* both stretching needed -- generic case */
301 MAYBE(TRACE("Horizontal and vertical stretching\n"));
303 if(heightSrc > heightDst)
305 iLine = 0;
306 delta = 0;
307 while(iLine < heightDst)
309 /* load source and dest lines */
310 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
311 dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
313 /* stretch source line to match dest one */
314 StretchLine(strBuf, widthDst, sBuf, widthSrc);
316 /* premultiply source by constant and pixel alpha */
317 PemultiplyLine(strBuf, widthDst, constAlpha);
319 /* blends source on dest */
320 BlendLine(dBuf, strBuf, widthDst);
322 /* puts dest line back */
323 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
325 while(delta < heightSrc)
327 ys++;
328 delta += heightDst;
330 delta -= heightSrc;
331 yd++;
332 iLine++;
335 else if(heightSrc < heightDst)
337 iLine = 0;
338 delta = 0;
339 while(iLine < heightSrc)
341 /* load source line */
342 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
344 /* stretch source line to match dest one */
345 StretchLine(strBuf, widthDst, sBuf, widthSrc);
347 /* premultiply source by constant and pixel alpha */
348 PemultiplyLine(strBuf, widthDst, constAlpha);
350 while(delta < heightDst)
352 /* load dest line */
353 dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
355 /* blends source on dest */
356 BlendLine(dBuf, strBuf, widthDst);
358 /* puts dest line back */
359 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
360 yd++;
361 delta += heightSrc;
363 delta -= heightDst;
364 ys++;
365 iLine++;
368 HeapFree(GetProcessHeap(), 0, strBuf);
371 HeapFree(GetProcessHeap(), 0, sBuf);
372 HeapFree(GetProcessHeap(), 0, dBuf);
373 return TRUE;
376 /* ------------------------------------------------------------*/
377 /* BLITTING PRIMITIVES */
378 BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
379 INT width, INT height, const DIBDRVPHYSDEV *physDevSrc,
380 INT xSrc, INT ySrc, DWORD rop)
382 int ys, yd;
383 int i;
384 DWORD *dwBuf;
385 DIBDRVBITMAP *dstBmp, *patBmp;
386 const DIBDRVBITMAP *srcBmp;
387 DWORD *wDstPnt, *wSrcPnt, *wPatPnt;
388 BOOL usePat, useSrc, useDst;
389 DWORD patColor;
390 BOOL res = FALSE;
392 /* 32 bit RGB source and destination buffer, if needed */
393 DWORD *sBuf = 0, *dBuf = 0, *pBuf = 0;
395 /* get elements usage */
396 usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000));
397 useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
398 useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
400 /* sanity check -- MSN messenger crashes without */
401 if(useSrc && !physDevSrc)
402 return FALSE;
404 /* gets source, dest and pattern bitmaps, if available */
405 if(usePat && physDevDst->isBrushBitmap)
406 patBmp = &physDevDst->brushBmpCache;
407 else
408 patBmp = NULL;
410 if(useSrc)
411 srcBmp = &physDevSrc->physBitmap;
412 else
413 srcBmp = NULL;
414 dstBmp = &physDevDst->physBitmap;
416 /* gets pattern color, in case it's needed
417 it's NOT the COLORREF value (colors are swapped
418 NOR the pixel value (it's applied to a 32 BPP BI_RGB */
419 if(usePat)
420 patColor = SwapColors(physDevDst->brushColorref);
421 else
422 patColor = 0;
424 /* allocate 32 bit RGB destination buffer */
425 if(!(dBuf = (DWORD *)HeapAlloc( GetProcessHeap(), 0, width * 4)))
426 goto error;
428 MAYBE(TRACE("dstBmp:%p(%s), xDst:%d, yDst:%d, width:%d, height:%d, srcBmp:%p(%s), xSrc:%d, ySrc:%d, rop:%8x\n",
429 dstBmp, _DIBDRVBITMAP_GetFormatName(dstBmp), xDst, yDst, width, height,
430 srcBmp, _DIBDRVBITMAP_GetFormatName(srcBmp), xSrc, ySrc, rop));
432 /* some simple ROPs optimizations */
433 switch(rop)
435 case BLACKNESS:
436 MAYBE(TRACE("BLACKNESS\n"));
437 memset(dBuf, 0x00, width * 4);
438 for(yd = yDst; yd < yDst+height; yd++)
439 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
440 break;
442 case WHITENESS:
443 MAYBE(TRACE("WHITENESS\n"));
444 for(dwBuf = dBuf, i = width; i; i--)
445 *dwBuf++ = 0x00ffffff;
446 for(yd = yDst; yd < yDst+height; yd++)
447 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
448 break;
450 case SRCCOPY:
451 MAYBE(TRACE("SRCCOPY\n"));
452 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
454 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
455 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
457 break;
459 /* fallback for generic ROP operation */
460 default:
461 rop >>= 16;
462 if(useSrc && useDst && usePat && physDevDst->isBrushBitmap)
464 MAYBE(TRACE("BitBlt use: src+dst+pat - pattern brush\n"));
465 if(!(sBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
466 goto error;
467 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
468 goto error;
469 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
471 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, sBuf);
472 dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf);
473 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
474 wDstPnt = dBuf;
475 wSrcPnt = sBuf;
476 wPatPnt = pBuf;
477 for(i = width; i > 0 ; i--)
479 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
480 wDstPnt++;
482 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
485 else if(useSrc && useDst)
487 if(usePat)
488 MAYBE(TRACE("BitBlt use: src+dst+pat - solid brush\n"));
489 else
490 MAYBE(TRACE("BitBlt use: src+dst\n"));
491 if(!(sBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
492 goto error;
493 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
495 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, sBuf);
496 dstBmp->funcs->GetLine(dstBmp, yd, xDst, width, dBuf);
497 wDstPnt = dBuf;
498 wSrcPnt = sBuf;
499 for(i = width; i > 0 ; i--)
501 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
502 wDstPnt++;
504 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
507 else if(useSrc && usePat && physDevDst->isBrushBitmap)
509 MAYBE(TRACE("BitBlt use: src+pat -- pattern brush\n"));
510 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
511 goto error;
512 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
514 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
515 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
516 wDstPnt = dBuf;
517 wSrcPnt = dBuf;
518 wPatPnt = pBuf;
519 for(i = width; i > 0 ; i--)
521 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
522 wDstPnt++;
524 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
527 else if(useSrc)
529 if(usePat)
530 MAYBE(TRACE("BitBlt use: src+pat - solid brush\n"));
531 else
532 MAYBE(TRACE("BitBlt use: src\n"));
533 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
535 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
536 wDstPnt = dBuf;
537 wSrcPnt = dBuf;
538 for(i = width; i > 0 ; i--)
540 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
541 wDstPnt++;
543 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
546 else if(useDst && usePat && physDevDst->isBrushBitmap)
548 MAYBE(TRACE("BitBlt use: dst+pat -- pattern brush\n"));
549 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
550 goto error;
551 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
553 dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf);
554 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
555 wDstPnt = dBuf;
556 wPatPnt = pBuf;
557 for(i = width; i > 0 ; i--)
559 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
560 wDstPnt++;
562 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
565 else if(useDst)
567 if(usePat)
568 MAYBE(TRACE("BitBlt use: dst+pat - solid brush\n"));
569 else
570 MAYBE(TRACE("BitBlt use: dst\n"));
571 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
573 dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf);
574 wDstPnt = dBuf;
575 for(i = width; i > 0 ; i--)
577 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
578 wDstPnt++;
580 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
583 else if(usePat && physDevDst->isBrushBitmap)
585 MAYBE(TRACE("BitBlt use: pat -- pattern brush\n"));
586 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
587 goto error;
588 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
590 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
591 wDstPnt = dBuf;
592 wPatPnt = pBuf;
593 for(i = width; i > 0 ; i--)
595 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
596 wDstPnt++;
598 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
601 else if(usePat)
603 MAYBE(TRACE("BitBlt use: pat -- solid brush -- rop is %02x, color is %08x\n", rop, patColor));
604 MAYBE(TRACE("Dest BMP is a '%s'\n", _DIBDRVBITMAP_GetFormatName(dstBmp)));
605 MAYBE(TRACE("xDst = %d, yDst = %d, width = %d, height = %d\n", xDst, yDst, width, height));
606 for(yd = yDst; yd < yDst+height; yd++)
608 wDstPnt = dBuf;
609 for(i = width; i > 0 ; i--)
611 *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
612 wDstPnt++;
614 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
617 else
618 ERR("What happened ?????? \n");
619 break;
620 } /* switch */
621 res = TRUE;
622 error:
623 if(sBuf) HeapFree( GetProcessHeap(), 0, sBuf );
624 if(dBuf) HeapFree( GetProcessHeap(), 0, dBuf );
625 if(pBuf) HeapFree( GetProcessHeap(), 0, pBuf );
626 return res;
629 /* ------------------------------------------------------------*/
630 /* STRETCHING PRIMITIVES */
631 BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
632 INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc,
633 INT xSrc, INT ySrc, int widthSrc, int heightSrc, DWORD rop)
635 int ys, yd;
636 int i, delta;
637 DWORD *dwBuf;
638 DIBDRVBITMAP *dstBmp, *patBmp;
639 const DIBDRVBITMAP *srcBmp;
640 DWORD *wDstPnt, *wSrcPnt, *wPatPnt;
641 BOOL usePat, useSrc, useDst;
642 DWORD patColor;
643 BOOL res = FALSE;
645 /* 32 bit RGB source and destination buffer, if needed */
646 DWORD *sBufOrig = 0, *sBufStr = 0, *dBuf = 0, *pBuf = 0;
648 /* get elements usage */
649 usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000));
650 useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
651 useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
653 /* sanity check -- MSN messenger crashes without */
654 if(useSrc && !physDevSrc)
655 return FALSE;
657 /* gets source, dest and pattern bitmaps, if available */
658 if(usePat && physDevDst->isBrushBitmap)
659 patBmp = &physDevDst->brushBmpCache;
660 else
661 patBmp = NULL;
663 if(useSrc)
664 srcBmp = &physDevSrc->physBitmap;
665 else
666 srcBmp = NULL;
667 dstBmp = &physDevDst->physBitmap;
669 /* gets pattern color, in case it's needed
670 it's NOT the COLORREF value (colors are swapped
671 NOR the pixel value (it's applied to a 32 BPP BI_RGB */
672 if(usePat)
673 patColor = SwapColors(physDevDst->brushColorref);
674 else
675 patColor = 0;
677 /* allocate 32 bit RGB destination buffer */
678 if(!(dBuf = (DWORD *)HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
679 goto error;
681 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",
682 dstBmp, _DIBDRVBITMAP_GetFormatName(dstBmp), xDst, yDst, widthDst, heightDst,
683 srcBmp, _DIBDRVBITMAP_GetFormatName(srcBmp), xSrc, ySrc, widthSrc, heightSrc, rop));
685 /* some simple ROPs optimizations */
686 switch(rop)
688 case BLACKNESS:
689 MAYBE(TRACE("BLACKNESS\n"));
690 memset(dBuf, 0x00, widthDst * 4);
691 for(yd = yDst; yd < yDst+heightDst; yd++)
692 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
693 break;
695 case WHITENESS:
696 MAYBE(TRACE("WHITENESS\n"));
697 for(dwBuf = dBuf, i = widthDst; i; i--)
698 *dwBuf++ = 0x00ffffff;
699 for(yd = yDst; yd < yDst+heightDst; yd++)
700 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
701 break;
703 case SRCCOPY:
704 MAYBE(TRACE("SRCCOPY\n"));
705 sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4);
706 if(heightSrc > heightDst)
708 ys = 0;
709 yd = 0;
710 delta = 0;
711 while(yd < heightDst)
713 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
714 StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
715 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
716 while(delta < heightSrc)
718 ys++;
719 delta += heightDst;
721 delta -= heightSrc;
722 yd++;
725 else if(heightSrc < heightDst)
727 ys = 0;
728 yd = 0;
729 delta = 0;
730 while(ys < heightSrc)
732 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
733 StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
734 while(delta < heightDst)
736 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
737 yd++;
738 delta += heightSrc;
740 delta -= heightDst;
741 ys++;
744 else
746 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
748 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
749 StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
750 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
753 break;
755 /* fallback for generic ROP operation */
756 default:
757 rop >>= 16;
758 if(useSrc && useDst && usePat && physDevDst->isBrushBitmap)
760 MAYBE(TRACE("StretchBlt use: src+dst+pat - pattern brush\n"));
761 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
762 goto error;
763 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
764 goto error;
765 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
766 goto error;
767 if(heightSrc > heightDst)
769 ys = 0;
770 yd = 0;
771 delta = 0;
772 while(yd < heightDst)
774 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
775 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
776 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
777 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
778 wDstPnt = dBuf;
779 wSrcPnt = sBufStr;
780 wPatPnt = pBuf;
781 for(i = widthDst; i > 0 ; i--)
783 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
784 wDstPnt++;
786 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
787 while(delta < heightSrc)
789 ys++;
790 delta += heightDst;
792 delta -= heightSrc;
793 yd++;
796 else if(heightSrc < heightDst)
798 ys = 0;
799 yd = 0;
800 delta = 0;
801 while(ys < heightSrc)
803 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
804 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
805 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
806 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
807 while(delta < heightDst)
809 wDstPnt = dBuf;
810 wSrcPnt = sBufStr;
811 wPatPnt = pBuf;
812 for(i = widthDst; i > 0 ; i--)
814 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
815 wDstPnt++;
817 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
818 yd++;
819 delta += heightSrc;
821 delta -= heightDst;
822 ys++;
825 else
827 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
829 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
830 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
831 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
832 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
833 wDstPnt = dBuf;
834 wSrcPnt = sBufStr;
835 wPatPnt = pBuf;
836 for(i = widthDst; i > 0 ; i--)
838 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
839 wDstPnt++;
841 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
845 else if(useSrc && useDst)
847 if(usePat)
848 MAYBE(TRACE("StretchBlt use: src+dst+pat - solid brush\n"));
849 else
850 MAYBE(TRACE("StretchBlt use: src+dst\n"));
851 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
852 goto error;
853 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
854 goto error;
855 if(heightSrc > heightDst)
857 ys = 0;
858 yd = 0;
859 delta = 0;
860 while(yd < heightDst)
862 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
863 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
864 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
865 wDstPnt = dBuf;
866 wSrcPnt = sBufStr;
867 for(i = widthDst; i > 0 ; i--)
869 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
870 wDstPnt++;
872 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
873 while(delta < heightSrc)
875 ys++;
876 delta += heightDst;
878 delta -= heightSrc;
879 yd++;
882 else if(heightSrc < heightDst)
884 ys = 0;
885 yd = 0;
886 delta = 0;
887 while(ys < heightSrc)
889 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
890 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
891 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
892 while(delta < heightDst)
894 wDstPnt = dBuf;
895 wSrcPnt = sBufStr;
896 for(i = widthDst; i > 0 ; i--)
898 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
899 wDstPnt++;
901 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
902 yd++;
903 delta += heightSrc;
905 delta -= heightDst;
906 ys++;
909 else
911 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
913 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
914 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
915 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
916 wDstPnt = dBuf;
917 wSrcPnt = sBufStr;
918 for(i = widthDst; i > 0 ; i--)
920 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
921 wDstPnt++;
923 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
927 else if(useSrc && usePat && physDevDst->isBrushBitmap)
929 MAYBE(TRACE("StretchBlt use: src+pat -- pattern brush\n"));
930 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
931 goto error;
932 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
933 goto error;
934 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
935 goto error;
936 if(heightSrc > heightDst)
938 ys = 0;
939 yd = 0;
940 delta = 0;
941 while(yd < heightDst)
943 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
944 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
945 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
946 wDstPnt = dBuf;
947 wSrcPnt = sBufStr;
948 wPatPnt = pBuf;
949 for(i = widthDst; i > 0 ; i--)
951 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
952 wDstPnt++;
954 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
955 while(delta < heightSrc)
957 ys++;
958 delta += heightDst;
960 delta -= heightSrc;
961 yd++;
964 else if(heightSrc < heightDst)
966 ys = 0;
967 yd = 0;
968 delta = 0;
969 while(ys < heightSrc)
971 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
972 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
973 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
974 while(delta < heightDst)
976 wDstPnt = dBuf;
977 wSrcPnt = sBufStr;
978 wPatPnt = pBuf;
979 for(i = widthDst; i > 0 ; i--)
981 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
982 wDstPnt++;
984 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
985 yd++;
986 delta += heightSrc;
988 delta -= heightDst;
989 ys++;
992 else
994 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
996 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
997 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
998 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
999 wDstPnt = dBuf;
1000 wSrcPnt = sBufStr;
1001 wPatPnt = pBuf;
1002 for(i = widthDst; i > 0 ; i--)
1004 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
1005 wDstPnt++;
1007 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1011 else if(useSrc)
1013 if(usePat)
1014 MAYBE(TRACE("StretchBlt use: src+pat - solid brush\n"));
1015 else
1016 MAYBE(TRACE("StretchBlt use: src\n"));
1017 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
1018 goto error;
1019 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
1020 goto error;
1021 if(heightSrc > heightDst)
1023 ys = 0;
1024 yd = 0;
1025 delta = 0;
1026 while(yd < heightDst)
1028 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
1029 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
1030 wDstPnt = dBuf;
1031 wSrcPnt = sBufStr;
1032 for(i = widthDst; i > 0 ; i--)
1034 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
1035 wDstPnt++;
1037 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1038 while(delta < heightSrc)
1040 ys++;
1041 delta += heightDst;
1043 delta -= heightSrc;
1044 yd++;
1047 else if(heightSrc < heightDst)
1049 ys = 0;
1050 yd = 0;
1051 delta = 0;
1052 while(ys < heightSrc)
1054 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
1055 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
1056 while(delta < heightDst)
1058 wDstPnt = dBuf;
1059 wSrcPnt = sBufStr;
1060 for(i = widthDst; i > 0 ; i--)
1062 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
1063 wDstPnt++;
1065 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1066 yd++;
1067 delta += heightSrc;
1069 delta -= heightDst;
1070 ys++;
1073 else
1075 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
1077 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
1078 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
1079 wDstPnt = dBuf;
1080 wSrcPnt = sBufStr;
1081 for(i = widthDst; i > 0 ; i--)
1083 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
1084 wDstPnt++;
1086 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1090 else if(useDst && usePat && physDevDst->isBrushBitmap)
1092 MAYBE(TRACE("StretchBlt use: dst+pat -- pattern brush\n"));
1093 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
1094 goto error;
1095 if(heightSrc > heightDst)
1097 ys = 0;
1098 yd = 0;
1099 delta = 0;
1100 while(yd < heightDst)
1102 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1103 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
1104 wDstPnt = dBuf;
1105 wPatPnt = pBuf;
1106 for(i = widthDst; i > 0 ; i--)
1108 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
1109 wDstPnt++;
1111 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1112 while(delta < heightSrc)
1114 ys++;
1115 delta += heightDst;
1117 delta -= heightSrc;
1118 yd++;
1121 else if(heightSrc < heightDst)
1123 ys = 0;
1124 yd = 0;
1125 delta = 0;
1126 while(ys < heightSrc)
1128 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1129 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
1130 while(delta < heightDst)
1132 wDstPnt = dBuf;
1133 wPatPnt = pBuf;
1134 for(i = widthDst; i > 0 ; i--)
1136 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
1137 wDstPnt++;
1139 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1140 yd++;
1141 delta += heightSrc;
1143 delta -= heightDst;
1144 ys++;
1147 else
1149 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
1151 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
1152 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
1153 wDstPnt = dBuf;
1154 wPatPnt = pBuf;
1155 for(i = widthDst; i > 0 ; i--)
1157 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
1158 wDstPnt++;
1160 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1164 else if(useDst)
1166 if(usePat)
1167 MAYBE(TRACE("StretchBlt use: dst+pat - solid brush\n"));
1168 else
1169 MAYBE(TRACE("StretchBlt use: dst\n"));
1170 if(heightSrc > heightDst)
1172 ys = 0;
1173 yd = 0;
1174 delta = 0;
1175 while(yd < heightDst)
1177 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1178 wDstPnt = dBuf;
1179 for(i = widthDst; i > 0 ; i--)
1181 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
1182 wDstPnt++;
1184 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1185 while(delta < heightSrc)
1187 ys++;
1188 delta += heightDst;
1190 delta -= heightSrc;
1191 yd++;
1194 else if(heightSrc < heightDst)
1196 ys = 0;
1197 yd = 0;
1198 delta = 0;
1199 while(ys < heightSrc)
1201 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1202 while(delta < heightDst)
1204 wDstPnt = dBuf;
1205 for(i = widthDst; i > 0 ; i--)
1207 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
1208 wDstPnt++;
1210 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1211 yd++;
1212 delta += heightSrc;
1214 delta -= heightDst;
1215 ys++;
1218 else
1220 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
1222 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
1223 wDstPnt = dBuf;
1224 for(i = widthDst; i > 0 ; i--)
1226 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
1227 wDstPnt++;
1229 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1233 else if(usePat && physDevDst->isBrushBitmap)
1235 MAYBE(TRACE("StretchBlt use: pat -- pattern brush\n"));
1236 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
1237 goto error;
1238 if(heightSrc > heightDst)
1240 ys = 0;
1241 yd = 0;
1242 delta = 0;
1243 while(yd < heightDst)
1245 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
1246 wDstPnt = dBuf;
1247 wPatPnt = pBuf;
1248 for(i = widthDst; i > 0 ; i--)
1250 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
1251 wDstPnt++;
1253 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1254 while(delta < heightSrc)
1256 ys++;
1257 delta += heightDst;
1259 delta -= heightSrc;
1260 yd++;
1263 else if(heightSrc < heightDst)
1265 ys = 0;
1266 yd = 0;
1267 delta = 0;
1268 while(ys < heightSrc)
1270 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
1271 while(delta < heightDst)
1273 wDstPnt = dBuf;
1274 wPatPnt = pBuf;
1275 for(i = widthDst; i > 0 ; i--)
1277 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
1278 wDstPnt++;
1280 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1281 yd++;
1282 delta += heightSrc;
1284 delta -= heightDst;
1285 ys++;
1288 else
1290 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
1292 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
1293 wDstPnt = dBuf;
1294 wPatPnt = pBuf;
1295 for(i = widthDst; i > 0 ; i--)
1297 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
1298 wDstPnt++;
1300 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1304 else if(usePat)
1306 MAYBE(TRACE("StretchBlt use: pat -- solid brush -- rop is %02x, color is %08x\n", rop, patColor));
1307 MAYBE(TRACE("Dest BMP is a '%s'\n", _DIBDRVBITMAP_GetFormatName(dstBmp)));
1308 MAYBE(TRACE("xDst = %d, yDst = %d, widthDst = %d, heightDst = %d\n", xDst, yDst, widthDst, heightDst));
1309 if(heightSrc > heightDst)
1311 ys = 0;
1312 yd = 0;
1313 delta = 0;
1314 while(yd < heightDst)
1316 wDstPnt = dBuf;
1317 for(i = widthDst; i > 0 ; i--)
1319 *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
1320 wDstPnt++;
1322 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1323 while(delta < heightSrc)
1325 ys++;
1326 delta += heightDst;
1328 delta -= heightSrc;
1329 yd++;
1332 else if(heightSrc < heightDst)
1334 ys = 0;
1335 yd = 0;
1336 delta = 0;
1337 while(ys < heightSrc)
1339 while(delta < heightDst)
1341 wDstPnt = dBuf;
1342 for(i = widthDst; i > 0 ; i--)
1344 *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
1345 wDstPnt++;
1347 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1348 yd++;
1349 delta += heightSrc;
1351 delta -= heightDst;
1352 ys++;
1355 else
1357 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
1359 wDstPnt = dBuf;
1360 for(i = widthDst; i > 0 ; i--)
1362 *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
1363 wDstPnt++;
1365 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1369 else
1370 ERR("What happened ?????? \n");
1371 break;
1372 } /* switch */
1373 res = TRUE;
1374 error:
1375 if(sBufOrig) HeapFree( GetProcessHeap(), 0, sBufOrig );
1376 if(sBufStr) HeapFree( GetProcessHeap(), 0, sBufStr );
1377 if(dBuf) HeapFree( GetProcessHeap(), 0, dBuf );
1378 if(pBuf) HeapFree( GetProcessHeap(), 0, pBuf );
1379 return res;