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