wineps.drv: better clipping; thereby fix bug (wrong clipping)

Wolfgang Walter wine at stwm.de
Mon Dec 8 10:51:19 CST 2008


Hello,

wineps sets the clipping path of the drawing conext leads for each
time a drawing function was invoked.

Modifing the clipping path is a very expensive operation. Doing this for every
drawing function makes postscript pinters very slow even if only a simple but
large clipping region for the DC is set. They need several minutes to print
one page.

Another problem is that wineps does not set a correct clipping region: it
ignores the MetaRegion set by the application.

The following three patches try to handle clipping differently

* the clipping path is set when gdi calls PSDRV_SetDeviceClipping

* a new page always immediately does a gsave after setting the
page specific settings

* to set the clipping path to the one valid when the page was startet a
grestore/gsave done.

* its not quite clear how to cooperate best with EscEscape's CLIP_xxxx
But I think its now what it should be

* In passthrough mode clipping is switch off


The signature of PSDRV_SetDeviceClipping is wrong: it should be
PSDRV_SetDeviceClipping( PSDRV_PDEVICE *physDev, HRGN vis_rgn, HRGN clip_rgn );




Regards,
Wolfgang Walter
Studentenwerk München
Anstalt des öffentlichen Rechts
Leiter EDV
Leopoldstraße 15
80802 München


From a835e2568a01e663ceda6cadb2562d3e35424313 Mon Sep 17 00:00:00 2001
From: Wolfgang Walter <wine at stwm.de>
Date: Mon, 8 Dec 2008 02:58:37 +0100
Subject: Modify how clipping is managed

The old method was to set the clipping path from the drawing conext for each
time a drawing function was invoked.

Modifing the clipping path is a very expensive operation. Doing this for every
drawing function makes postscript pinters very slow even if only a simple but
large clipping region for the DC is set.

This is patch tries to handle this differently:

* the clipping path is set when gdi calls PSDRV_SetDeviceClipping

* to set the clipping path to the one valid when the page was startet a
grestore done.

We may should do a grestorall instead but

* its not quite clear how to cooperate best with EscEscape's CLIP_xxxx
---
 dlls/wineps.drv/clipping.c |  200 +++++++++++++++++++++++++++----------------
 dlls/wineps.drv/escape.c   |   11 ++-
 dlls/wineps.drv/ps.c       |    3 +
 dlls/wineps.drv/psdrv.h    |    7 ++
 4 files changed, 142 insertions(+), 79 deletions(-)

diff --git a/dlls/wineps.drv/clipping.c b/dlls/wineps.drv/clipping.c
index 3540b76..caad692 100644
--- a/dlls/wineps.drv/clipping.c
+++ b/dlls/wineps.drv/clipping.c
@@ -24,112 +24,162 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
 
-/***********************************************************************
- *           PSDRV_SetDeviceClipping
- */
-void PSDRV_SetDeviceClipping( PSDRV_PDEVICE *physDev, HRGN vis_rgn, HRGN clip_rgn )
-{
-    /* We could set a dirty flag here to speed up PSDRV_SetClip */
-    return;
-}
 
 /***********************************************************************
- *           PSDRV_SetClip
- *
- * The idea here is that every graphics operation should bracket
- * output in PSDRV_SetClip/ResetClip calls.  The clip path outside
- * these calls will be empty; the reason for this is that it is
- * impossible in PostScript to cleanly make the clip path larger than
- * the current one.  Also Photoshop assumes that despite having set a
- * small clip area in the printer dc that it can still write raw
- * PostScript to the driver and expect this code not to be clipped.
+ *           PSDRV_SetDeviceClipping
  */
