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