da4835298ae3462261c5741c1b8406288a5ed119
[wine/hacks.git] / dlls / winedib.drv / primitives_bitblt.c
blobda4835298ae3462261c5741c1b8406288a5ed119
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 /* ------------------------------------------------------------*/
84 /* BLITTING PRIMITIVES */
85 BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
86 INT width, INT height, const DIBDRVPHYSDEV *physDevSrc,
87 INT xSrc, INT ySrc, DWORD rop)
89 int ys, yd;
90 int i;
91 DWORD *dwBuf;
92 DIBDRVBITMAP *dstBmp, *patBmp;
93 const DIBDRVBITMAP *srcBmp;
94 DWORD *wDstPnt, *wSrcPnt, *wPatPnt;
95 BOOL usePat, useSrc, useDst;
96 DWORD patColor;
97 BOOL res = FALSE;
99 /* 32 bit RGB source and destination buffer, if needed */
100 DWORD *sBuf = 0, *dBuf = 0, *pBuf = 0;
102 /* get elements usage */
103 usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000));
104 useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
105 useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
107 /* gets source, dest and pattern bitmaps, if available */
108 if(usePat && physDevDst->isBrushBitmap)
109 patBmp = &physDevDst->brushBmpCache;
110 else
111 patBmp = NULL;
113 if(useSrc)
114 srcBmp = &physDevSrc->physBitmap;
115 else
116 srcBmp = NULL;
117 dstBmp = &physDevDst->physBitmap;
119 /* gets pattern color, in case it's needed */
120 if(usePat)
121 patColor = physDevDst->brushColor;
122 else
123 patColor = 0;
125 /* allocate 32 bit RGB destination buffer */
126 if(!(dBuf = (DWORD *)HeapAlloc( GetProcessHeap(), 0, width * 4)))
127 goto error;
129 MAYBE(TRACE("dstBmp:%p(%s), xDst:%d, yDst:%d, width:%d, height:%d, srcBmp:%p(%s), xSrc:%d, ySrc:%d, rop:%8x\n",
130 dstBmp, _DIBDRVBITMAP_GetFormatName(dstBmp), xDst, yDst, width, height,
131 srcBmp, _DIBDRVBITMAP_GetFormatName(srcBmp), xSrc, ySrc, rop));
133 /* some simple ROPs optimizations */
134 switch(rop)
136 case BLACKNESS:
137 MAYBE(TRACE("BLACKNESS\n"));
138 memset(dBuf, 0x00, width * 4);
139 for(yd = yDst; yd < yDst+height; yd++)
140 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
141 break;
143 case WHITENESS:
144 MAYBE(TRACE("WHITENESS\n"));
145 for(dwBuf = dBuf, i = width; i; i--)
146 *dwBuf++ = 0x00ffffff;
147 for(yd = yDst; yd < yDst+height; yd++)
148 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
149 break;
151 case SRCCOPY:
152 MAYBE(TRACE("SRCCOPY\n"));
153 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
155 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
156 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
158 break;
160 /* fallback for generic ROP operation */
161 default:
162 rop >>= 16;
163 if(useSrc && useDst && usePat && physDevDst->isBrushBitmap)
165 MAYBE(TRACE("BitBlt use: src+dst+pat - pattern brush\n"));
166 if(!(sBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
167 goto error;
168 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
169 goto error;
170 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
172 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, sBuf);
173 dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf);
174 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
175 wDstPnt = dBuf;
176 wSrcPnt = sBuf;
177 wPatPnt = pBuf;
178 for(i = width; i > 0 ; i--)
180 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
181 wDstPnt++;
183 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
186 else if(useSrc && useDst)
188 if(usePat)
189 MAYBE(TRACE("BitBlt use: src+dst+pat - solid brush\n"));
190 else
191 MAYBE(TRACE("BitBlt use: src+dst\n"));
192 if(!(sBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
193 goto error;
194 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
196 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, sBuf);
197 dstBmp->funcs->GetLine(dstBmp, yd, xDst, width, dBuf);
198 wDstPnt = dBuf;
199 wSrcPnt = sBuf;
200 for(i = width; i > 0 ; i--)
202 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
203 wDstPnt++;
205 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
208 else if(useSrc && usePat && physDevDst->isBrushBitmap)
210 MAYBE(TRACE("BitBlt use: src+pat -- pattern brush\n"));
211 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
212 goto error;
213 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
215 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
216 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
217 wDstPnt = sBuf;
218 wSrcPnt = sBuf;
219 wPatPnt = pBuf;
220 for(i = width; i > 0 ; i--)
222 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
223 wDstPnt++;
225 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
228 else if(useSrc)
230 if(usePat)
231 MAYBE(TRACE("BitBlt use: src+pat - solid brush\n"));
232 else
233 MAYBE(TRACE("BitBlt use: src\n"));
234 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
236 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
237 wDstPnt = sBuf;
238 wSrcPnt = sBuf;
239 for(i = width; i > 0 ; i--)
241 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
242 wDstPnt++;
244 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
247 else if(useDst && usePat && physDevDst->isBrushBitmap)
249 MAYBE(TRACE("BitBlt use: dst+pat -- pattern brush\n"));
250 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
251 goto error;
252 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
254 dstBmp->funcs->GetLine(srcBmp, ys, xDst, width, dBuf);
255 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
256 wDstPnt = sBuf;
257 wPatPnt = pBuf;
258 for(i = width; i > 0 ; i--)
260 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
261 wDstPnt++;
263 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
266 else if(useDst)
268 if(usePat)
269 MAYBE(TRACE("BitBlt use: dst+pat - solid brush\n"));
270 else
271 MAYBE(TRACE("BitBlt use: dst\n"));
272 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
274 dstBmp->funcs->GetLine(srcBmp, ys, xDst, width, dBuf);
275 wDstPnt = sBuf;
276 for(i = width; i > 0 ; i--)
278 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
279 wDstPnt++;
281 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
284 else if(usePat && physDevDst->isBrushBitmap)
286 MAYBE(TRACE("BitBlt use: pat -- pattern brush\n"));
287 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
288 goto error;
289 for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
291 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
292 wDstPnt = dBuf;
293 wPatPnt = pBuf;
294 for(i = width; i > 0 ; i--)
296 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
297 wDstPnt++;
299 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
302 else if(usePat)
304 MAYBE(TRACE("BitBlt use: pat -- solid brush -- rop is %02x, color is %08x\n", rop, patColor));
305 MAYBE(TRACE("Dest BMP is a '%s'\n", _DIBDRVBITMAP_GetFormatName(dstBmp)));
306 MAYBE(TRACE("xDst = %d, yDst = %d, width = %d, height = %d\n", xDst, yDst, width, height));
307 for(yd = yDst; yd < yDst+height; yd++)
309 wDstPnt = dBuf;
310 for(i = width; i > 0 ; i--)
312 *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
313 wDstPnt++;
315 dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
318 else
319 ERR("What happened ?????? \n");
320 break;
321 } /* switch */
322 res = TRUE;
323 error:
324 if(sBuf) HeapFree( GetProcessHeap(), 0, sBuf );
325 if(dBuf) HeapFree( GetProcessHeap(), 0, dBuf );
326 if(pBuf) HeapFree( GetProcessHeap(), 0, pBuf );
327 return res;
330 /* ------------------------------------------------------------*/
331 /* STRETCHING PRIMITIVES */
332 BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
333 INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc,
334 INT xSrc, INT ySrc, int widthSrc, int heightSrc, DWORD rop)
336 int ys, yd;
337 int i, delta;
338 DWORD *dwBuf;
339 DIBDRVBITMAP *dstBmp, *patBmp;
340 const DIBDRVBITMAP *srcBmp;
341 DWORD *wDstPnt, *wSrcPnt, *wPatPnt;
342 BOOL usePat, useSrc, useDst;
343 DWORD patColor;
344 BOOL res = FALSE;
346 /* 32 bit RGB source and destination buffer, if needed */
347 DWORD *sBufOrig = 0, *sBufStr = 0, *dBuf = 0, *pBuf = 0;
349 /* get elements usage */
350 usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000));
351 useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
352 useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
354 /* gets source, dest and pattern bitmaps, if available */
355 if(usePat && physDevDst->isBrushBitmap)
356 patBmp = &physDevDst->brushBmpCache;
357 else
358 patBmp = NULL;
360 if(useSrc)
361 srcBmp = &physDevSrc->physBitmap;
362 else
363 srcBmp = NULL;
364 dstBmp = &physDevDst->physBitmap;
366 /* gets pattern color, in case it's needed */
367 if(usePat)
368 patColor = physDevDst->brushColor;
369 else
370 patColor = 0;
372 /* allocate 32 bit RGB destination buffer */
373 if(!(dBuf = (DWORD *)HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
374 goto error;
376 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",
377 dstBmp, _DIBDRVBITMAP_GetFormatName(dstBmp), xDst, yDst, widthDst, heightDst,
378 srcBmp, _DIBDRVBITMAP_GetFormatName(srcBmp), xSrc, ySrc, widthSrc, heightSrc, rop));
380 /* some simple ROPs optimizations */
381 switch(rop)
383 case BLACKNESS:
384 MAYBE(TRACE("BLACKNESS\n"));
385 memset(dBuf, 0x00, widthDst * 4);
386 for(yd = yDst; yd < yDst+heightDst; yd++)
387 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
388 break;
390 case WHITENESS:
391 MAYBE(TRACE("WHITENESS\n"));
392 for(dwBuf = dBuf, i = widthDst; i; i--)
393 *dwBuf++ = 0x00ffffff;
394 for(yd = yDst; yd < yDst+heightDst; yd++)
395 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
396 break;
398 case SRCCOPY:
399 MAYBE(TRACE("SRCCOPY\n"));
400 sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4);
401 if(heightSrc > heightDst)
403 ys = 0;
404 yd = 0;
405 delta = 0;
406 while(yd < heightDst)
408 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
409 StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
410 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
411 while(delta < heightSrc)
413 ys++;
414 delta += heightDst;
416 delta -= heightSrc;
417 yd++;
420 else if(heightSrc < heightDst)
422 ys = 0;
423 yd = 0;
424 delta = 0;
425 while(ys < heightSrc)
427 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
428 StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
429 while(delta < heightDst)
431 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
432 yd++;
433 delta += heightSrc;
435 delta -= heightDst;
436 ys++;
439 else
441 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
443 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
444 StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
445 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
448 break;
450 /* fallback for generic ROP operation */
451 default:
452 rop >>= 16;
453 if(useSrc && useDst && usePat && physDevDst->isBrushBitmap)
455 MAYBE(TRACE("StretchBlt use: src+dst+pat - pattern brush\n"));
456 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
457 goto error;
458 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
459 goto error;
460 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
461 goto error;
462 if(heightSrc > heightDst)
464 ys = 0;
465 yd = 0;
466 delta = 0;
467 while(yd < heightDst)
469 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
470 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
471 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
472 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
473 wDstPnt = dBuf;
474 wSrcPnt = sBufStr;
475 wPatPnt = pBuf;
476 for(i = widthDst; i > 0 ; i--)
478 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
479 wDstPnt++;
481 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
482 while(delta < heightSrc)
484 ys++;
485 delta += heightDst;
487 delta -= heightSrc;
488 yd++;
491 else if(heightSrc < heightDst)
493 ys = 0;
494 yd = 0;
495 delta = 0;
496 while(ys < heightSrc)
498 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
499 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
500 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
501 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
502 while(delta < heightDst)
504 wDstPnt = dBuf;
505 wSrcPnt = sBufStr;
506 wPatPnt = pBuf;
507 for(i = widthDst; i > 0 ; i--)
509 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
510 wDstPnt++;
512 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
513 yd++;
514 delta += heightSrc;
516 delta -= heightDst;
517 ys++;
520 else
522 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
524 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
525 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
526 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
527 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
528 wDstPnt = dBuf;
529 wSrcPnt = sBufStr;
530 wPatPnt = pBuf;
531 for(i = widthDst; i > 0 ; i--)
533 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
534 wDstPnt++;
536 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
540 else if(useSrc && useDst)
542 if(usePat)
543 MAYBE(TRACE("StretchBlt use: src+dst+pat - solid brush\n"));
544 else
545 MAYBE(TRACE("StretchBlt use: src+dst\n"));
546 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
547 goto error;
548 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
549 goto error;
550 if(heightSrc > heightDst)
552 ys = 0;
553 yd = 0;
554 delta = 0;
555 while(yd < heightDst)
557 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
558 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
559 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
560 wDstPnt = dBuf;
561 wSrcPnt = sBufStr;
562 for(i = widthDst; i > 0 ; i--)
564 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
565 wDstPnt++;
567 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
568 while(delta < heightSrc)
570 ys++;
571 delta += heightDst;
573 delta -= heightSrc;
574 yd++;
577 else if(heightSrc < heightDst)
579 ys = 0;
580 yd = 0;
581 delta = 0;
582 while(ys < heightSrc)
584 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
585 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
586 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
587 while(delta < heightDst)
589 wDstPnt = dBuf;
590 wSrcPnt = sBufStr;
591 for(i = widthDst; i > 0 ; i--)
593 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
594 wDstPnt++;
596 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
597 yd++;
598 delta += heightSrc;
600 delta -= heightDst;
601 ys++;
604 else
606 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
608 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
609 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
610 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
611 wDstPnt = dBuf;
612 wSrcPnt = sBufStr;
613 for(i = widthDst; i > 0 ; i--)
615 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
616 wDstPnt++;
618 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
622 else if(useSrc && usePat && physDevDst->isBrushBitmap)
624 MAYBE(TRACE("StretchBlt use: src+pat -- pattern brush\n"));
625 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
626 goto error;
627 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
628 goto error;
629 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
630 goto error;
631 if(heightSrc > heightDst)
633 ys = 0;
634 yd = 0;
635 delta = 0;
636 while(yd < heightDst)
638 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
639 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
640 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
641 wDstPnt = dBuf;
642 wSrcPnt = sBufStr;
643 wPatPnt = pBuf;
644 for(i = widthDst; i > 0 ; i--)
646 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
647 wDstPnt++;
649 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
650 while(delta < heightSrc)
652 ys++;
653 delta += heightDst;
655 delta -= heightSrc;
656 yd++;
659 else if(heightSrc < heightDst)
661 ys = 0;
662 yd = 0;
663 delta = 0;
664 while(ys < heightSrc)
666 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
667 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
668 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
669 while(delta < heightDst)
671 wDstPnt = dBuf;
672 wSrcPnt = sBufStr;
673 wPatPnt = pBuf;
674 for(i = widthDst; i > 0 ; i--)
676 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
677 wDstPnt++;
679 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
680 yd++;
681 delta += heightSrc;
683 delta -= heightDst;
684 ys++;
687 else
689 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
691 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
692 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
693 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
694 wDstPnt = dBuf;
695 wSrcPnt = sBufStr;
696 wPatPnt = pBuf;
697 for(i = widthDst; i > 0 ; i--)
699 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
700 wDstPnt++;
702 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
706 else if(useSrc)
708 if(usePat)
709 MAYBE(TRACE("StretchBlt use: src+pat - solid brush\n"));
710 else
711 MAYBE(TRACE("StretchBlt use: src\n"));
712 if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
713 goto error;
714 if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
715 goto error;
716 if(heightSrc > heightDst)
718 ys = 0;
719 yd = 0;
720 delta = 0;
721 while(yd < heightDst)
723 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
724 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
725 wDstPnt = dBuf;
726 wSrcPnt = sBufStr;
727 for(i = widthDst; i > 0 ; i--)
729 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
730 wDstPnt++;
732 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
733 while(delta < heightSrc)
735 ys++;
736 delta += heightDst;
738 delta -= heightSrc;
739 yd++;
742 else if(heightSrc < heightDst)
744 ys = 0;
745 yd = 0;
746 delta = 0;
747 while(ys < heightSrc)
749 srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
750 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
751 while(delta < heightDst)
753 wDstPnt = dBuf;
754 wSrcPnt = sBufStr;
755 for(i = widthDst; i > 0 ; i--)
757 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
758 wDstPnt++;
760 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
761 yd++;
762 delta += heightSrc;
764 delta -= heightDst;
765 ys++;
768 else
770 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
772 srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
773 StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
774 wDstPnt = dBuf;
775 wSrcPnt = sBufStr;
776 for(i = widthDst; i > 0 ; i--)
778 *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
779 wDstPnt++;
781 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
785 else if(useDst && usePat && physDevDst->isBrushBitmap)
787 MAYBE(TRACE("StretchBlt use: dst+pat -- pattern brush\n"));
788 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
789 goto error;
790 if(heightSrc > heightDst)
792 ys = 0;
793 yd = 0;
794 delta = 0;
795 while(yd < heightDst)
797 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
798 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
799 wDstPnt = dBuf;
800 wPatPnt = pBuf;
801 for(i = widthDst; i > 0 ; i--)
803 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
804 wDstPnt++;
806 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
807 while(delta < heightSrc)
809 ys++;
810 delta += heightDst;
812 delta -= heightSrc;
813 yd++;
816 else if(heightSrc < heightDst)
818 ys = 0;
819 yd = 0;
820 delta = 0;
821 while(ys < heightSrc)
823 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
824 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
825 while(delta < heightDst)
827 wDstPnt = dBuf;
828 wPatPnt = pBuf;
829 for(i = widthDst; i > 0 ; i--)
831 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
832 wDstPnt++;
834 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
835 yd++;
836 delta += heightSrc;
838 delta -= heightDst;
839 ys++;
842 else
844 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
846 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
847 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
848 wDstPnt = dBuf;
849 wPatPnt = pBuf;
850 for(i = widthDst; i > 0 ; i--)
852 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
853 wDstPnt++;
855 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
859 else if(useDst)
861 if(usePat)
862 MAYBE(TRACE("StretchBlt use: dst+pat - solid brush\n"));
863 else
864 MAYBE(TRACE("StretchBlt use: dst\n"));
865 if(heightSrc > heightDst)
867 ys = 0;
868 yd = 0;
869 delta = 0;
870 while(yd < heightDst)
872 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
873 wDstPnt = dBuf;
874 for(i = widthDst; i > 0 ; i--)
876 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
877 wDstPnt++;
879 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
880 while(delta < heightSrc)
882 ys++;
883 delta += heightDst;
885 delta -= heightSrc;
886 yd++;
889 else if(heightSrc < heightDst)
891 ys = 0;
892 yd = 0;
893 delta = 0;
894 while(ys < heightSrc)
896 dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
897 while(delta < heightDst)
899 wDstPnt = dBuf;
900 for(i = widthDst; i > 0 ; i--)
902 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
903 wDstPnt++;
905 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
906 yd++;
907 delta += heightSrc;
909 delta -= heightDst;
910 ys++;
913 else
915 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
917 dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
918 wDstPnt = dBuf;
919 for(i = widthDst; i > 0 ; i--)
921 *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
922 wDstPnt++;
924 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
928 else if(usePat && physDevDst->isBrushBitmap)
930 MAYBE(TRACE("StretchBlt use: pat -- pattern brush\n"));
931 if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
932 goto error;
933 if(heightSrc > heightDst)
935 ys = 0;
936 yd = 0;
937 delta = 0;
938 while(yd < heightDst)
940 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
941 wDstPnt = dBuf;
942 wPatPnt = pBuf;
943 for(i = widthDst; i > 0 ; i--)
945 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
946 wDstPnt++;
948 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
949 while(delta < heightSrc)
951 ys++;
952 delta += heightDst;
954 delta -= heightSrc;
955 yd++;
958 else if(heightSrc < heightDst)
960 ys = 0;
961 yd = 0;
962 delta = 0;
963 while(ys < heightSrc)
965 patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
966 while(delta < heightDst)
968 wDstPnt = dBuf;
969 wPatPnt = pBuf;
970 for(i = widthDst; i > 0 ; i--)
972 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
973 wDstPnt++;
975 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
976 yd++;
977 delta += heightSrc;
979 delta -= heightDst;
980 ys++;
983 else
985 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
987 patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
988 wDstPnt = dBuf;
989 wPatPnt = pBuf;
990 for(i = widthDst; i > 0 ; i--)
992 *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
993 wDstPnt++;
995 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
999 else if(usePat)
1001 MAYBE(TRACE("StretchBlt use: pat -- solid brush -- rop is %02x, color is %08x\n", rop, patColor));
1002 MAYBE(TRACE("Dest BMP is a '%s'\n", _DIBDRVBITMAP_GetFormatName(dstBmp)));
1003 MAYBE(TRACE("xDst = %d, yDst = %d, widthDst = %d, heightDst = %d\n", xDst, yDst, widthDst, heightDst));
1004 if(heightSrc > heightDst)
1006 ys = 0;
1007 yd = 0;
1008 delta = 0;
1009 while(yd < heightDst)
1011 wDstPnt = dBuf;
1012 for(i = widthDst; i > 0 ; i--)
1014 *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
1015 wDstPnt++;
1017 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1018 while(delta < heightSrc)
1020 ys++;
1021 delta += heightDst;
1023 delta -= heightSrc;
1024 yd++;
1027 else if(heightSrc < heightDst)
1029 ys = 0;
1030 yd = 0;
1031 delta = 0;
1032 while(ys < heightSrc)
1034 while(delta < heightDst)
1036 wDstPnt = dBuf;
1037 for(i = widthDst; i > 0 ; i--)
1039 *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
1040 wDstPnt++;
1042 dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
1043 yd++;
1044 delta += heightSrc;
1046 delta -= heightDst;
1047 ys++;
1050 else
1052 for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
1054 wDstPnt = dBuf;
1055 for(i = widthDst; i > 0 ; i--)
1057 *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
1058 wDstPnt++;
1060 dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
1064 else
1065 ERR("What happened ?????? \n");
1066 break;
1067 } /* switch */
1068 res = TRUE;
1069 error:
1070 if(sBufOrig) HeapFree( GetProcessHeap(), 0, sBufOrig );
1071 if(sBufStr) HeapFree( GetProcessHeap(), 0, sBufStr );
1072 if(dBuf) HeapFree( GetProcessHeap(), 0, dBuf );
1073 if(pBuf) HeapFree( GetProcessHeap(), 0, pBuf );
1074 return res;