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