File 0001-Fix-of-GM_ADVANCED-rotation-problems-in-postscript-d.patch of Package wine

From 3f250071dfdf049affc28b6f35197075917e717e Mon Sep 17 00:00:00 2001
From: Ralf Habacker <ralf.habacker@freenet.de>
Date: Thu, 6 Feb 2014 10:25:32 +0100
Subject: [PATCH] Fix of GM_ADVANCED rotation problems in postscript driver.

Because gdi currently do not display rotated graphic elements correctly,
the postscript driver writes the transformation matrix directly into the
postscript output and let the GDI think, that it should draw unrotated.

Limitations: GetTransform() returns identity matrix when requesting
world2Vport and vport2World matrices.
A fix requires:
1. to add a pGetTransform entry in the driver function table
2. PSDRV_SetWorldTransform has to call nulldrv_setWorldTransform() and
   afterwards save and reset the internal transformations matrixes.
3. A new function PSDRV_GetTransform returns the saved matrixes.
---
 dlls/wineps.drv/Makefile.in |  1 +
 dlls/wineps.drv/clipping.c  |  1 +
 dlls/wineps.drv/init.c      |  4 +--
 dlls/wineps.drv/ps.c        | 80 +++++++++++++++++++++++++++++++++++++++++++++
 dlls/wineps.drv/psdrv.h     |  3 ++
 5 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/dlls/wineps.drv/Makefile.in b/dlls/wineps.drv/Makefile.in
index c7282d8..1526df3 100644
--- a/dlls/wineps.drv/Makefile.in
+++ b/dlls/wineps.drv/Makefile.in
@@ -1,5 +1,6 @@
 MODULE    = wineps.drv
 IMPORTS   = user32 gdi32 winspool advapi32
+EXTRAINCL = -I$(top_srcdir)/dlls
 
 C_SRCS = \
 	afm.c \
diff --git a/dlls/wineps.drv/clipping.c b/dlls/wineps.drv/clipping.c
index 59c8817..c3ccda0 100644
--- a/dlls/wineps.drv/clipping.c
+++ b/dlls/wineps.drv/clipping.c
@@ -62,6 +62,7 @@ void PSDRV_AddClip( PHYSDEV dev, HRGN hrgn )
         PSDRV_WriteRectClip2(dev, szArrayName);
         break;
     }
+    PSDRV_WriteWorldTransform( dev );
     HeapFree( GetProcessHeap(), 0, data );
 }
 
diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c
index ec98f04..d6f79df 100644
--- a/dlls/wineps.drv/init.c
+++ b/dlls/wineps.drv/init.c
@@ -881,7 +881,7 @@ static const struct gdi_dc_funcs psdrv_funcs =
     NULL,                               /* pIntersectClipRect */
     NULL,                               /* pInvertRgn */
     PSDRV_LineTo,                       /* pLineTo */
-    NULL,                               /* pModifyWorldTransform */
+    PSDRV_ModifyWorldTransform,         /* pModifyWorldTransform */
     NULL,                               /* pMoveTo */
     NULL,                               /* pOffsetClipRgn */
     NULL,                               /* pOffsetViewportOrg */
@@ -938,7 +938,7 @@ static const struct gdi_dc_funcs psdrv_funcs =
     NULL,                               /* pSetViewportOrg */
     NULL,                               /* pSetWindowExt */
     NULL,                               /* pSetWindowOrg */
-    NULL,                               /* pSetWorldTransform */
+    PSDRV_SetWorldTransform,            /* pSetWorldTransform */
     PSDRV_StartDoc,                     /* pStartDoc */
     PSDRV_StartPage,                    /* pStartPage */
     NULL,                               /* pStretchBlt */
diff --git a/dlls/wineps.drv/ps.c b/dlls/wineps.drv/ps.c
index 6187223..fa53edd 100644
--- a/dlls/wineps.drv/ps.c
+++ b/dlls/wineps.drv/ps.c
@@ -31,6 +31,7 @@
 #include "winbase.h"
 #include "wingdi.h"
 #include "psdrv.h"
+#include "gdi32/gdi_private.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
@@ -92,6 +93,9 @@ static const char psendfeature[] =
 "\n%%EndFeature\n"
 "} stopped cleartomark\n";
 
+static const char pssettransform[] = /* eM11, eM12, eM21, eM22, eDx, eDy */
+"[%f %f %f %f %f %f] concat\n";
+
 static const char psnewpage[] = /* name, number, xres, yres, xtrans, ytrans, rot */
 "%%%%Page: %s %d\n"
 "%%%%BeginPageSetup\n"
@@ -469,8 +473,84 @@ INT PSDRV_WriteEndPage( PHYSDEV dev )
     return 1;
 }
 
