[PATCH 1/2] gdi32: Cache the device caps from the reference dc, since the dc may become invalid.
Huw Davies
huw at codeweavers.com
Tue Aug 22 06:42:34 CDT 2017
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
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 531392b456..37180fec9e 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 547c411bc8..1763781d39 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 d241f217c6..6f9a95632c 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);
--
2.12.0
More information about the wine-patches
mailing list