Commit 9ea33ed0 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

gdi32: Cache the device caps from the reference dc, since the dc may become invalid.

parent e8ef521c
...@@ -510,7 +510,9 @@ INT EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap) ...@@ -510,7 +510,9 @@ INT EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap)
{ {
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev ); 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;
} }
......
...@@ -40,10 +40,9 @@ typedef struct ...@@ -40,10 +40,9 @@ typedef struct
HANDLE hFile; /* Handle for disk based MetaFile */ HANDLE hFile; /* Handle for disk based MetaFile */
HBRUSH dc_brush; HBRUSH dc_brush;
HPEN dc_pen; HPEN dc_pen;
HDC ref_dc; /* Reference device */
HDC screen_dc; /* Screen DC if no reference device specified */
INT restoring; /* RestoreDC counter */ INT restoring; /* RestoreDC counter */
BOOL path; BOOL path;
INT dev_caps[COLORMGMTCAPS + 1];
} EMFDRV_PDEVICE; } EMFDRV_PDEVICE;
static inline EMFDRV_PDEVICE *get_emf_physdev( PHYSDEV dev ) static inline EMFDRV_PDEVICE *get_emf_physdev( PHYSDEV dev )
......
...@@ -301,6 +301,23 @@ HDC WINAPI CreateEnhMetaFileA( ...@@ -301,6 +301,23 @@ HDC WINAPI CreateEnhMetaFileA(
return hReturnDC; 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.@) * CreateEnhMetaFileW (GDI32.@)
*/ */
...@@ -312,12 +329,13 @@ HDC WINAPI CreateEnhMetaFileW( ...@@ -312,12 +329,13 @@ HDC WINAPI CreateEnhMetaFileW(
) )
{ {
static const WCHAR displayW[] = {'D','I','S','P','L','A','Y',0}; static const WCHAR displayW[] = {'D','I','S','P','L','A','Y',0};
HDC ret; HDC ret, ref_dc;
DC *dc; DC *dc;
EMFDRV_PDEVICE *physDev; EMFDRV_PDEVICE *physDev;
HANDLE hFile; HANDLE hFile;
DWORD size = 0, length = 0; DWORD size = 0, length = 0;
DWORD bytes_written; DWORD bytes_written;
int cap;
TRACE("(%p %s %s %s)\n", hdc, debugstr_w(filename), wine_dbgstr_rect(rect), debugstr_w(description) ); TRACE("(%p %s %s %s)\n", hdc, debugstr_w(filename), wine_dbgstr_rect(rect), debugstr_w(description) );
...@@ -350,13 +368,20 @@ HDC WINAPI CreateEnhMetaFileW( ...@@ -350,13 +368,20 @@ HDC WINAPI CreateEnhMetaFileW(
physDev->hFile = 0; physDev->hFile = 0;
physDev->dc_brush = 0; physDev->dc_brush = 0;
physDev->dc_pen = 0; physDev->dc_pen = 0;
physDev->screen_dc = 0;
physDev->restoring = 0; physDev->restoring = 0;
physDev->path = FALSE; physDev->path = FALSE;
if (hdc) /* if no ref, use current display */ if (hdc) /* if no ref, use current display */
physDev->ref_dc = hdc; ref_dc = hdc;
else 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); SetVirtualResolution(physDev->dev.hdc, 0, 0, 0, 0);
...@@ -390,12 +415,12 @@ HDC WINAPI CreateEnhMetaFileW( ...@@ -390,12 +415,12 @@ HDC WINAPI CreateEnhMetaFileW(
physDev->emh->nPalEntries = 0; /* I guess this should start at 0 */ physDev->emh->nPalEntries = 0; /* I guess this should start at 0 */
/* Size in pixels */ /* Size in pixels */
physDev->emh->szlDevice.cx = GetDeviceCaps( physDev->ref_dc, HORZRES ); physDev->emh->szlDevice.cx = physDev->dev_caps[HORZRES];
physDev->emh->szlDevice.cy = GetDeviceCaps( physDev->ref_dc, VERTRES ); physDev->emh->szlDevice.cy = physDev->dev_caps[VERTRES];
/* Size in millimeters */ /* Size in millimeters */
physDev->emh->szlMillimeters.cx = GetDeviceCaps( physDev->ref_dc, HORZSIZE ); physDev->emh->szlMillimeters.cx = physDev->dev_caps[HORZSIZE];
physDev->emh->szlMillimeters.cy = GetDeviceCaps( physDev->ref_dc, VERTSIZE ); physDev->emh->szlMillimeters.cy = physDev->dev_caps[VERTSIZE];
/* Size in micrometers */ /* Size in micrometers */
physDev->emh->szlMicrometers.cx = physDev->emh->szlMillimeters.cx * 1000; physDev->emh->szlMicrometers.cx = physDev->emh->szlMillimeters.cx * 1000;
...@@ -457,7 +482,6 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */ ...@@ -457,7 +482,6 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
if (physDev->dc_brush) DeleteObject( physDev->dc_brush ); if (physDev->dc_brush) DeleteObject( physDev->dc_brush );
if (physDev->dc_pen) DeleteObject( physDev->dc_pen ); if (physDev->dc_pen) DeleteObject( physDev->dc_pen );
if (physDev->screen_dc) DeleteDC( physDev->screen_dc );
emr.emr.iType = EMR_EOF; emr.emr.iType = EMR_EOF;
emr.emr.nSize = sizeof(emr); emr.emr.nSize = sizeof(emr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment