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; > } > > >