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