Module: wine Branch: master Commit: 9ea33ed00a242392a7c19dbb51afb54c0770d178 URL: http://source.winehq.org/git/wine.git/?a=commit;h=9ea33ed00a242392a7c19dbb51...
Author: Huw Davies huw@codeweavers.com Date: Tue Aug 22 12:42:34 2017 +0100
gdi32: Cache the device caps from the reference dc, since the dc may become invalid.
Signed-off-by: Huw Davies huw@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/gdi32/enhmfdrv/dc.c | 4 +++- dlls/gdi32/enhmfdrv/enhmetafiledrv.h | 3 +-- dlls/gdi32/enhmfdrv/init.c | 42 ++++++++++++++++++++++++++++-------- 3 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/dlls/gdi32/enhmfdrv/dc.c b/dlls/gdi32/enhmfdrv/dc.c index 531392b..37180fe 100644 --- a/dlls/gdi32/enhmfdrv/dc.c +++ b/dlls/gdi32/enhmfdrv/dc.c @@ -510,7 +510,9 @@ INT EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap) { EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
- return GetDeviceCaps( physDev->ref_dc, cap ); + if (cap >= 0 && cap < sizeof(physDev->dev_caps) / sizeof(physDev->dev_caps[0])) + return physDev->dev_caps[cap]; + return 0; }
diff --git a/dlls/gdi32/enhmfdrv/enhmetafiledrv.h b/dlls/gdi32/enhmfdrv/enhmetafiledrv.h index 547c411..1763781 100644 --- a/dlls/gdi32/enhmfdrv/enhmetafiledrv.h +++ b/dlls/gdi32/enhmfdrv/enhmetafiledrv.h @@ -40,10 +40,9 @@ typedef struct HANDLE hFile; /* Handle for disk based MetaFile */ HBRUSH dc_brush; HPEN dc_pen; - HDC ref_dc; /* Reference device */ - HDC screen_dc; /* Screen DC if no reference device specified */ INT restoring; /* RestoreDC counter */ BOOL path; + INT dev_caps[COLORMGMTCAPS + 1]; } EMFDRV_PDEVICE;
static inline EMFDRV_PDEVICE *get_emf_physdev( PHYSDEV dev ) diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c index d241f21..6f9a956 100644 --- a/dlls/gdi32/enhmfdrv/init.c +++ b/dlls/gdi32/enhmfdrv/init.c @@ -301,6 +301,23 @@ HDC WINAPI CreateEnhMetaFileA( return hReturnDC; }
+static inline BOOL devcap_is_valid( int cap ) +{ + if (cap >= 0 && cap <= ASPECTXY) return !(cap & 1); + if (cap >= PHYSICALWIDTH && cap <= COLORMGMTCAPS) return TRUE; + switch (cap) + { + case LOGPIXELSX: + case LOGPIXELSY: + case CAPS1: + case SIZEPALETTE: + case NUMRESERVED: + case COLORRES: + return TRUE; + } + return FALSE; +} + /********************************************************************** * CreateEnhMetaFileW (GDI32.@) */ @@ -312,12 +329,13 @@ HDC WINAPI CreateEnhMetaFileW( ) { static const WCHAR displayW[] = {'D','I','S','P','L','A','Y',0}; - HDC ret; + HDC ret, ref_dc; DC *dc; EMFDRV_PDEVICE *physDev; HANDLE hFile; DWORD size = 0, length = 0; DWORD bytes_written; + int cap;
TRACE("(%p %s %s %s)\n", hdc, debugstr_w(filename), wine_dbgstr_rect(rect), debugstr_w(description) );
@@ -350,13 +368,20 @@ HDC WINAPI CreateEnhMetaFileW( physDev->hFile = 0; physDev->dc_brush = 0; physDev->dc_pen = 0; - physDev->screen_dc = 0; physDev->restoring = 0; physDev->path = FALSE; + if (hdc) /* if no ref, use current display */ - physDev->ref_dc = hdc; + ref_dc = hdc; else - physDev->ref_dc = physDev->screen_dc = CreateDCW( displayW, NULL, NULL, NULL ); + ref_dc = CreateDCW( displayW, NULL, NULL, NULL ); + + memset( physDev->dev_caps, 0, sizeof(physDev->dev_caps) ); + for (cap = 0; cap < sizeof(physDev->dev_caps) / sizeof(physDev->dev_caps[0]); cap++) + if (devcap_is_valid( cap )) + physDev->dev_caps[cap] = GetDeviceCaps( ref_dc, cap ); + + if (!hdc) DeleteDC( ref_dc );
SetVirtualResolution(physDev->dev.hdc, 0, 0, 0, 0);
@@ -390,12 +415,12 @@ HDC WINAPI CreateEnhMetaFileW( physDev->emh->nPalEntries = 0; /* I guess this should start at 0 */
/* Size in pixels */ - physDev->emh->szlDevice.cx = GetDeviceCaps( physDev->ref_dc, HORZRES ); - physDev->emh->szlDevice.cy = GetDeviceCaps( physDev->ref_dc, VERTRES ); + physDev->emh->szlDevice.cx = physDev->dev_caps[HORZRES]; + physDev->emh->szlDevice.cy = physDev->dev_caps[VERTRES];
/* Size in millimeters */ - physDev->emh->szlMillimeters.cx = GetDeviceCaps( physDev->ref_dc, HORZSIZE ); - physDev->emh->szlMillimeters.cy = GetDeviceCaps( physDev->ref_dc, VERTSIZE ); + physDev->emh->szlMillimeters.cx = physDev->dev_caps[HORZSIZE]; + physDev->emh->szlMillimeters.cy = physDev->dev_caps[VERTSIZE];
/* Size in micrometers */ physDev->emh->szlMicrometers.cx = physDev->emh->szlMillimeters.cx * 1000; @@ -457,7 +482,6 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
if (physDev->dc_brush) DeleteObject( physDev->dc_brush ); if (physDev->dc_pen) DeleteObject( physDev->dc_pen ); - if (physDev->screen_dc) DeleteDC( physDev->screen_dc );
emr.emr.iType = EMR_EOF; emr.emr.nSize = sizeof(emr);