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;
}
One more comment on your patch:
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];
Variables must be declared at the beginning of the function. We require strict ANSI C. --Juan