-void PSDRV_SetClip( PSDRV_PDEVICE *physDev )
+void PSDRV_SetDeviceClipping( PSDRV_PDEVICE *physDev, HRGN hrgn )
 {
-    CHAR szArrayName[] = "clippath";
+    CHAR szArrayName[] = "WineClippingPathDC";
     DWORD size;
     RGNDATA *rgndata = NULL;
-    HRGN hrgn = CreateRectRgn(0,0,0,0);
-    BOOL empty;
 
     TRACE("hdc=%p\n", physDev->hdc);
 
     if(physDev->pathdepth) {
         TRACE("inside a path, so not clipping\n");
-        goto end;
+        return;
     }
 
-    empty = !GetClipRgn(physDev->hdc, hrgn);
+    PSDRV_ClippingOff(physDev);
 
-    if(!empty) {
-        size = GetRegionData(hrgn, 0, NULL);
-        if(!size) {
-            ERR("Invalid region\n");
-            goto end;
-        }
+    if (!hrgn)
+       return;
 
-        rgndata = HeapAlloc( GetProcessHeap(), 0, size );
-        if(!rgndata) {
-            ERR("Can't allocate buffer\n");
-            goto end;
-        }
+    size = GetRegionData(hrgn, 0, NULL);
+    if(!size) {
+        ERR("Invalid region\n");
+        return;
+    }
 
-        GetRegionData(hrgn, size, rgndata);
+    rgndata = HeapAlloc( GetProcessHeap(), 0, size );
+    if(!rgndata) {
+        ERR("Can't allocate buffer\n");
+        goto end;
+    }
+    GetRegionData(hrgn, size, rgndata);
 
-        PSDRV_WriteGSave(physDev);
+    /* check for NULL region */
+    if (rgndata->rdh.nCount == 0)
+    {
+        /* set an empty clip path. */
+        PSDRV_WriteRectClip(physDev, 0, 0, 0, 0);
+    }
+    /* optimize when it is a simple region */
+    else if (rgndata->rdh.nCount == 1)
+    {
+        RECT *pRect = (RECT *)rgndata->Buffer;
+
+        PSDRV_WriteRectClip(physDev, pRect->left, pRect->top,
+                            pRect->right - pRect->left,
+                            pRect->bottom - pRect->top);
+    }
+    else
+    {
+        UINT i;
+        RECT *pRect = (RECT *)rgndata->Buffer;
 
-        /* check for NULL region */
-        if (rgndata->rdh.nCount == 0)
-        {
-            /* set an empty clip path. */
-            PSDRV_WriteRectClip(physDev, 0, 0, 0, 0);
-        }
-        /* optimize when it is a simple region */
-        else if (rgndata->rdh.nCount == 1)
-        {
-            RECT *pRect = (RECT *)rgndata->Buffer;
+        PSDRV_WriteArrayDef(physDev, szArrayName, rgndata->rdh.nCount * 4);
 
-            PSDRV_WriteRectClip(physDev, pRect->left, pRect->top,
-                                pRect->right - pRect->left,
-                                pRect->bottom - pRect->top);
-        }
-        else
+        for (i = 0; i < rgndata->rdh.nCount; i++, pRect++)
         {
-            UINT i;
-            RECT *pRect = (RECT *)rgndata->Buffer;
-
-            PSDRV_WriteArrayDef(physDev, szArrayName, rgndata->rdh.nCount * 4);
-
-            for (i = 0; i < rgndata->rdh.nCount; i++, pRect++)
-            {
-                PSDRV_WriteArrayPut(physDev, szArrayName, i * 4,
-                                    pRect->left);
-                PSDRV_WriteArrayPut(physDev, szArrayName, i * 4 + 1,
-                                    pRect->top);
-                PSDRV_WriteArrayPut(physDev, szArrayName, i * 4 + 2,
-                                    pRect->right - pRect->left);
-                PSDRV_WriteArrayPut(physDev, szArrayName, i * 4 + 3,
-                                    pRect->bottom - pRect->top);
-            }
-            PSDRV_WriteRectClip2(physDev, szArrayName);
+            PSDRV_WriteArrayPut(physDev, szArrayName, i * 4,
+                                pRect->left);
+            PSDRV_WriteArrayPut(physDev, szArrayName, i * 4 + 1,
+                                pRect->top);
+            PSDRV_WriteArrayPut(physDev, szArrayName, i * 4 + 2,
+                                pRect->right - pRect->left);
+            PSDRV_WriteArrayPut(physDev, szArrayName, i * 4 + 3,
+                                pRect->bottom - pRect->top);
         }
+        PSDRV_WriteRectClip2(physDev, szArrayName);
     }
 end:
     HeapFree( GetProcessHeap(), 0, rgndata );
+}
+
+/***********************************************************************
+ *           PSDRV_SetDeviceClippingFromDC
+ *
+ */
+void PSDRV_SetDeviceClippingFromDC( PSDRV_PDEVICE *physDev )
+{
+    HRGN hrgn;
+
+    TRACE("hdc=%p\n", physDev->hdc);
+
+    hrgn = CreateRectRgn(0,0,0,0);
+    GetRandomRgn(physDev->hdc, hrgn, 3);
+    PSDRV_SetDeviceClipping(physDev, hrgn);
     DeleteObject(hrgn);
 }
 
+/***********************************************************************
+ *           PSDRV_ClippingOn( PSDRV_PDEVICE *physDev )
+ *
+ */
+void PSDRV_ClippingOn( PSDRV_PDEVICE *physDev )
+{
+    TRACE("hdc=%p\n", physDev->hdc);
+
+    PSDRV_SetDeviceClippingFromDC(physDev);
+}
+
+/***********************************************************************
+ *           PSDRV_ClippingOff( PSDRV_PDEVICE *physDev )
+ *
+ */
+void PSDRV_ClippingOff( PSDRV_PDEVICE *physDev )
+{
+    TRACE("hdc=%p\n", physDev->hdc);
+
+    PSDRV_WriteGRestore(physDev);
+    PSDRV_WriteGSave(physDev);
+
+    physDev->brush.set = FALSE;
+    physDev->font.set = FALSE;
+    physDev->pen.set = FALSE;
+
+}
+
+/***********************************************************************
+ *           PSDRV_ClippingEscSave
+ *
+ */
+void PSDRV_ClippingEscSave( PSDRV_PDEVICE *physDev )
+{
+    PSDRV_WriteGSave(physDev);
+}
+
+/***********************************************************************
+ *           PSDRV_ClippingEscRestore
+ *
+ */
+void PSDRV_ClippingEscRestore( PSDRV_PDEVICE *physDev )
+{
+    PSDRV_WriteGRestore(physDev);
+}
+
+/***********************************************************************
+ *           PSDRV_ClippingEscSet
+ *
+ */
+void PSDRV_ClippingEscSet( PSDRV_PDEVICE *physDev, WORD mode )
+{
+    PSDRV_WriteClip(physDev);
+}
+
+/***********************************************************************
+ *           PSDRV_SetClip
+ *
+ */
+void PSDRV_SetClip( PSDRV_PDEVICE *physDev)
+{
+}
 
 /***********************************************************************
  *           PSDRV_ResetClip
  */
 void PSDRV_ResetClip( PSDRV_PDEVICE *physDev )
 {
-    HRGN hrgn = CreateRectRgn(0,0,0,0);
-    BOOL empty;
-
-    empty = !GetClipRgn(physDev->hdc, hrgn);
-    if(!empty && !physDev->pathdepth)
-        PSDRV_WriteGRestore(physDev);
-    DeleteObject(hrgn);
 }
diff --git a/dlls/wineps.drv/escape.c b/dlls/wineps.drv/escape.c
index b397461..bfa4976 100644
--- a/dlls/wineps.drv/escape.c
+++ b/dlls/wineps.drv/escape.c
@@ -87,11 +87,13 @@ INT PSDRV_ExtEscape( PSDRV_PDEVICE *physDev, INT nEscape, INT cbInput, LPCVOID i
     {
 	DRAWPATRECT	*dpr = (DRAWPATRECT*)in_data;
 
+        PSDRV_ClippingOff(physDev);
 	FIXME("DRAWPATTERNRECT(pos (%d,%d), size %dx%d, style %d, pattern %x), stub!\n",
 		dpr->ptPosition.x, dpr->ptPosition.y,
 		dpr->ptSize.x, dpr->ptSize.y,
 		dpr->wStyle, dpr->wPattern
 	);
+        PSDRV_ClippingOn(physDev);
 	return 1;
     }
     case BANDINFO:
@@ -252,6 +254,7 @@ INT PSDRV_ExtEscape( PSDRV_PDEVICE *physDev, INT nEscape, INT cbInput, LPCVOID i
              * in_data[0] instead.
              */
             if(!physDev->job.in_passthrough) {
+                PSDRV_ClippingOff(physDev);
                 WriteSpool16(physDev->job.hJob, (LPSTR)psbegindocument, sizeof(psbegindocument)-1);
                 physDev->job.in_passthrough = TRUE;
             }
@@ -287,7 +290,7 @@ INT PSDRV_ExtEscape( PSDRV_PDEVICE *physDev, INT nEscape, INT cbInput, LPCVOID i
 
 	TRACE("END_PATH\n");
         if(!physDev->pathdepth) {
-	    ERR("END_PATH called without a BEIGN_PATH\n");
+	    ERR("END_PATH called without a BEGIN_PATH\n");
 	    return -1;
 	}
 	TRACE("RenderMode = %d, FillMode = %d, BkMode = %d\n",
@@ -312,16 +315,16 @@ INT PSDRV_ExtEscape( PSDRV_PDEVICE *physDev, INT nEscape, INT cbInput, LPCVOID i
 	switch(mode) {
 	case CLIP_SAVE:
 	    TRACE("CLIP_TO_PATH: CLIP_SAVE\n");
-	    PSDRV_WriteGSave(physDev);
+            PSDRV_ClippingEscSave(physDev);
 	    return 1;
 	case CLIP_RESTORE:
 	    TRACE("CLIP_TO_PATH: CLIP_RESTORE\n");
-	    PSDRV_WriteGRestore(physDev);
+            PSDRV_ClippingEscRestore(physDev);
 	    return 1;
 	case CLIP_INCLUSIVE:
 	    TRACE("CLIP_TO_PATH: CLIP_INCLUSIVE\n");
 	    /* FIXME to clip or eoclip ? (see PATH_INFO.FillMode) */
-	    PSDRV_WriteClip(physDev);
+            PSDRV_ClippingEscSet(physDev, CLIP_INCLUSIVE);
             PSDRV_WriteNewPath(physDev);
 	    return 1;
 	case CLIP_EXCLUSIVE:
diff --git a/dlls/wineps.drv/ps.c b/dlls/wineps.drv/ps.c
index fdebf46..27a3fc7 100644
--- a/dlls/wineps.drv/ps.c
+++ b/dlls/wineps.drv/ps.c
@@ -211,6 +211,9 @@ DWORD PSDRV_WriteSpool(PSDRV_PDEVICE *physDev, LPCSTR lpData, DWORD cch)
     if(physDev->job.in_passthrough) { /* Was in PASSTHROUGH mode */
         WriteSpool16( physDev->job.hJob, (LPSTR)psenddocument, sizeof(psenddocument)-1 );
         physDev->job.in_passthrough = physDev->job.had_passthrough_rect = FALSE;
+        /* ATTENTION: this will call PSDRV_WriteSpool again
+           it's vital that physDev->job.in_passthrough is now FALSE */
+        PSDRV_ClippingOn(physDev);
     }
 
     if(physDev->job.OutOfPage) { /* Will get here after NEWFRAME Escape */
diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h
index fcdc78d..37ed42d 100644
--- a/dlls/wineps.drv/psdrv.h
+++ b/dlls/wineps.drv/psdrv.h
@@ -421,6 +421,13 @@ extern BOOL PSDRV_Brush(PSDRV_PDEVICE *physDev, BOOL EO);
 extern BOOL PSDRV_SetFont( PSDRV_PDEVICE *physDev );
 extern BOOL PSDRV_SetPen( PSDRV_PDEVICE *physDev );
 
+void PSDRV_SetDeviceClippingFromDC( PSDRV_PDEVICE *physDev );
+void PSDRV_ClippingOn( PSDRV_PDEVICE *physDev );
+void PSDRV_ClippingOff( PSDRV_PDEVICE *physDev );
+void PSDRV_ClippingEscSave( PSDRV_PDEVICE *physDev );
+void PSDRV_ClippingEscRestore( PSDRV_PDEVICE *physDev );
+void PSDRV_ClippingEscSet( PSDRV_PDEVICE *physDev, WORD mode );
+
 extern void PSDRV_SetClip(PSDRV_PDEVICE* phyDev);
 extern void PSDRV_ResetClip(PSDRV_PDEVICE* phyDev);
 
-- 
1.5.6.5


From 4e48d5973bba59f3cd20b6bbca224037e17f6474 Mon Sep 17 00:00:00 2001
From: Wolfgang Walter <wine at stwm.de>
Date: Mon, 8 Dec 2008 03:27:05 +0100
Subject: Detect if clipping path does not really change; fix signature of PSDRV_SetDeviceClipping; fix missing gsave

1) Try to detect if clipping path is unchanged even if PSDRV_SetDeviceClipping
is called:

keep last used region data and compare it with the new one

There are some edge cases:

* unset clipping

* there was no clipping bevor

* region data is not valid any more (ClippingOff() was called, i.e.)

2) PSDRV_SetDeviceClipping had wrong signature

Gets to region handles: one vor visible area and one for combined
meta/clipping region.

Ignore visible area for the moment as this seems just to be page bounderies.

3) We need to store the graphic state after page has been set up and always do
grestore/gsave in PSDRV_ClippingOff of. Otherwise we destroy the page
settings.
---
 dlls/wineps.drv/clipping.c |  141 ++++++++++++++++++++++++++-----------------
 dlls/wineps.drv/escape.c   |    3 +
 dlls/wineps.drv/init.c     |    3 +
 dlls/wineps.drv/ps.c       |    1 +
 dlls/wineps.drv/psdrv.h    |   14 +++--
 5 files changed, 100 insertions(+), 62 deletions(-)

diff --git a/dlls/wineps.drv/clipping.c b/dlls/wineps.drv/clipping.c
index caad692..3bebbc4 100644
--- a/dlls/wineps.drv/clipping.c
+++ b/dlls/wineps.drv/clipping.c
@@ -28,11 +28,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
 /***********************************************************************
  *           PSDRV_SetDeviceClipping
  */
-void PSDRV_SetDeviceClipping( PSDRV_PDEVICE *physDev, HRGN hrgn )
+void PSDRV_SetDeviceClipping( PSDRV_PDEVICE *physDev, HRGN vis_rgn, HRGN clip_rgn )
 {
     CHAR szArrayName[] = "WineClippingPathDC";
-    DWORD size;
     RGNDATA *rgndata = NULL;
+    RGNDATA *rgndata_set = physDev->dc_rgndata_set;
+    BOOL valid = physDev->dc_rgndata_valid;
+    HRGN hrgn = clip_rgn;
 
     TRACE("hdc=%p\n", physDev->hdc);
 
@@ -41,61 +43,84 @@ void PSDRV_SetDeviceClipping( PSDRV_PDEVICE *physDev, HRGN hrgn )
         return;
     }
 
-    PSDRV_ClippingOff(physDev);
-
-    if (!hrgn)
-       return;
-
-    size = GetRegionData(hrgn, 0, NULL);
-    if(!size) {
-        ERR("Invalid region\n");
-        return;
-    }
-
-    rgndata = HeapAlloc( GetProcessHeap(), 0, size );
-    if(!rgndata) {
-        ERR("Can't allocate buffer\n");
-        goto end;
-    }
-    GetRegionData(hrgn, size, rgndata);
-
-    /* check for NULL region */
-    if (rgndata->rdh.nCount == 0)
-    {
-        /* set an empty clip path. */
-        PSDRV_WriteRectClip(physDev, 0, 0, 0, 0);
-    }
-    /* optimize when it is a simple region */
-    else if (rgndata->rdh.nCount == 1)
-    {
-        RECT *pRect = (RECT *)rgndata->Buffer;
-
-        PSDRV_WriteRectClip(physDev, pRect->left, pRect->top,
-                            pRect->right - pRect->left,
-                            pRect->bottom - pRect->top);
+    if (!hrgn) {
+        if (physDev->dc_rgndata_set)
+           valid = FALSE;
+    } else {
+        DWORD size;
+        size = GetRegionData(hrgn, 0, NULL);
+        if(!size) {
+            ERR("Invalid region\n");
+            return;
+        }
+        rgndata = HeapAlloc( PSDRV_Heap, 0, size );
+        if(!rgndata) {
+            ERR("Can't allocate buffer\n");
+            return;
+        }
+        GetRegionData(hrgn, size, rgndata);
+
+        if (rgndata_set) {
+            if (valid && rgndata->rdh.nCount == rgndata_set->rdh.nCount) {
+                UINT i;
+                RECT *pRect = (RECT *)rgndata->Buffer;
+                RECT *pRectSet = (RECT *)rgndata_set->Buffer;
+                for (i = 0; i < rgndata->rdh.nCount && valid; i++, pRect++, pRectSet++) {
+                    if (pRect->left != pRectSet->left ||
+                        pRect->top != pRectSet->top ||
+                        pRect->right != pRectSet->right ||
+                        pRect->bottom != pRectSet->bottom)
+                        valid = FALSE;
+                }
+            }
+        } else {
+            valid = FALSE;
+        }
     }
-    else
-    {
-        UINT i;
-        RECT *pRect = (RECT *)rgndata->Buffer;
-
-        PSDRV_WriteArrayDef(physDev, szArrayName, rgndata->rdh.nCount * 4);
-
-        for (i = 0; i < rgndata->rdh.nCount; i++, pRect++)
-        {
-            PSDRV_WriteArrayPut(physDev, szArrayName, i * 4,
-                                pRect->left);
-            PSDRV_WriteArrayPut(physDev, szArrayName, i * 4 + 1,
-                                pRect->top);
-            PSDRV_WriteArrayPut(physDev, szArrayName, i * 4 + 2,
-                                pRect->right - pRect->left);
-            PSDRV_WriteArrayPut(physDev, szArrayName, i * 4 + 3,
-                                pRect->bottom - pRect->top);
+    if (!valid) {
+        PSDRV_ClippingOff(physDev);
+
+        if (rgndata) {
+            /* check for NULL region */
+            if (rgndata->rdh.nCount == 0)
+            {
+                /* set an empty clip path. */
+                PSDRV_WriteRectClip(physDev, 0, 0, 0, 0);
+            }
+            /* optimize when it is a simple region */
+            else if (rgndata->rdh.nCount == 1)
+            {
+                RECT *pRect = (RECT *)rgndata->Buffer;
+
+                PSDRV_WriteRectClip(physDev, pRect->left, pRect->top,
+                                    pRect->right - pRect->left,
+                                    pRect->bottom - pRect->top);
+            }
+            else
+            {
+                UINT i;
+                RECT *pRect = (RECT *)rgndata->Buffer;
+        
+                PSDRV_WriteArrayDef(physDev, szArrayName, rgndata->rdh.nCount * 4);
+        
+                for (i = 0; i < rgndata->rdh.nCount; i++, pRect++)
+                {
+                    PSDRV_WriteArrayPut(physDev, szArrayName, i * 4,
+                                        pRect->left);
+                    PSDRV_WriteArrayPut(physDev, szArrayName, i * 4 + 1,
+                                        pRect->top);
+                    PSDRV_WriteArrayPut(physDev, szArrayName, i * 4 + 2,
+                                        pRect->right - pRect->left);
+                    PSDRV_WriteArrayPut(physDev, szArrayName, i * 4 + 3,
+                                        pRect->bottom - pRect->top);
+                }
+                PSDRV_WriteRectClip2(physDev, szArrayName);
+            }
         }
-        PSDRV_WriteRectClip2(physDev, szArrayName);
+        physDev->dc_rgndata_set = rgndata;
+        physDev->dc_rgndata_valid = TRUE;
     }
-end:
-    HeapFree( GetProcessHeap(), 0, rgndata );
+    HeapFree( PSDRV_Heap, 0, rgndata_set );
 }
 
 /***********************************************************************
@@ -110,7 +135,7 @@ void PSDRV_SetDeviceClippingFromDC( PSDRV_PDEVICE *physDev )
 
     hrgn = CreateRectRgn(0,0,0,0);
     GetRandomRgn(physDev->hdc, hrgn, 3);
-    PSDRV_SetDeviceClipping(physDev, hrgn);
+    PSDRV_SetDeviceClipping(physDev, NULL, hrgn);
     DeleteObject(hrgn);
 }
 
@@ -133,9 +158,10 @@ void PSDRV_ClippingOff( PSDRV_PDEVICE *physDev )
 {
     TRACE("hdc=%p\n", physDev->hdc);
 
+    PSDRV_WriteSpool(physDev, "% ClippingOff\n", strlen("% ClippingOff\n"));
     PSDRV_WriteGRestore(physDev);
     PSDRV_WriteGSave(physDev);
-
+    physDev->dc_rgndata_valid = FALSE;
     physDev->brush.set = FALSE;
     physDev->font.set = FALSE;
     physDev->pen.set = FALSE;
@@ -167,6 +193,9 @@ void PSDRV_ClippingEscRestore( PSDRV_PDEVICE *physDev )
 void PSDRV_ClippingEscSet( PSDRV_PDEVICE *physDev, WORD mode )
 {
     PSDRV_WriteClip(physDev);
+#if 0
+    physDev->dc_rgndata_valid = FALSE;
+#endif
 }
 
 /***********************************************************************
diff --git a/dlls/wineps.drv/escape.c b/dlls/wineps.drv/escape.c
index bfa4976..02bd449 100644
--- a/dlls/wineps.drv/escape.c
+++ b/dlls/wineps.drv/escape.c
@@ -358,7 +358,10 @@ INT PSDRV_StartPage( PSDRV_PDEVICE *physDev )
 
     if(!PSDRV_WriteNewPage( physDev ))
         return 0;
+
+    physDev->dc_rgndata_valid = FALSE;
     physDev->job.OutOfPage = FALSE;
+
     return 1;
 }
 
diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c
index 61e31d8..8adeb90 100644
--- a/dlls/wineps.drv/init.c
+++ b/dlls/wineps.drv/init.c
@@ -387,6 +387,7 @@ BOOL PSDRV_DeleteDC( PSDRV_PDEVICE *physDev )
 
     HeapFree( PSDRV_Heap, 0, physDev->Devmode );
     HeapFree( PSDRV_Heap, 0, physDev->job.output );
+    HeapFree( PSDRV_Heap, 0, physDev->dc_rgndata_set);
     HeapFree( PSDRV_Heap, 0, physDev );
 
     return TRUE;
@@ -408,6 +409,8 @@ HDC PSDRV_ResetDC( PSDRV_PDEVICE *physDev, const DEVMODEW *lpInitData )
         SelectVisRgn( physDev->hdc, hrgn );
         DeleteObject(hrgn);
     }
+    HeapFree( PSDRV_Heap, 0, physDev->dc_rgndata_set);
+    physDev->dc_rgndata_valid = FALSE;
     return physDev->hdc;
 }
 
diff --git a/dlls/wineps.drv/ps.c b/dlls/wineps.drv/ps.c
index 27a3fc7..2bd591c 100644
--- a/dlls/wineps.drv/ps.c
+++ b/dlls/wineps.drv/ps.c
@@ -85,6 +85,7 @@ static const char psnewpage[] = /* name, number, xres, yres, xtrans, ytrans, rot
 "%d %d translate\n"
 "1 -1 scale\n"
 "%d rotate\n"
+"gsave\n"
 "%%%%EndPageSetup\n";
 
 static const char psendpage[] =
diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h
index 37ed42d..84dccf3 100644
--- a/dlls/wineps.drv/psdrv.h
+++ b/dlls/wineps.drv/psdrv.h
@@ -369,6 +369,8 @@ typedef struct {
     int                 logPixelsY;
 
     int                 pathdepth;
+    RGNDATA		*dc_rgndata_set;
+    BOOL		dc_rgndata_valid;
 } PSDRV_PDEVICE;
 
 typedef struct {
@@ -421,12 +423,12 @@ extern BOOL PSDRV_Brush(PSDRV_PDEVICE *physDev, BOOL EO);
 extern BOOL PSDRV_SetFont( PSDRV_PDEVICE *physDev );
 extern BOOL PSDRV_SetPen( PSDRV_PDEVICE *physDev );
 
-void PSDRV_SetDeviceClippingFromDC( PSDRV_PDEVICE *physDev );
-void PSDRV_ClippingOn( PSDRV_PDEVICE *physDev );
-void PSDRV_ClippingOff( PSDRV_PDEVICE *physDev );
-void PSDRV_ClippingEscSave( PSDRV_PDEVICE *physDev );
-void PSDRV_ClippingEscRestore( PSDRV_PDEVICE *physDev );
-void PSDRV_ClippingEscSet( PSDRV_PDEVICE *physDev, WORD mode );
+extern void PSDRV_SetDeviceClipping( PSDRV_PDEVICE *physDev, HRGN vis_rgn, HRGN clip_rgn );
+extern void PSDRV_ClippingOn( PSDRV_PDEVICE *physDev );
+extern void PSDRV_ClippingOff( PSDRV_PDEVICE *physDev );
+extern void PSDRV_ClippingEscSave( PSDRV_PDEVICE *physDev );
+extern void PSDRV_ClippingEscRestore( PSDRV_PDEVICE *physDev );
+extern void PSDRV_ClippingEscSet( PSDRV_PDEVICE *physDev, WORD mode );
 
 extern void PSDRV_SetClip(PSDRV_PDEVICE* phyDev);
 extern void PSDRV_ResetClip(PSDRV_PDEVICE* phyDev);
-- 
1.5.6.5




More information about the wine-patches mailing list