DIB Engine: implement AlphaBlend
[wine/hacks.git] / dlls / winedib.drv / primitives_bitblt.c
blob7540dad819009e9a7b7bfc1483fe7738fb6cd016
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, sBuf, 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 /* gets source, dest and pattern bitmaps, if available */
395 if(usePat && physDevDst->isBrushBitmap)
396 patBmp = &physDevDst->brushBmpCache;
397 else
398 patBmp = NULL;
400 if(useSrc)
401 srcBmp = &physDevSrc->physBitmap;
402 else
403 srcBmp = NULL;
404 dstBmp = &physDevDst->physBitmap;
406 /* gets pattern color, in case it's needed */
407 if(usePat)
408 patColor = physDevDst->brushColor;
409 else
410 patColor = 0;
412 /* allocate 32 bit RGB destination buffer */
413 if(!(dBuf = (DWORD *)HeapAlloc( GetProcessHeap(), 0, width * 4)))
414 goto error;
416 MAYBE(TRACE("dstBmp:%p(%s), xDst:%d, yDst:%d, width:%d, height:%d, srcBmp:%p(%s), xSrc:%d, ySrc:%d, rop:%8x\n",
417 dstBmp, _DIBDRVBITMAP_GetFormatName(dstBmp), xDst, yDst, width, height,
418 srcBmp, _DIBDRVBITMAP_GetFormatName(srcBmp), xSrc, ySrc, rop));
420 /* some simple ROPs optimizations */
421 switch(rop)
423 case BLACKNESS:
424 MAYBE(TRACE("BLACKNESS\n"));
425 memset(dBuf, 0x00, width * 4);
426 for(yd = yDst; yd < yDst+height; yd++)
427 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
428 break;
430 case WHITENESS:
431 MAYBE(TRACE("WHITENESS\n"));
432 for(dwBuf = dBuf, i = width; i; i--)
433 *dwBuf++ = 0x00ffffff;
434 for(yd = yDst; yd < yDst+height; yd++)
435 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
436 break;
438 case SRCCOPY:
439 MAYBE(TRACE("SRCCOPY\n"));
440 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
442 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
443 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
445 break;
447 /* fallback for generic ROP operation */
448 default:
449 rop >>= 16;
450 if(useSrc && useDst && usePat && physDevDst->isBrushBitmap)
452 MAYBE(TRACE("BitBlt use: src+dst+pat - pattern brush\n"));
453 if(!(sBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
454 goto error;
455 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
456 goto error;
457 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
459 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, sBuf);
460 dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf);
461 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
462 wDstPnt = dBuf;
463 wSrcPnt = sBuf;
464 wPatPnt = pBuf;
465 for(i = width; i > 0 ; i--)
467 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
468 wDstPnt++;
470 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
473 else if(useSrc && useDst)
475 if(usePat)
476 MAYBE(TRACE("BitBlt use: src+dst+pat - solid brush\n"));
477 else
478 MAYBE(TRACE("BitBlt use: src+dst\n"));
479 if(!(sBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
480 goto error;
481 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
483 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, sBuf);
484 dstBmp->funcs->GetLine(dstBmp, yd, xDst, width, dBuf);
485 wDstPnt = dBuf;
486 wSrcPnt = sBuf;
487 for(i = width; i > 0 ; i--)
489 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
490 wDstPnt++;
492 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
495 else if(useSrc && usePat && physDevDst->isBrushBitmap)
497 MAYBE(TRACE("BitBlt use: src+pat -- pattern brush\n"));
498 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
499 goto error;
500 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
502 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
503 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
504 wDstPnt = sBuf;
505 wSrcPnt = sBuf;
506 wPatPnt = pBuf;
507 for(i = width; i > 0 ; i--)
509 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
510 wDstPnt++;
512 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
515 else if(useSrc)
517 if(usePat)
518 MAYBE(TRACE("BitBlt use: src+pat - solid brush\n"));
519 else
520 MAYBE(TRACE("BitBlt use: src\n"));
521 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
523 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
524 wDstPnt = sBuf;
525 wSrcPnt = sBuf;
526 for(i = width; i > 0 ; i--)
528 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
529 wDstPnt++;
531 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
534 else if(useDst && usePat && physDevDst->isBrushBitmap)
536 MAYBE(TRACE("BitBlt use: dst+pat -- pattern brush\n"));
537 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
538 goto error;
539 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
541 dstBmp->funcs->GetLine(srcBmp, ys, xDst, width, dBuf);
542 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
543 wDstPnt = sBuf;
544 wPatPnt = pBuf;
545 for(i = width; i > 0 ; i--)
547 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
548 wDstPnt++;
550 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
553 else if(useDst)
555 if(usePat)
556 MAYBE(TRACE("BitBlt use: dst+pat - solid brush\n"));
557 else
558 MAYBE(TRACE("BitBlt use: dst\n"));
559 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
561 dstBmp->funcs->GetLine(srcBmp, ys, xDst, width, dBuf);
562 wDstPnt = sBuf;
563 for(i = width; i > 0 ; i--)
565 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
566 wDstPnt++;
568 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
571 else if(usePat && physDevDst->isBrushBitmap)
573 MAYBE(TRACE("BitBlt use: pat -- pattern brush\n"));
574 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
575 goto error;
576 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
578 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
579 wDstPnt = dBuf;
580 wPatPnt = pBuf;
581 for(i = width; i > 0 ; i--)
583 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
584 wDstPnt++;
586 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
589 else if(usePat)
591 MAYBE(TRACE("BitBlt use: pat -- solid brush -- rop is %02x, color is %08x\n", rop, patColor));
592 MAYBE(TRACE("Dest BMP is a '%s'\n", _DIBDRVBITMAP_GetFormatName(dstBmp)));
593 MAYBE(TRACE("xDst = %d, yDst = %d, width = %d, height = %d\n", xDst, yDst, width, height));
594 for(yd = yDst; yd < yDst+height; yd++)
596 wDstPnt = dBuf;
597 for(i = width; i > 0 ; i--)
599 *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
600 wDstPnt++;
602 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
605 else
606 ERR("What happened ?????? \n");
607 break;
608 } /* switch */
609 res = TRUE;
610 error:
611 if(sBuf) HeapFree( GetProcessHeap(), 0, sBuf );
612 if(dBuf) HeapFree( GetProcessHeap(), 0, dBuf );
613 if(pBuf) HeapFree( GetProcessHeap(), 0, pBuf );
614 return res;
617 /* ------------------------------------------------------------*/
618 /* STRETCHING PRIMITIVES */
619 BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
620 INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc,
621 INT xSrc, INT ySrc, int widthSrc, int heightSrc, DWORD rop)
623 int ys, yd;
624 int i, delta;
625 DWORD *dwBuf;
626 DIBDRVBITMAP *dstBmp, *patBmp;
627 const DIBDRVBITMAP *srcBmp;
628 DWORD *wDstPnt, *wSrcPnt, *wPatPnt;
629 BOOL usePat, useSrc, useDst;
630 DWORD patColor;
631 BOOL res = FALSE;
633 /* 32 bit RGB source and destination buffer, if needed */
634 DWORD *sBufOrig = 0, *sBufStr = 0, *dBuf = 0, *pBuf = 0;
636 /* get elements usage */
637 usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000));
638 useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
639 useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
641 /* gets source, dest and pattern bitmaps, if available */
642 if(usePat && physDevDst->isBrushBitmap)
643 patBmp = &physDevDst->brushBmpCache;
644 else
645 patBmp = NULL;
647 if(useSrc)
648 srcBmp = &physDevSrc->physBitmap;
649 else
650 srcBmp = NULL;
651 dstBmp = &physDevDst->physBitmap;
653 /* gets pattern color, in case it's needed */
654 if(usePat)
655 patColor = physDevDst->brushColor;
656 else
657 patColor = 0;
659 /* allocate 32 bit RGB destination buffer */
660 if(!(dBuf = (DWORD *)HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
661 goto error;
663 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",
664 dstBmp, _DIBDRVBITMAP_GetFormatName(dstBmp), xDst, yDst, widthDst, heightDst,
665 srcBmp, _DIBDRVBITMAP_GetFormatName(srcBmp), xSrc, ySrc, widthSrc, heightSrc, rop));
667 /* some simple ROPs optimizations */
668 switch(rop)
670 case BLACKNESS:
671 MAYBE(TRACE("BLACKNESS\n"));
672 memset(dBuf, 0x00, widthDst * 4);
673 for(yd = yDst; yd < yDst+heightDst; yd++)
674 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
675 break;
677 case WHITENESS:
678 MAYBE(TRACE("WHITENESS\n"));
679 for(dwBuf = dBuf, i = widthDst; i; i--)
680 *dwBuf++ = 0x00ffffff;
681 for(yd = yDst; yd < yDst+heightDst; yd++)
682 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
683 break;
685 case SRCCOPY:
686 MAYBE(TRACE("SRCCOPY\n"));
687 sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4);
688 if(heightSrc > heightDst)
690 ys = 0;
691 yd = 0;
692 delta = 0;
693 while(yd < heightDst)
695 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
696 StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
697 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
698 while(delta < heightSrc)
700 ys++;
701 delta += heightDst;
703 delta -= heightSrc;
704 yd++;
707 else if(heightSrc < heightDst)
709 ys = 0;
710 yd = 0;
711 delta = 0;
712 while(ys < heightSrc)
714 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
715 StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
716 while(delta < heightDst)
718 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
719 yd++;
720 delta += heightSrc;
722 delta -= heightDst;
723 ys++;
726 else
728 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
730 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
731 StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
732 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
735 break;
737 /* fallback for generic ROP operation */
738 default:
739 rop >>= 16;
740 if(useSrc && useDst && usePat && physDevDst->isBrushBitmap)
742 MAYBE(TRACE("StretchBlt use: src+dst+pat - pattern brush\n"));
743 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
744 goto error;
745 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
746 goto error;
747 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
748 goto error;
749 if(heightSrc > heightDst)
751 ys = 0;
752 yd = 0;
753 delta = 0;
754 while(yd < heightDst)
756 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
757 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
758 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
759 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
760 wDstPnt = dBuf;
761 wSrcPnt = sBufStr;
762 wPatPnt = pBuf;
763 for(i = widthDst; i > 0 ; i--)
765 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
766 wDstPnt++;
768 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
769 while(delta < heightSrc)
771 ys++;
772 delta += heightDst;
774 delta -= heightSrc;
775 yd++;
778 else if(heightSrc < heightDst)
780 ys = 0;
781 yd = 0;
782 delta = 0;
783 while(ys < heightSrc)
785 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
786 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
787 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
788 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
789 while(delta < heightDst)
791 wDstPnt = dBuf;
792 wSrcPnt = sBufStr;
793 wPatPnt = pBuf;
794 for(i = widthDst; i > 0 ; i--)
796 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
797 wDstPnt++;
799 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
800 yd++;
801 delta += heightSrc;
803 delta -= heightDst;
804 ys++;
807 else
809 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
811 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
812 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
813 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
814 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
815 wDstPnt = dBuf;
816 wSrcPnt = sBufStr;
817 wPatPnt = pBuf;
818 for(i = widthDst; i > 0 ; i--)
820 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
821 wDstPnt++;
823 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
827 else if(useSrc && useDst)
829 if(usePat)
830 MAYBE(TRACE("StretchBlt use: src+dst+pat - solid brush\n"));
831 else
832 MAYBE(TRACE("StretchBlt use: src+dst\n"));
833 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
834 goto error;
835 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
836 goto error;
837 if(heightSrc > heightDst)
839 ys = 0;
840 yd = 0;
841 delta = 0;
842 while(yd < heightDst)
844 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
845 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
846 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
847 wDstPnt = dBuf;
848 wSrcPnt = sBufStr;
849 for(i = widthDst; i > 0 ; i--)
851 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
852 wDstPnt++;
854 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
855 while(delta < heightSrc)
857 ys++;
858 delta += heightDst;
860 delta -= heightSrc;
861 yd++;
864 else if(heightSrc < heightDst)
866 ys = 0;
867 yd = 0;
868 delta = 0;
869 while(ys < heightSrc)
871 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
872 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
873 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
874 while(delta < heightDst)
876 wDstPnt = dBuf;
877 wSrcPnt = sBufStr;
878 for(i = widthDst; i > 0 ; i--)
880 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
881 wDstPnt++;
883 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
884 yd++;
885 delta += heightSrc;
887 delta -= heightDst;
888 ys++;
891 else
893 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
895 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
896 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
897 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
898 wDstPnt = dBuf;
899 wSrcPnt = sBufStr;
900 for(i = widthDst; i > 0 ; i--)
902 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
903 wDstPnt++;
905 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
909 else if(useSrc && usePat && physDevDst->isBrushBitmap)
911 MAYBE(TRACE("StretchBlt use: src+pat -- pattern brush\n"));
912 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
913 goto error;
914 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
915 goto error;
916 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
917 goto error;
918 if(heightSrc > heightDst)
920 ys = 0;
921 yd = 0;
922 delta = 0;
923 while(yd < heightDst)
925 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
926 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
927 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
928 wDstPnt = dBuf;
929 wSrcPnt = sBufStr;
930 wPatPnt = pBuf;
931 for(i = widthDst; i > 0 ; i--)
933 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
934 wDstPnt++;
936 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
937 while(delta < heightSrc)
939 ys++;
940 delta += heightDst;
942 delta -= heightSrc;
943 yd++;
946 else if(heightSrc < heightDst)
948 ys = 0;
949 yd = 0;
950 delta = 0;
951 while(ys < heightSrc)
953 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
954 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
955 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
956 while(delta < heightDst)
958 wDstPnt = dBuf;
959 wSrcPnt = sBufStr;
960 wPatPnt = pBuf;
961 for(i = widthDst; i > 0 ; i--)
963 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
964 wDstPnt++;
966 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
967 yd++;
968 delta += heightSrc;
970 delta -= heightDst;
971 ys++;
974 else
976 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
978 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
979 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
980 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
981 wDstPnt = dBuf;
982 wSrcPnt = sBufStr;
983 wPatPnt = pBuf;
984 for(i = widthDst; i > 0 ; i--)
986 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
987 wDstPnt++;
989 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
993 else if(useSrc)
995 if(usePat)
996 MAYBE(TRACE("StretchBlt use: src+pat - solid brush\n"));
997 else
998 MAYBE(TRACE("StretchBlt use: src\n"));
999 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
1000 goto error;
1001 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
1002 goto error;
1003 if(heightSrc > heightDst)
1005 ys = 0;
1006 yd = 0;
1007 delta = 0;
1008 while(yd < heightDst)
1010 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
1011 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
1012 wDstPnt = dBuf;
1013 wSrcPnt = sBufStr;
1014 for(i = widthDst; i > 0 ; i--)
1016 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
1017 wDstPnt++;
1019 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1020 while(delta < heightSrc)
1022 ys++;
1023 delta += heightDst;
1025 delta -= heightSrc;
1026 yd++;
1029 else if(heightSrc < heightDst)
1031 ys = 0;
1032 yd = 0;
1033 delta = 0;
1034 while(ys < heightSrc)
1036 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
1037 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
1038 while(delta < heightDst)
1040 wDstPnt = dBuf;
1041 wSrcPnt = sBufStr;
1042 for(i = widthDst; i > 0 ; i--)
1044 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
1045 wDstPnt++;
1047 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1048 yd++;
1049 delta += heightSrc;
1051 delta -= heightDst;
1052 ys++;
1055 else
1057 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
1059 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
1060 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
1061 wDstPnt = dBuf;
1062 wSrcPnt = sBufStr;
1063 for(i = widthDst; i > 0 ; i--)
1065 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
1066 wDstPnt++;
1068 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1072 else if(useDst && usePat && physDevDst->isBrushBitmap)
1074 MAYBE(TRACE("StretchBlt use: dst+pat -- pattern brush\n"));
1075 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
1076 goto error;
1077 if(heightSrc > heightDst)
1079 ys = 0;
1080 yd = 0;
1081 delta = 0;
1082 while(yd < heightDst)
1084 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1085 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
1086 wDstPnt = dBuf;
1087 wPatPnt = pBuf;
1088 for(i = widthDst; i > 0 ; i--)
1090 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
1091 wDstPnt++;
1093 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1094 while(delta < heightSrc)
1096 ys++;
1097 delta += heightDst;
1099 delta -= heightSrc;
1100 yd++;
1103 else if(heightSrc < heightDst)
1105 ys = 0;
1106 yd = 0;
1107 delta = 0;
1108 while(ys < heightSrc)
1110 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1111 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
1112 while(delta < heightDst)
1114 wDstPnt = dBuf;
1115 wPatPnt = pBuf;
1116 for(i = widthDst; i > 0 ; i--)
1118 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
1119 wDstPnt++;
1121 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1122 yd++;
1123 delta += heightSrc;
1125 delta -= heightDst;
1126 ys++;
1129 else
1131 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
1133 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
1134 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
1135 wDstPnt = dBuf;
1136 wPatPnt = pBuf;
1137 for(i = widthDst; i > 0 ; i--)
1139 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
1140 wDstPnt++;
1142 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1146 else if(useDst)
1148 if(usePat)
1149 MAYBE(TRACE("StretchBlt use: dst+pat - solid brush\n"));
1150 else
1151 MAYBE(TRACE("StretchBlt use: dst\n"));
1152 if(heightSrc > heightDst)
1154 ys = 0;
1155 yd = 0;
1156 delta = 0;
1157 while(yd < heightDst)
1159 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1160 wDstPnt = dBuf;
1161 for(i = widthDst; i > 0 ; i--)
1163 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
1164 wDstPnt++;
1166 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1167 while(delta < heightSrc)
1169 ys++;
1170 delta += heightDst;
1172 delta -= heightSrc;
1173 yd++;
1176 else if(heightSrc < heightDst)
1178 ys = 0;
1179 yd = 0;
1180 delta = 0;
1181 while(ys < heightSrc)
1183 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1184 while(delta < heightDst)
1186 wDstPnt = dBuf;
1187 for(i = widthDst; i > 0 ; i--)
1189 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
1190 wDstPnt++;
1192 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1193 yd++;
1194 delta += heightSrc;
1196 delta -= heightDst;
1197 ys++;
1200 else
1202 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
1204 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
1205 wDstPnt = dBuf;
1206 for(i = widthDst; i > 0 ; i--)
1208 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
1209 wDstPnt++;
1211 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1215 else if(usePat && physDevDst->isBrushBitmap)
1217 MAYBE(TRACE("StretchBlt use: pat -- pattern brush\n"));
1218 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
1219 goto error;
1220 if(heightSrc > heightDst)
1222 ys = 0;
1223 yd = 0;
1224 delta = 0;
1225 while(yd < heightDst)
1227 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
1228 wDstPnt = dBuf;
1229 wPatPnt = pBuf;
1230 for(i = widthDst; i > 0 ; i--)
1232 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
1233 wDstPnt++;
1235 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1236 while(delta < heightSrc)
1238 ys++;
1239 delta += heightDst;
1241 delta -= heightSrc;
1242 yd++;
1245 else if(heightSrc < heightDst)
1247 ys = 0;
1248 yd = 0;
1249 delta = 0;
1250 while(ys < heightSrc)
1252 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
1253 while(delta < heightDst)
1255 wDstPnt = dBuf;
1256 wPatPnt = pBuf;
1257 for(i = widthDst; i > 0 ; i--)
1259 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
1260 wDstPnt++;
1262 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1263 yd++;
1264 delta += heightSrc;
1266 delta -= heightDst;
1267 ys++;
1270 else
1272 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
1274 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
1275 wDstPnt = dBuf;
1276 wPatPnt = pBuf;
1277 for(i = widthDst; i > 0 ; i--)
1279 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
1280 wDstPnt++;
1282 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1286 else if(usePat)
1288 MAYBE(TRACE("StretchBlt use: pat -- solid brush -- rop is %02x, color is %08x\n", rop, patColor));
1289 MAYBE(TRACE("Dest BMP is a '%s'\n", _DIBDRVBITMAP_GetFormatName(dstBmp)));
1290 MAYBE(TRACE("xDst = %d, yDst = %d, widthDst = %d, heightDst = %d\n", xDst, yDst, widthDst, heightDst));
1291 if(heightSrc > heightDst)
1293 ys = 0;
1294 yd = 0;
1295 delta = 0;
1296 while(yd < heightDst)
1298 wDstPnt = dBuf;
1299 for(i = widthDst; i > 0 ; i--)
1301 *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
1302 wDstPnt++;
1304 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1305 while(delta < heightSrc)
1307 ys++;
1308 delta += heightDst;
1310 delta -= heightSrc;
1311 yd++;
1314 else if(heightSrc < heightDst)
1316 ys = 0;
1317 yd = 0;
1318 delta = 0;
1319 while(ys < heightSrc)
1321 while(delta < heightDst)
1323 wDstPnt = dBuf;
1324 for(i = widthDst; i > 0 ; i--)
1326 *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
1327 wDstPnt++;
1329 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1330 yd++;
1331 delta += heightSrc;
1333 delta -= heightDst;
1334 ys++;
1337 else
1339 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
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, xDst, widthDst, dBuf);
1351 else
1352 ERR("What happened ?????? \n");
1353 break;
1354 } /* switch */
1355 res = TRUE;
1356 error:
1357 if(sBufOrig) HeapFree( GetProcessHeap(), 0, sBufOrig );
1358 if(sBufStr) HeapFree( GetProcessHeap(), 0, sBufStr );
1359 if(dBuf) HeapFree( GetProcessHeap(), 0, dBuf );
1360 if(pBuf) HeapFree( GetProcessHeap(), 0, pBuf );
1361 return res;