Hello Nikolay, thanks for the patch. Nikolay Sivov wrote:
Changelog: gdi32: initial implementation using coord transformation and MaskBlt patch is made in Windows using TortoiseCVS functionality (all that I can use at this moment, shouldn't be a problem I hope) No that's not a problem as long as you do the cvs diff from the top level wine directory.
Please do not use C++ style comments but the traditional /* */. bye michael
Index: bitblt.c =================================================================== RCS file: /home/wine/wine/dlls/gdi32/bitblt.c,v retrieving revision 1.4 diff -u -r1.4 bitblt.c --- bitblt.c 18 Sep 2007 10:32:56 -0000 1.4 +++ bitblt.c 26 Mar 2008 21:19:31 -0000 @@ -26,6 +26,9 @@ #include "gdi_private.h" #include "wine/debug.h"
+#include <math.h> +#include <float.h> + WINE_DEFAULT_DEBUG_CHANNEL(bitblt);
@@ -522,9 +525,72 @@ * */ BOOL WINAPI PlgBlt( HDC hdcDest, const POINT *lpPoint, - HDC hdcSrc, INT nXDest, INT nYDest, INT nWidth, + HDC hdcSrc, INT nXSrc, INT nYSrc, INT nWidth, INT nHeight, HBITMAP hbmMask, INT xMask, INT yMask) { - FIXME("PlgBlt, stub\n"); - return 1; + //save actual mode, set GM_ADVANCED + int oldgMode = SetGraphicsMode(hdcDest,GM_ADVANCED); + if (oldgMode == 0) + return FALSE; + + //parallelogram coords + POINT plg[3]; + memcpy(plg,lpPoint,sizeof(POINT)*3); + //rect coords + POINT rect[3]; + rect[0].x = nXSrc; + rect[0].y = nYSrc; + rect[1].x = nXSrc + nWidth; + rect[1].y = nYSrc; + rect[2].x = nXSrc; + rect[2].y = nYSrc + nHeight; + //calc XFORM matrix to transform hdcDest -> hdcSrc (parallelogram to rectangle) + XFORM xf; + //determinant + FLOAT 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)); + + if (fabs(det) < FLT_EPSILON) + { + SetGraphicsMode(hdcDest,oldgMode); + return FALSE; + } + + TRACE("hdcSrc=%p %d,%d,%dx%d -> hdcDest=%p %d,%d,%d,%d,%d,%d\n", + hdcSrc, nXSrc, nYSrc, nWidth, nHeight, hdcDest, plg[0].x, plg[0].y, plg[1].x, plg[1].y, plg[2].x, plg[2].y); + + //X components + 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; + 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; + xf.eDx = (rect[0].x*(rect[1].y*plg[2].x - rect[2].y*plg[1].x) - + rect[1].x*(rect[0].y*plg[2].x - rect[2].y*plg[0].x) + + rect[2].x*(rect[0].y*plg[1].x - rect[1].y*plg[0].x) + ) / det; + + //Y components + 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; + 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; + xf.eDy = (rect[0].x*(rect[1].y*plg[2].y - rect[2].y*plg[1].y) - + rect[1].x*(rect[0].y*plg[2].y - rect[2].y*plg[0].y) + + rect[2].x*(rect[0].y*plg[1].y - rect[1].y*plg[0].y) + ) / det; + + XFORM SrcXf; + GetWorldTransform(hdcSrc,&SrcXf); + CombineTransform(&xf,&xf,&SrcXf); + + //save actual dest transform + XFORM oldDestXf; + GetWorldTransform(hdcDest,&oldDestXf); + // + SetWorldTransform(hdcDest,&xf); + //now destination and source DCs use same coords + MaskBlt(hdcDest,nXSrc,nYSrc,nWidth,nHeight, + hdcSrc, nXSrc,nYSrc, + hbmMask,xMask,yMask, + SRCCOPY); + //restore dest DC + SetWorldTransform(hdcDest,&oldDestXf); + SetGraphicsMode(hdcDest,oldgMode); + + return TRUE; }