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>
This commit is contained in:
parent
e8ef521c83
commit
9ea33ed00a
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue