[PATCH 1/4] ole32: Add support for loading enhmetafiles from presentation and contents streams to data cache.

Sergio Gómez Del Real sdelreal at codeweavers.com
Tue Mar 27 11:39:58 CDT 2018


Signed-off-by: Sergio Gómez Del Real <sdelreal at codeweavers.com>
---
 dlls/ole32/datacache.c | 97 +++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 73 insertions(+), 24 deletions(-)

diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c
index 325a98b33b..e511eac23e 100644
--- a/dlls/ole32/datacache.c
+++ b/dlls/ole32/datacache.c
@@ -547,6 +547,30 @@ static HRESULT open_pres_stream( IStorage *stg, int stream_number, IStream **stm
     return IStorage_OpenStream( stg, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
 }
 
+static HRESULT synthesize_emf( HMETAFILEPICT data, STGMEDIUM *med )
+{
+    METAFILEPICT *pict;
+    HRESULT hr = E_FAIL;
+    UINT size;
+    void *bits;
+
+    if (!(pict = GlobalLock( data ))) return hr;
+
+    size = GetMetaFileBitsEx( pict->hMF, 0, NULL );
+    if ((bits = HeapAlloc( GetProcessHeap(), 0, size )))
+    {
+        GetMetaFileBitsEx( pict->hMF, size, bits );
+        med->u.hEnhMetaFile = SetWinMetaFileBits( size, bits, NULL, pict );
+        HeapFree( GetProcessHeap(), 0, bits );
+        med->tymed = TYMED_ENHMF;
+        med->pUnkForRelease = NULL;
+        hr = S_OK;
+    }
+
+    GlobalUnlock( data );
+    return hr;
+}
+
 static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm )
 {
     HRESULT hr;
@@ -701,7 +725,52 @@ fail:
     GlobalUnlock( hglobal );
     GlobalFree( hglobal );
     return E_FAIL;
+}
+
+static HRESULT load_emf( DataCacheEntry *cache_entry, IStream *stm )
+{
+
+    if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS)
+    {
+        HMETAFILEPICT hmfpict;
+        METAFILEPICT *mfpict;
+
+        load_mf_pict(cache_entry, stm);
+        hmfpict = cache_entry->stgmedium.u.hMetaFilePict;
+        synthesize_emf(hmfpict, &cache_entry->stgmedium);
+        mfpict = GlobalLock(hmfpict);
+        DeleteMetaFile(mfpict->hMF);
+        GlobalFree(hmfpict);
+    }
+    else
+    {
+        HRESULT hr;
+        STATSTG stat;
+        void *data;
+        DWORD size_bits;
+        ULONG read;
+
+        hr = IStream_Stat( stm, &stat, STATFLAG_NONAME );
+        if (FAILED( hr )) return hr;
 
+        data = HeapAlloc( GetProcessHeap(), 0, stat.cbSize.u.LowPart );
+        if (!data) return E_OUTOFMEMORY;
+
+        hr = IStream_Read( stm, data, stat.cbSize.u.LowPart, &read );
+        if (hr != S_OK || read != stat.cbSize.u.LowPart) hr = E_FAIL;
+
+        size_bits = read - sizeof(DWORD) - sizeof(ENHMETAHEADER);
+        if (size_bits <= 0)
+        {
+            HeapFree( GetProcessHeap(), 0, data );
+            return E_FAIL;
+        }
+        cache_entry->stgmedium.u.hEnhMetaFile = SetEnhMetaFileBits( size_bits, (BYTE *)data + (read - size_bits) );
+        cache_entry->stgmedium.tymed = TYMED_ENHMF;
+        cache_entry->stgmedium.pUnkForRelease = NULL;
+    }
+
+    return S_OK;
 }
 
 /************************************************************************
@@ -736,6 +805,10 @@ static HRESULT DataCacheEntry_LoadData(DataCacheEntry *cache_entry, IStorage *st
         hr = load_dib( cache_entry, stm );
         break;
 
+    case CF_ENHMETAFILE:
+        hr = load_emf( cache_entry, stm );
+        break;
+
     default:
         FIXME( "Unimplemented clip format %x\n", cache_entry->fmtetc.cfFormat );
         hr = E_NOTIMPL;
@@ -1118,30 +1191,6 @@ static HRESULT synthesize_bitmap( HGLOBAL dib, STGMEDIUM *med )
     return hr;
 }
 
-static HRESULT synthesize_emf( HMETAFILEPICT data, STGMEDIUM *med )
-{
-    METAFILEPICT *pict;
-    HRESULT hr = E_FAIL;
-    UINT size;
-    void *bits;
-
-    if (!(pict = GlobalLock( data ))) return hr;
-
-    size = GetMetaFileBitsEx( pict->hMF, 0, NULL );
-    if ((bits = HeapAlloc( GetProcessHeap(), 0, size )))
-    {
-        GetMetaFileBitsEx( pict->hMF, size, bits );
-        med->u.hEnhMetaFile = SetWinMetaFileBits( size, bits, NULL, pict );
-        HeapFree( GetProcessHeap(), 0, bits );
-        med->tymed = TYMED_ENHMF;
-        med->pUnkForRelease = NULL;
-        hr = S_OK;
-    }
-
-    GlobalUnlock( data );
-    return hr;
-}
-
 static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry,
                                       const FORMATETC *formatetc,
                                       STGMEDIUM *stgmedium,
-- 
2.14.1




More information about the wine-devel mailing list