Of particular concern is making sure my dynamically allocated memory is
being freed.  The new data is stored in PSPEN and is allocated when
SelectObject (on a wineps.drv device of course) passing a pen and is
freed whenever a subsequent pen is selected or the device context is
deleted.

I'm just not intimately familiar enough with this part of the API to
know for certain that this eliminates all room for leaks.

Thanks!
Daniel
>From b29f23aa59f74399d7a00352deb7e72554281942 Mon Sep 17 00:00:00 2001
From: Daniel Santos <[email protected]>
Date: Tue, 15 Feb 2011 00:22:18 -0600
Subject: wineps.drv: Implement PS_USERSTYLE on printers
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="------------1.7.3.4"

This is a multi-part message in MIME format.
--------------1.7.3.4
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit


Tests are still missing (need to figure out where they go). Dynamic
memory is required and was added to struct PSPEN, when own_dash is
non-zero, then the memory pointed to by dash needs to be freed. Freeing
is handled by static inline psdrv_cleanup_pen() and called from
PSDRV_SelectPen (when replacing a pen with PS_USERSTYLE) or
PSDRV_DeleteDC.
---
 dlls/wineps.drv/init.c  |    1 +
 dlls/wineps.drv/pen.c   |   48 ++++++++++++++++++++++++++++++++++++++++++----
 dlls/wineps.drv/psdrv.h |    8 +++++++
 3 files changed, 52 insertions(+), 5 deletions(-)


--------------1.7.3.4
Content-Type: text/x-patch; 
name="0001-wineps.drv-Implement-PS_USERSTYLE-on-printers.txt"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; 
filename="0001-wineps.drv-Implement-PS_USERSTYLE-on-printers.txt"

diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c
index 3a6f89f..c2d8449 100644
--- a/dlls/wineps.drv/init.c
+++ b/dlls/wineps.drv/init.c
@@ -402,6 +402,7 @@ static BOOL PSDRV_DeleteDC( PHYSDEV dev )
 
     TRACE("\n");
 
+    psdrv_cleanup_pen( physDev );
     HeapFree( PSDRV_Heap, 0, physDev->Devmode );
     HeapFree( PSDRV_Heap, 0, physDev->job.output );
     HeapFree( PSDRV_Heap, 0, physDev );
diff --git a/dlls/wineps.drv/pen.c b/dlls/wineps.drv/pen.c
index 55379db..da073bf 100644
--- a/dlls/wineps.drv/pen.c
+++ b/dlls/wineps.drv/pen.c
@@ -19,6 +19,7 @@
  */
 
 #include <stdarg.h>
+#include <stdio.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -41,11 +42,11 @@ HPEN PSDRV_SelectPen( PHYSDEV dev, HPEN hpen )
 {
     PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
     LOGPEN logpen;
+    EXTLOGPEN *elp = NULL;
 
     if (!GetObjectW( hpen, sizeof(logpen), &logpen ))
     {
         /* must be an extended pen */
-        EXTLOGPEN *elp;
         INT size = GetObjectW( hpen, 0, NULL );
 
         if (!size) return 0;
@@ -53,13 +54,10 @@ HPEN PSDRV_SelectPen( PHYSDEV dev, HPEN hpen )
         elp = HeapAlloc( GetProcessHeap(), 0, size );
 
         GetObjectW( hpen, size, elp );
-        /* FIXME: add support for user style pens */
         logpen.lopnStyle = elp->elpPenStyle;
         logpen.lopnWidth.x = elp->elpWidth;
         logpen.lopnWidth.y = 0;
         logpen.lopnColor = elp->elpColor;
-
-        HeapFree( GetProcessHeap(), 0, elp );
     }
 
     TRACE("hpen = %p colour = %08x\n", hpen, logpen.lopnColor);
@@ -92,6 +90,9 @@ HPEN PSDRV_SelectPen( PHYSDEV dev, HPEN hpen )
     PSDRV_CreateColor(dev, &physDev->pen.color, logpen.lopnColor);
     physDev->pen.style = logpen.lopnStyle & PS_STYLE_MASK;
 
+    psdrv_cleanup_pen( physDev );
+    physDev->pen.own_dash = 0;
+
     switch(physDev->pen.style) {
     case PS_DASH:
        physDev->pen.dash = PEN_dash;
@@ -113,15 +114,52 @@ HPEN PSDRV_SelectPen( PHYSDEV dev, HPEN hpen )
        physDev->pen.dash = PEN_alternate;
        break;
 
+    case PS_USERSTYLE:
+    {
+        /* buf[256] in PSDRV_WriteSetPen will get 14 bytes with a zero-length
+         * pen.dash, so 240 bytes should be a reasonable limit here. */
+        char buf[240];
+        char *p = buf;
+        size_t buf_size = sizeof(buf);
+        size_t i;
+
+        /* ExtCreatePen assures that elp->elpNumEntries > 0 here */
+        for (i = 0; i < elp->elpNumEntries; ++i) {
+            size_t bytes_written;
+            bytes_written = snprintf(p, buf_size, "%d ", 
elp->elpStyleEntry[i]);
+            if (bytes_written > buf_size) {
+                WARN("buffer too small while formatting PS_USERSTYLE into "
+                        "postscript\n");
+                break;
+            }
+            buf_size -= bytes_written;
+            p += bytes_written;
+        }
+
+        /* remove trailing space */
+        *(p - 1) = 0;
+
+        if (! (physDev->pen.dash = HeapAlloc( GetProcessHeap(), 0, p - buf ))) 
{
+            HeapFree( GetProcessHeap(), 0, elp );
+            return 0;
+        }
+        physDev->pen.own_dash = 1;
+        strcpy((char *)physDev->pen.dash, buf);
+        break;
+    }
+
     default:
        physDev->pen.dash = NULL;
     }
 
-    if ((physDev->pen.width > 1) && (physDev->pen.dash != NULL)) {
+    if ((physDev->pen.style != PS_USERSTYLE) && (physDev->pen.width > 1)
+             && (physDev->pen.dash != NULL)) {
        physDev->pen.style = PS_SOLID;
          physDev->pen.dash = NULL;
     }
 
+    HeapFree( GetProcessHeap(), 0, elp );
+
     physDev->pen.set = FALSE;
     return hpen;
 }
diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h
index 8047942..caed5f3 100644
--- a/dlls/wineps.drv/psdrv.h
+++ b/dlls/wineps.drv/psdrv.h
@@ -337,6 +337,7 @@ typedef struct {
     const char*                dash;
     PSCOLOR            color;
     BOOL               set;
+    BOOL                own_dash;       /* TRUE if we need to free dash */
 } PSPEN;
 
 typedef struct {
@@ -390,6 +391,13 @@ static inline PSDRV_PDEVICE *get_psdrv_dev( PHYSDEV dev )
     return (PSDRV_PDEVICE *)dev;
 }
 
+static inline void psdrv_cleanup_pen(PSDRV_PDEVICE *dev) {
+    if (dev->pen.own_dash) {
+        HeapFree( GetProcessHeap(), 0, (LPVOID)dev->pen.dash );
+        dev->pen.own_dash = 0;
+    }
+}
+
 /*
  *  Every glyph name in the Adobe Glyph List and the 35 core PostScript fonts
  */

--------------1.7.3.4--




Reply via email to