+static inline DC *_get_nulldrv_dc( PHYSDEV dev )
+{
+    return CONTAINING_RECORD( dev, DC, nulldrv );
+}
+
+static inline PHYSDEV find_null_driver( PHYSDEV dev )
+{
+    while (dev) {
+        if (dev->funcs->priority == 0)
+            return dev;
+        dev = dev->next;
+    }
+    return 0;
+}
+
+BOOL PSDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode )
+{
+    PHYSDEV nulldrv = find_null_driver( dev );
+    DC *dc = _get_nulldrv_dc( nulldrv );
 
+    switch (mode)
+    {
+    case MWT_IDENTITY:
+        dc->xformWorld2Wnd.eM11 = 1.0f;
+        dc->xformWorld2Wnd.eM12 = 0.0f;
+        dc->xformWorld2Wnd.eM21 = 0.0f;
+        dc->xformWorld2Wnd.eM22 = 1.0f;
+        dc->xformWorld2Wnd.eDx  = 0.0f;
+        dc->xformWorld2Wnd.eDy  = 0.0f;
+        break;
+    case MWT_LEFTMULTIPLY:
+        CombineTransform( &dc->xformWorld2Wnd, xform, &dc->xformWorld2Wnd );
+        break;
+    case MWT_RIGHTMULTIPLY:
+        CombineTransform( &dc->xformWorld2Wnd, &dc->xformWorld2Wnd, xform );
+        break;
+    default:
+        return FALSE;
+    }
+    /* We write the transform and unrotated graphical elements into the
+     * postscript output and do not want the transform to be applied.
+     * DC_UpdateXforms( dc ); */
+    return TRUE;
+}
+
+BOOL PSDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform )
+{
+    PHYSDEV nulldrv = find_null_driver( dev );
+    DC *dc = _get_nulldrv_dc( nulldrv );
+    dc->xformWorld2Wnd = *xform;
+    return TRUE;
+}
 
+BOOL PSDRV_WriteWorldTransform( PHYSDEV dev )
+{
+    PHYSDEV nulldrv = find_null_driver( dev );
+    DC *dc = _get_nulldrv_dc( nulldrv );
+    char *buf;
+
+    XFORM *xform  = &dc->xformWorld2Wnd;
+
+    buf = HeapAlloc( GetProcessHeap(), 0, sizeof(pssettransform) + 200 );
+    if(!buf) {
+        WARN("HeapAlloc failed\n");
+        return 0;
+    }
+
+    sprintf(buf, pssettransform, xform->eM11, xform->eM12, xform->eM21, xform->eM22, xform->eDx, xform->eDy);
+
+    if( write_spool( dev, buf, strlen(buf) ) != strlen(buf) ) {
+        WARN("WriteSpool error\n");
+        HeapFree( GetProcessHeap(), 0, buf );
+        return 0;
+    }
+
+    HeapFree( GetProcessHeap(), 0, buf );
+    return 1;
+}
 
 INT PSDRV_WriteNewPage( PHYSDEV dev )
 {
diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h
index 229d04c..db7e9dc 100644
--- a/dlls/wineps.drv/psdrv.h
+++ b/dlls/wineps.drv/psdrv.h
@@ -438,6 +438,7 @@ extern BOOL PSDRV_GetCharWidth(PHYSDEV dev, UINT firstChar, UINT lastChar, LPINT
 extern BOOL PSDRV_GetTextExtentExPoint(PHYSDEV dev, LPCWSTR str, INT count, LPINT alpDx) DECLSPEC_HIDDEN;
 extern BOOL PSDRV_GetTextMetrics(PHYSDEV dev, TEXTMETRICW *metrics) DECLSPEC_HIDDEN;
 extern BOOL PSDRV_LineTo(PHYSDEV dev, INT x, INT y) DECLSPEC_HIDDEN;
+extern BOOL PSDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode );
 extern BOOL PSDRV_PaintRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
 extern BOOL PSDRV_PatBlt(PHYSDEV dev, struct bitblt_coords *dst, DWORD dwRop) DECLSPEC_HIDDEN;
 extern BOOL PSDRV_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
@@ -460,6 +461,7 @@ extern COLORREF PSDRV_SetDCBrushColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HI
 extern COLORREF PSDRV_SetDCPenColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
 extern COLORREF PSDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color ) DECLSPEC_HIDDEN;
 extern COLORREF PSDRV_SetTextColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
+extern BOOL PSDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform ) DECLSPEC_HIDDEN;
 extern INT PSDRV_StartDoc( PHYSDEV dev, const DOCINFOW *doc ) DECLSPEC_HIDDEN;
 extern BOOL PSDRV_StrokeAndFillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
 extern BOOL PSDRV_StrokePath( PHYSDEV dev ) DECLSPEC_HIDDEN;
@@ -532,6 +534,7 @@ extern DWORD PSDRV_WriteSpool(PHYSDEV dev, LPCSTR lpData, DWORD cch) DECLSPEC_HI
 extern BOOL PSDRV_WriteDIBPatternDict(PHYSDEV dev, const BITMAPINFO *bmi, BYTE *bits, UINT usage) DECLSPEC_HIDDEN;
 extern BOOL PSDRV_WriteArrayPut(PHYSDEV dev, CHAR *pszArrayName, INT nIndex, LONG lCoord) DECLSPEC_HIDDEN;
 extern BOOL PSDRV_WriteArrayDef(PHYSDEV dev, CHAR *pszArrayName, INT nSize) DECLSPEC_HIDDEN;
+extern BOOL PSDRV_WriteWorldTransform( PHYSDEV dev ) DECLSPEC_HIDDEN;
 
 extern INT PSDRV_StartPage( PHYSDEV dev ) DECLSPEC_HIDDEN;
 
-- 
1.8.4
openSUSE Build Service is sponsored by