Jacek Caban : gdi32: Introduce NtGdiCreateMetafileDC.
Alexandre Julliard
julliard at winehq.org
Mon Aug 23 16:24:14 CDT 2021
Module: wine
Branch: master
Commit: 59670ffb2d7b3fb698c9c54d04c497474148cc91
URL: https://source.winehq.org/git/wine.git/?a=commit;h=59670ffb2d7b3fb698c9c54d04c497474148cc91
Author: Jacek Caban <jacek at codeweavers.com>
Date: Mon Aug 23 13:50:32 2021 +0200
gdi32: Introduce NtGdiCreateMetafileDC.
And use it in CreateEnhMetaFileW.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/gdi32/enhmfdrv/init.c | 165 ++++++++++++++++++++++++++-------------------
1 file changed, 96 insertions(+), 69 deletions(-)
diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c
index 09a9a901086..c47ddcbd41b 100644
--- a/dlls/gdi32/enhmfdrv/init.c
+++ b/dlls/gdi32/enhmfdrv/init.c
@@ -281,6 +281,47 @@ static inline BOOL devcap_is_valid( int cap )
return FALSE;
}
+/**********************************************************************
+ * NtGdiCreateMetafileDC (win32u.@)
+ */
+HDC WINAPI NtGdiCreateMetafileDC( HDC hdc )
+{
+ EMFDRV_PDEVICE *physDev;
+ HDC ref_dc, ret;
+ int cap;
+ DC *dc;
+
+ if (!(dc = alloc_dc_ptr( NTGDI_OBJ_ENHMETADC ))) return 0;
+
+ physDev = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev) );
+ if (!physDev)
+ {
+ free_dc_ptr( dc );
+ return 0;
+ }
+ dc->attr->emf = physDev;
+
+ push_dc_driver( &dc->physDev, &physDev->dev, &emfdrv_driver );
+
+ if (hdc) /* if no ref, use current display */
+ ref_dc = hdc;
+ else
+ ref_dc = CreateDCW( L"DISPLAY", NULL, NULL, NULL );
+
+ memset( physDev->dev_caps, 0, sizeof(physDev->dev_caps) );
+ for (cap = 0; cap < ARRAY_SIZE( physDev->dev_caps ); cap++)
+ if (devcap_is_valid( cap ))
+ physDev->dev_caps[cap] = NtGdiGetDeviceCaps( ref_dc, cap );
+
+ if (!hdc) NtGdiDeleteObjectApp( ref_dc );
+
+ NtGdiSetVirtualResolution( dc->hSelf, 0, 0, 0, 0 );
+
+ ret = dc->hSelf;
+ release_dc_ptr( dc );
+ return ret;
+}
+
/**********************************************************************
* CreateEnhMetaFileW (GDI32.@)
*/
@@ -291,23 +332,23 @@ HDC WINAPI CreateEnhMetaFileW(
LPCWSTR description /* [in] optional description */
)
{
- HDC ret, ref_dc;
- DC *dc;
- EMFDRV_PDEVICE *physDev;
+ HDC ret;
+ EMFDRV_PDEVICE *emf;
+ DC_ATTR *dc_attr;
HANDLE hFile;
DWORD size = 0, length = 0;
- int cap;
TRACE("(%p %s %s %s)\n", hdc, debugstr_w(filename), wine_dbgstr_rect(rect), debugstr_w(description) );
- if (!(dc = alloc_dc_ptr( NTGDI_OBJ_ENHMETADC ))) return 0;
+ if (!(ret = NtGdiCreateMetafileDC( hdc ))) return 0;
- physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
- if (!physDev) {
- free_dc_ptr( dc );
+ if (!(dc_attr = get_dc_attr( ret )))
+ {
+ DeleteDC( ret );
return 0;
}
- dc->attr->emf = physDev;
+ emf = dc_attr->emf;
+
if(description) { /* App name\0Title\0\0 */
length = lstrlenW(description);
length += lstrlenW(description + length + 1);
@@ -316,93 +357,79 @@ HDC WINAPI CreateEnhMetaFileW(
}
size = sizeof(ENHMETAHEADER) + (length + 3) / 4 * 4;
- if (!(physDev->emh = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size))) {
- HeapFree( GetProcessHeap(), 0, physDev );
- free_dc_ptr( dc );
+ if (!(emf->emh = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size)))
+ {
+ DeleteDC( ret );
return 0;
}
- push_dc_driver( &dc->physDev, &physDev->dev, &emfdrv_driver );
+ emf->handles = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+ HANDLE_LIST_INC * sizeof(emf->handles[0]) );
+ emf->handles_size = HANDLE_LIST_INC;
+ emf->cur_handles = 1;
+ emf->hFile = 0;
+ emf->dc_brush = 0;
+ emf->dc_pen = 0;
+ emf->path = FALSE;
- physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0]));
- physDev->handles_size = HANDLE_LIST_INC;
- physDev->cur_handles = 1;
- physDev->hFile = 0;
- physDev->dc_brush = 0;
- physDev->dc_pen = 0;
- physDev->path = FALSE;
+ emf->emh->iType = EMR_HEADER;
+ emf->emh->nSize = size;
- if (hdc) /* if no ref, use current display */
- ref_dc = hdc;
- else
- ref_dc = CreateDCW( L"DISPLAY", NULL, NULL, NULL );
+ emf->emh->rclBounds.left = emf->emh->rclBounds.top = 0;
+ emf->emh->rclBounds.right = emf->emh->rclBounds.bottom = -1;
- memset( physDev->dev_caps, 0, sizeof(physDev->dev_caps) );
- for (cap = 0; cap < ARRAY_SIZE( physDev->dev_caps ); cap++)
- if (devcap_is_valid( cap ))
- physDev->dev_caps[cap] = GetDeviceCaps( ref_dc, cap );
-
- if (!hdc) DeleteDC( ref_dc );
-
- NtGdiSetVirtualResolution(physDev->dev.hdc, 0, 0, 0, 0);
-
- physDev->emh->iType = EMR_HEADER;
- physDev->emh->nSize = size;
-
- physDev->emh->rclBounds.left = physDev->emh->rclBounds.top = 0;
- physDev->emh->rclBounds.right = physDev->emh->rclBounds.bottom = -1;
-
- if(rect) {
- physDev->emh->rclFrame.left = rect->left;
- physDev->emh->rclFrame.top = rect->top;
- physDev->emh->rclFrame.right = rect->right;
- physDev->emh->rclFrame.bottom = rect->bottom;
- } else { /* Set this to {0,0 - -1,-1} and update it at the end */
- physDev->emh->rclFrame.left = physDev->emh->rclFrame.top = 0;
- physDev->emh->rclFrame.right = physDev->emh->rclFrame.bottom = -1;
+ if (rect)
+ {
+ emf->emh->rclFrame.left = rect->left;
+ emf->emh->rclFrame.top = rect->top;
+ emf->emh->rclFrame.right = rect->right;
+ emf->emh->rclFrame.bottom = rect->bottom;
+ }
+ else
+ {
+ /* Set this to {0,0 - -1,-1} and update it at the end */
+ emf->emh->rclFrame.left = emf->emh->rclFrame.top = 0;
+ emf->emh->rclFrame.right = emf->emh->rclFrame.bottom = -1;
}
- physDev->emh->dSignature = ENHMETA_SIGNATURE;
- physDev->emh->nVersion = 0x10000;
- physDev->emh->nBytes = physDev->emh->nSize;
- physDev->emh->nRecords = 1;
- physDev->emh->nHandles = 1;
+ emf->emh->dSignature = ENHMETA_SIGNATURE;
+ emf->emh->nVersion = 0x10000;
+ emf->emh->nBytes = emf->emh->nSize;
+ emf->emh->nRecords = 1;
+ emf->emh->nHandles = 1;
- physDev->emh->sReserved = 0; /* According to docs, this is reserved and must be 0 */
- physDev->emh->nDescription = length / 2;
+ emf->emh->sReserved = 0; /* According to docs, this is reserved and must be 0 */
+ emf->emh->nDescription = length / 2;
- physDev->emh->offDescription = length ? sizeof(ENHMETAHEADER) : 0;
+ emf->emh->offDescription = length ? sizeof(ENHMETAHEADER) : 0;
- physDev->emh->nPalEntries = 0; /* I guess this should start at 0 */
+ emf->emh->nPalEntries = 0; /* I guess this should start at 0 */
/* Size in pixels */
- physDev->emh->szlDevice.cx = physDev->dev_caps[HORZRES];
- physDev->emh->szlDevice.cy = physDev->dev_caps[VERTRES];
+ emf->emh->szlDevice.cx = GetDeviceCaps( ret, HORZRES );
+ emf->emh->szlDevice.cy = GetDeviceCaps( ret, VERTRES );
/* Size in millimeters */
- physDev->emh->szlMillimeters.cx = physDev->dev_caps[HORZSIZE];
- physDev->emh->szlMillimeters.cy = physDev->dev_caps[VERTSIZE];
+ emf->emh->szlMillimeters.cx = GetDeviceCaps( ret, HORZSIZE );
+ emf->emh->szlMillimeters.cy = GetDeviceCaps( ret, VERTSIZE );
/* Size in micrometers */
- physDev->emh->szlMicrometers.cx = physDev->emh->szlMillimeters.cx * 1000;
- physDev->emh->szlMicrometers.cy = physDev->emh->szlMillimeters.cy * 1000;
+ emf->emh->szlMicrometers.cx = emf->emh->szlMillimeters.cx * 1000;
+ emf->emh->szlMicrometers.cy = emf->emh->szlMillimeters.cy * 1000;
- memcpy((char *)physDev->emh + sizeof(ENHMETAHEADER), description, length);
+ memcpy( (char *)emf->emh + sizeof(ENHMETAHEADER), description, length );
if (filename) /* disk based metafile */
{
if ((hFile = CreateFileW(filename, GENERIC_WRITE | GENERIC_READ, 0,
NULL, CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) {
- free_dc_ptr( dc );
+ DeleteDC( ret );
return 0;
}
- physDev->hFile = hFile;
+ emf->hFile = hFile;
}
- TRACE("returning %p\n", physDev->dev.hdc);
- ret = physDev->dev.hdc;
- release_dc_ptr( dc );
-
+ TRACE( "returning %p\n", ret );
return ret;
}
More information about the wine-cvs
mailing list