gdi32: PlgBlt implementation

Michael Stefaniuc mstefani at redhat.com
Wed Mar 26 16:47:49 CDT 2008


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




More information about the wine-devel mailing list