Module: wine Branch: master Commit: 59670ffb2d7b3fb698c9c54d04c497474148cc91 URL: https://source.winehq.org/git/wine.git/?a=commit;h=59670ffb2d7b3fb698c9c54d0...
Author: Jacek Caban jacek@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@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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; }