d3d9/tests: Test for Direct3DCreate9 failure.
[wine/wine64.git] / dlls / gdi32 / bitblt.c
blobf446e260b047afeed745cb5184d61de93ae2f80c
1 /*
2 * GDI bit-blit operations
4 * Copyright 1993, 1994 Alexandre Julliard
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 <stdarg.h>
23 #include <math.h>
24 #ifdef HAVE_FLOAT_H
25 #include <float.h>
26 #endif
28 #include "windef.h"
29 #include "winbase.h"
30 #include "wingdi.h"
31 #include "gdi_private.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(bitblt);
37 /***********************************************************************
38 * PatBlt (GDI32.@)
40 BOOL WINAPI PatBlt( HDC hdc, INT left, INT top,
41 INT width, INT height, DWORD rop)
43 DC * dc = get_dc_ptr( hdc );
44 BOOL bRet = FALSE;
46 if (!dc) return FALSE;
48 if (dc->funcs->pPatBlt)
50 TRACE("%p %d,%d %dx%d %06x\n", hdc, left, top, width, height, rop );
51 update_dc( dc );
52 bRet = dc->funcs->pPatBlt( dc->physDev, left, top, width, height, rop );
54 release_dc_ptr( dc );
55 return bRet;
59 /***********************************************************************
60 * BitBlt (GDI32.@)
62 BOOL WINAPI BitBlt( HDC hdcDst, INT xDst, INT yDst, INT width,
63 INT height, HDC hdcSrc, INT xSrc, INT ySrc, DWORD rop )
65 BOOL ret = FALSE;
66 DC *dcDst, *dcSrc;
68 TRACE("hdcSrc=%p %d,%d -> hdcDest=%p %d,%d %dx%d rop=%06x\n",
69 hdcSrc, xSrc, ySrc, hdcDst, xDst, yDst, width, height, rop);
71 if (!(dcDst = get_dc_ptr( hdcDst ))) return FALSE;
73 if (dcDst->funcs->pBitBlt)
75 update_dc( dcDst );
76 dcSrc = get_dc_ptr( hdcSrc );
77 if (dcSrc) update_dc( dcSrc );
79 ret = dcDst->funcs->pBitBlt( dcDst->physDev, xDst, yDst, width, height,
80 dcSrc ? dcSrc->physDev : NULL, xSrc, ySrc, rop );
82 release_dc_ptr( dcDst );
83 if (dcSrc) release_dc_ptr( dcSrc );
85 else if (dcDst->funcs->pStretchDIBits)
87 BITMAP bm;
88 BITMAPINFOHEADER info_hdr;
89 HBITMAP hbm;
90 LPVOID bits;
91 INT lines;
93 release_dc_ptr( dcDst );
95 if(GetObjectType( hdcSrc ) != OBJ_MEMDC)
97 FIXME("hdcSrc isn't a memory dc. Don't yet cope with this\n");
98 return FALSE;
101 GetObjectW(GetCurrentObject(hdcSrc, OBJ_BITMAP), sizeof(bm), &bm);
103 info_hdr.biSize = sizeof(info_hdr);
104 info_hdr.biWidth = bm.bmWidth;
105 info_hdr.biHeight = bm.bmHeight;
106 info_hdr.biPlanes = 1;
107 info_hdr.biBitCount = 32;
108 info_hdr.biCompression = BI_RGB;
109 info_hdr.biSizeImage = 0;
110 info_hdr.biXPelsPerMeter = 0;
111 info_hdr.biYPelsPerMeter = 0;
112 info_hdr.biClrUsed = 0;
113 info_hdr.biClrImportant = 0;
115 if(!(bits = HeapAlloc(GetProcessHeap(), 0, bm.bmHeight * bm.bmWidth * 4)))
116 return FALSE;
118 /* Select out the src bitmap before calling GetDIBits */
119 hbm = SelectObject(hdcSrc, GetStockObject(DEFAULT_BITMAP));
120 GetDIBits(hdcSrc, hbm, 0, bm.bmHeight, bits, (BITMAPINFO*)&info_hdr, DIB_RGB_COLORS);
121 SelectObject(hdcSrc, hbm);
123 lines = StretchDIBits(hdcDst, xDst, yDst, width, height, xSrc, bm.bmHeight - height - ySrc,
124 width, height, bits, (BITMAPINFO*)&info_hdr, DIB_RGB_COLORS, rop);
126 HeapFree(GetProcessHeap(), 0, bits);
127 return (lines == height);
129 else release_dc_ptr( dcDst );
131 return ret;
135 /***********************************************************************
136 * StretchBlt (GDI32.@)
138 BOOL WINAPI StretchBlt( HDC hdcDst, INT xDst, INT yDst,
139 INT widthDst, INT heightDst,
140 HDC hdcSrc, INT xSrc, INT ySrc,
141 INT widthSrc, INT heightSrc,
142 DWORD rop )
144 BOOL ret = FALSE;
145 DC *dcDst, *dcSrc;
147 TRACE("%p %d,%d %dx%d -> %p %d,%d %dx%d rop=%06x\n",
148 hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
149 hdcDst, xDst, yDst, widthDst, heightDst, rop );
152 if (!(dcDst = get_dc_ptr( hdcDst ))) return FALSE;
154 if (dcDst->funcs->pStretchBlt)
156 if ((dcSrc = get_dc_ptr( hdcSrc )))
158 update_dc( dcDst );
159 update_dc( dcSrc );
161 ret = dcDst->funcs->pStretchBlt( dcDst->physDev, xDst, yDst, widthDst, heightDst,
162 dcSrc->physDev, xSrc, ySrc, widthSrc, heightSrc,
163 rop );
164 release_dc_ptr( dcDst );
165 release_dc_ptr( dcSrc );
168 else if (dcDst->funcs->pStretchDIBits)
170 BITMAP bm;
171 BITMAPINFOHEADER info_hdr;
172 HBITMAP hbm;
173 LPVOID bits;
174 INT lines;
176 release_dc_ptr( dcDst );
178 if(GetObjectType( hdcSrc ) != OBJ_MEMDC) return FALSE;
180 GetObjectW(GetCurrentObject(hdcSrc, OBJ_BITMAP), sizeof(bm), &bm);
182 info_hdr.biSize = sizeof(info_hdr);
183 info_hdr.biWidth = bm.bmWidth;
184 info_hdr.biHeight = bm.bmHeight;
185 info_hdr.biPlanes = 1;
186 info_hdr.biBitCount = 32;
187 info_hdr.biCompression = BI_RGB;
188 info_hdr.biSizeImage = 0;
189 info_hdr.biXPelsPerMeter = 0;
190 info_hdr.biYPelsPerMeter = 0;
191 info_hdr.biClrUsed = 0;
192 info_hdr.biClrImportant = 0;
194 if(!(bits = HeapAlloc(GetProcessHeap(), 0, bm.bmHeight * bm.bmWidth * 4)))
195 return FALSE;
197 /* Select out the src bitmap before calling GetDIBits */
198 hbm = SelectObject(hdcSrc, GetStockObject(DEFAULT_BITMAP));
199 GetDIBits(hdcSrc, hbm, 0, bm.bmHeight, bits, (BITMAPINFO*)&info_hdr, DIB_RGB_COLORS);
200 SelectObject(hdcSrc, hbm);
202 lines = StretchDIBits(hdcDst, xDst, yDst, widthDst, heightDst, xSrc, bm.bmHeight - heightSrc - ySrc,
203 widthSrc, heightSrc, bits, (BITMAPINFO*)&info_hdr, DIB_RGB_COLORS, rop);
205 HeapFree(GetProcessHeap(), 0, bits);
206 return (lines == heightSrc);
208 else release_dc_ptr( dcDst );
210 return ret;
213 #define FRGND_ROP3(ROP4) ((ROP4) & 0x00FFFFFF)
214 #define BKGND_ROP3(ROP4) (ROP3Table[((ROP4)>>24) & 0xFF])
216 /***********************************************************************
217 * MaskBlt [GDI32.@]
219 BOOL WINAPI MaskBlt(HDC hdcDest, INT nXDest, INT nYDest,
220 INT nWidth, INT nHeight, HDC hdcSrc,
221 INT nXSrc, INT nYSrc, HBITMAP hbmMask,
222 INT xMask, INT yMask, DWORD dwRop)
224 HBITMAP hBitmap1, hOldBitmap1, hBitmap2, hOldBitmap2;
225 HDC hDC1, hDC2;
226 HBRUSH hbrMask, hbrDst, hbrTmp;
228 static const DWORD ROP3Table[256] =
230 0x00000042, 0x00010289,
231 0x00020C89, 0x000300AA,
232 0x00040C88, 0x000500A9,
233 0x00060865, 0x000702C5,
234 0x00080F08, 0x00090245,
235 0x000A0329, 0x000B0B2A,
236 0x000C0324, 0x000D0B25,
237 0x000E08A5, 0x000F0001,
238 0x00100C85, 0x001100A6,
239 0x00120868, 0x001302C8,
240 0x00140869, 0x001502C9,
241 0x00165CCA, 0x00171D54,
242 0x00180D59, 0x00191CC8,
243 0x001A06C5, 0x001B0768,
244 0x001C06CA, 0x001D0766,
245 0x001E01A5, 0x001F0385,
246 0x00200F09, 0x00210248,
247 0x00220326, 0x00230B24,
248 0x00240D55, 0x00251CC5,
249 0x002606C8, 0x00271868,
250 0x00280369, 0x002916CA,
251 0x002A0CC9, 0x002B1D58,
252 0x002C0784, 0x002D060A,
253 0x002E064A, 0x002F0E2A,
254 0x0030032A, 0x00310B28,
255 0x00320688, 0x00330008,
256 0x003406C4, 0x00351864,
257 0x003601A8, 0x00370388,
258 0x0038078A, 0x00390604,
259 0x003A0644, 0x003B0E24,
260 0x003C004A, 0x003D18A4,
261 0x003E1B24, 0x003F00EA,
262 0x00400F0A, 0x00410249,
263 0x00420D5D, 0x00431CC4,
264 0x00440328, 0x00450B29,
265 0x004606C6, 0x0047076A,
266 0x00480368, 0x004916C5,
267 0x004A0789, 0x004B0605,
268 0x004C0CC8, 0x004D1954,
269 0x004E0645, 0x004F0E25,
270 0x00500325, 0x00510B26,
271 0x005206C9, 0x00530764,
272 0x005408A9, 0x00550009,
273 0x005601A9, 0x00570389,
274 0x00580785, 0x00590609,
275 0x005A0049, 0x005B18A9,
276 0x005C0649, 0x005D0E29,
277 0x005E1B29, 0x005F00E9,
278 0x00600365, 0x006116C6,
279 0x00620786, 0x00630608,
280 0x00640788, 0x00650606,
281 0x00660046, 0x006718A8,
282 0x006858A6, 0x00690145,
283 0x006A01E9, 0x006B178A,
284 0x006C01E8, 0x006D1785,
285 0x006E1E28, 0x006F0C65,
286 0x00700CC5, 0x00711D5C,
287 0x00720648, 0x00730E28,
288 0x00740646, 0x00750E26,
289 0x00761B28, 0x007700E6,
290 0x007801E5, 0x00791786,
291 0x007A1E29, 0x007B0C68,
292 0x007C1E24, 0x007D0C69,
293 0x007E0955, 0x007F03C9,
294 0x008003E9, 0x00810975,
295 0x00820C49, 0x00831E04,
296 0x00840C48, 0x00851E05,
297 0x008617A6, 0x008701C5,
298 0x008800C6, 0x00891B08,
299 0x008A0E06, 0x008B0666,
300 0x008C0E08, 0x008D0668,
301 0x008E1D7C, 0x008F0CE5,
302 0x00900C45, 0x00911E08,
303 0x009217A9, 0x009301C4,
304 0x009417AA, 0x009501C9,
305 0x00960169, 0x0097588A,
306 0x00981888, 0x00990066,
307 0x009A0709, 0x009B07A8,
308 0x009C0704, 0x009D07A6,
309 0x009E16E6, 0x009F0345,
310 0x00A000C9, 0x00A11B05,
311 0x00A20E09, 0x00A30669,
312 0x00A41885, 0x00A50065,
313 0x00A60706, 0x00A707A5,
314 0x00A803A9, 0x00A90189,
315 0x00AA0029, 0x00AB0889,
316 0x00AC0744, 0x00AD06E9,
317 0x00AE0B06, 0x00AF0229,
318 0x00B00E05, 0x00B10665,
319 0x00B21974, 0x00B30CE8,
320 0x00B4070A, 0x00B507A9,
321 0x00B616E9, 0x00B70348,
322 0x00B8074A, 0x00B906E6,
323 0x00BA0B09, 0x00BB0226,
324 0x00BC1CE4, 0x00BD0D7D,
325 0x00BE0269, 0x00BF08C9,
326 0x00C000CA, 0x00C11B04,
327 0x00C21884, 0x00C3006A,
328 0x00C40E04, 0x00C50664,
329 0x00C60708, 0x00C707AA,
330 0x00C803A8, 0x00C90184,
331 0x00CA0749, 0x00CB06E4,
332 0x00CC0020, 0x00CD0888,
333 0x00CE0B08, 0x00CF0224,
334 0x00D00E0A, 0x00D1066A,
335 0x00D20705, 0x00D307A4,
336 0x00D41D78, 0x00D50CE9,
337 0x00D616EA, 0x00D70349,
338 0x00D80745, 0x00D906E8,
339 0x00DA1CE9, 0x00DB0D75,
340 0x00DC0B04, 0x00DD0228,
341 0x00DE0268, 0x00DF08C8,
342 0x00E003A5, 0x00E10185,
343 0x00E20746, 0x00E306EA,
344 0x00E40748, 0x00E506E5,
345 0x00E61CE8, 0x00E70D79,
346 0x00E81D74, 0x00E95CE6,
347 0x00EA02E9, 0x00EB0849,
348 0x00EC02E8, 0x00ED0848,
349 0x00EE0086, 0x00EF0A08,
350 0x00F00021, 0x00F10885,
351 0x00F20B05, 0x00F3022A,
352 0x00F40B0A, 0x00F50225,
353 0x00F60265, 0x00F708C5,
354 0x00F802E5, 0x00F90845,
355 0x00FA0089, 0x00FB0A09,
356 0x00FC008A, 0x00FD0A0A,
357 0x00FE02A9, 0x00FF0062,
360 if (!hbmMask)
361 return BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop));
363 hbrMask = CreatePatternBrush(hbmMask);
364 hbrDst = SelectObject(hdcDest, GetStockObject(NULL_BRUSH));
366 /* make bitmap */
367 hDC1 = CreateCompatibleDC(hdcDest);
368 hBitmap1 = CreateCompatibleBitmap(hdcDest, nWidth, nHeight);
369 hOldBitmap1 = SelectObject(hDC1, hBitmap1);
371 /* draw using bkgnd rop */
372 BitBlt(hDC1, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY);
373 hbrTmp = SelectObject(hDC1, hbrDst);
374 BitBlt(hDC1, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, BKGND_ROP3(dwRop));
375 SelectObject(hDC1, hbrTmp);
377 /* make bitmap */
378 hDC2 = CreateCompatibleDC(hdcDest);
379 hBitmap2 = CreateCompatibleBitmap(hdcDest, nWidth, nHeight);
380 hOldBitmap2 = SelectObject(hDC2, hBitmap2);
382 /* draw using foregnd rop */
383 BitBlt(hDC2, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY);
384 hbrTmp = SelectObject(hDC2, hbrDst);
385 BitBlt(hDC2, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop));
387 /* combine both using the mask as a pattern brush */
388 SelectObject(hDC2, hbrMask);
389 BitBlt(hDC2, 0, 0, nWidth, nHeight, hDC1, 0, 0, 0xac0744 ); /* (D & P) | (S & ~P) */
390 SelectObject(hDC2, hbrTmp);
392 /* blit to dst */
393 BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hDC2, 0, 0, SRCCOPY);
395 /* restore all objects */
396 SelectObject(hdcDest, hbrDst);
397 SelectObject(hDC1, hOldBitmap1);
398 SelectObject(hDC2, hOldBitmap2);
400 /* delete all temp objects */
401 DeleteObject(hBitmap1);
402 DeleteObject(hBitmap2);
403 DeleteObject(hbrMask);
405 DeleteDC(hDC1);
406 DeleteDC(hDC2);
408 return TRUE;
411 /******************************************************************************
412 * GdiTransparentBlt [GDI32.@]
414 BOOL WINAPI GdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDest, int heightDest,
415 HDC hdcSrc, int xSrc, int ySrc, int widthSrc, int heightSrc,
416 UINT crTransparent )
418 BOOL ret = FALSE;
419 HDC hdcWork;
420 HBITMAP bmpWork;
421 HGDIOBJ oldWork;
422 HDC hdcMask = NULL;
423 HBITMAP bmpMask = NULL;
424 HBITMAP oldMask = NULL;
425 COLORREF oldBackground;
426 COLORREF oldForeground;
427 int oldStretchMode;
429 if(widthDest < 0 || heightDest < 0 || widthSrc < 0 || heightSrc < 0) {
430 TRACE("Cannot mirror\n");
431 return FALSE;
434 oldBackground = SetBkColor(hdcDest, RGB(255,255,255));
435 oldForeground = SetTextColor(hdcDest, RGB(0,0,0));
437 /* Stretch bitmap */
438 oldStretchMode = GetStretchBltMode(hdcSrc);
439 if(oldStretchMode == BLACKONWHITE || oldStretchMode == WHITEONBLACK)
440 SetStretchBltMode(hdcSrc, COLORONCOLOR);
441 hdcWork = CreateCompatibleDC(hdcDest);
442 bmpWork = CreateCompatibleBitmap(hdcDest, widthDest, heightDest);
443 oldWork = SelectObject(hdcWork, bmpWork);
444 if(!StretchBlt(hdcWork, 0, 0, widthDest, heightDest, hdcSrc, xSrc, ySrc, widthSrc, heightSrc, SRCCOPY)) {
445 TRACE("Failed to stretch\n");
446 goto error;
448 SetBkColor(hdcWork, crTransparent);
450 /* Create mask */
451 hdcMask = CreateCompatibleDC(hdcDest);
452 bmpMask = CreateCompatibleBitmap(hdcMask, widthDest, heightDest);
453 oldMask = SelectObject(hdcMask, bmpMask);
454 if(!BitBlt(hdcMask, 0, 0, widthDest, heightDest, hdcWork, 0, 0, SRCCOPY)) {
455 TRACE("Failed to create mask\n");
456 goto error;
459 /* Replace transparent color with black */
460 SetBkColor(hdcWork, RGB(0,0,0));
461 SetTextColor(hdcWork, RGB(255,255,255));
462 if(!BitBlt(hdcWork, 0, 0, widthDest, heightDest, hdcMask, 0, 0, SRCAND)) {
463 TRACE("Failed to mask out background\n");
464 goto error;
467 /* Replace non-transparent area on destination with black */
468 if(!BitBlt(hdcDest, xDest, yDest, widthDest, heightDest, hdcMask, 0, 0, SRCAND)) {
469 TRACE("Failed to clear destination area\n");
470 goto error;
473 /* Draw the image */
474 if(!BitBlt(hdcDest, xDest, yDest, widthDest, heightDest, hdcWork, 0, 0, SRCPAINT)) {
475 TRACE("Failed to paint image\n");
476 goto error;
479 ret = TRUE;
480 error:
481 SetStretchBltMode(hdcSrc, oldStretchMode);
482 SetBkColor(hdcDest, oldBackground);
483 SetTextColor(hdcDest, oldForeground);
484 if(hdcWork) {
485 SelectObject(hdcWork, oldWork);
486 DeleteDC(hdcWork);
488 if(bmpWork) DeleteObject(bmpWork);
489 if(hdcMask) {
490 SelectObject(hdcMask, oldMask);
491 DeleteDC(hdcMask);
493 if(bmpMask) DeleteObject(bmpMask);
494 return ret;
497 /******************************************************************************
498 * GdiAlphaBlend [GDI32.@]
500 BOOL WINAPI GdiAlphaBlend(HDC hdcDst, int xDst, int yDst, int widthDst, int heightDst,
501 HDC hdcSrc, int xSrc, int ySrc, int widthSrc, int heightSrc,
502 BLENDFUNCTION blendFunction)
504 BOOL ret = FALSE;
505 DC *dcDst, *dcSrc;
507 dcSrc = get_dc_ptr( hdcSrc );
508 if ((dcDst = get_dc_ptr( hdcDst )))
510 if (dcSrc) update_dc( dcSrc );
511 update_dc( dcDst );
512 TRACE("%p %d,%d %dx%d -> %p %d,%d %dx%d op=%02x flags=%02x srcconstalpha=%02x alphafmt=%02x\n",
513 hdcSrc, xSrc, ySrc, widthSrc, heightSrc,
514 hdcDst, xDst, yDst, widthDst, heightDst,
515 blendFunction.BlendOp, blendFunction.BlendFlags,
516 blendFunction.SourceConstantAlpha, blendFunction.AlphaFormat);
517 if (dcDst->funcs->pAlphaBlend)
518 ret = dcDst->funcs->pAlphaBlend( dcDst->physDev, xDst, yDst, widthDst, heightDst,
519 dcSrc ? dcSrc->physDev : NULL,
520 xSrc, ySrc, widthSrc, heightSrc, blendFunction );
521 release_dc_ptr( dcDst );
523 if (dcSrc) release_dc_ptr( dcSrc );
524 return ret;
527 /*********************************************************************
528 * PlgBlt [GDI32.@]
531 BOOL WINAPI PlgBlt( HDC hdcDest, const POINT *lpPoint,
532 HDC hdcSrc, INT nXSrc, INT nYSrc, INT nWidth,
533 INT nHeight, HBITMAP hbmMask, INT xMask, INT yMask)
535 int oldgMode;
536 /* parallelogram coords */
537 POINT plg[3];
538 /* rect coords */
539 POINT rect[3];
540 XFORM xf;
541 XFORM SrcXf;
542 XFORM oldDestXf;
543 double det;
545 /* save actual mode, set GM_ADVANCED */
546 oldgMode = SetGraphicsMode(hdcDest,GM_ADVANCED);
547 if (oldgMode == 0)
548 return FALSE;
550 memcpy(plg,lpPoint,sizeof(POINT)*3);
551 rect[0].x = nXSrc;
552 rect[0].y = nYSrc;
553 rect[1].x = nXSrc + nWidth;
554 rect[1].y = nYSrc;
555 rect[2].x = nXSrc;
556 rect[2].y = nYSrc + nHeight;
557 /* calc XFORM matrix to transform hdcDest -> hdcSrc (parallelogram to rectangle) */
558 /* determinant */
559 det = rect[1].x*(rect[2].y - rect[0].y) - rect[2].x*(rect[1].y - rect[0].y) - rect[0].x*(rect[2].y - rect[1].y);
561 if (fabs(det) < 1e-5)
563 SetGraphicsMode(hdcDest,oldgMode);
564 return FALSE;
567 TRACE("hdcSrc=%p %d,%d,%dx%d -> hdcDest=%p %d,%d,%d,%d,%d,%d\n",
568 hdcSrc, nXSrc, nYSrc, nWidth, nHeight, hdcDest, plg[0].x, plg[0].y, plg[1].x, plg[1].y, plg[2].x, plg[2].y);
570 /* X components */
571 xf.eM11 = (plg[1].x*(rect[2].y - rect[0].y) - plg[2].x*(rect[1].y - rect[0].y) - plg[0].x*(rect[2].y - rect[1].y)) / det;
572 xf.eM21 = (rect[1].x*(plg[2].x - plg[0].x) - rect[2].x*(plg[1].x - plg[0].x) - rect[0].x*(plg[2].x - plg[1].x)) / det;
573 xf.eDx = (rect[0].x*(rect[1].y*plg[2].x - rect[2].y*plg[1].x) -
574 rect[1].x*(rect[0].y*plg[2].x - rect[2].y*plg[0].x) +
575 rect[2].x*(rect[0].y*plg[1].x - rect[1].y*plg[0].x)
576 ) / det;
578 /* Y components */
579 xf.eM12 = (plg[1].y*(rect[2].y - rect[0].y) - plg[2].y*(rect[1].y - rect[0].y) - plg[0].y*(rect[2].y - rect[1].y)) / det;
580 xf.eM22 = (plg[1].x*(rect[2].y - rect[0].y) - plg[2].x*(rect[1].y - rect[0].y) - plg[0].x*(rect[2].y - rect[1].y)) / det;
581 xf.eDy = (rect[0].x*(rect[1].y*plg[2].y - rect[2].y*plg[1].y) -
582 rect[1].x*(rect[0].y*plg[2].y - rect[2].y*plg[0].y) +
583 rect[2].x*(rect[0].y*plg[1].y - rect[1].y*plg[0].y)
584 ) / det;
586 GetWorldTransform(hdcSrc,&SrcXf);
587 CombineTransform(&xf,&xf,&SrcXf);
589 /* save actual dest transform */
590 GetWorldTransform(hdcDest,&oldDestXf);
592 SetWorldTransform(hdcDest,&xf);
593 /* now destination and source DCs use same coords */
594 MaskBlt(hdcDest,nXSrc,nYSrc,nWidth,nHeight,
595 hdcSrc, nXSrc,nYSrc,
596 hbmMask,xMask,yMask,
597 SRCCOPY);
598 /* restore dest DC */
599 SetWorldTransform(hdcDest,&oldDestXf);
600 SetGraphicsMode(hdcDest,oldgMode);
602 return TRUE;