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