From: Dmitry Timoshkov dmitry@baikal.ru
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=40523. Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/oleaut32/olepicture.c | 53 +++++++++++++++++++++++++++++--- dlls/oleaut32/tests/olepicture.c | 5 +-- 2 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c index 8278ec1f2f8..5b3783f1de9 100644 --- a/dlls/oleaut32/olepicture.c +++ b/dlls/oleaut32/olepicture.c @@ -256,6 +256,18 @@ static void OLEPictureImpl_SetIcon(OLEPictureImpl * This) } }
+static void OLEPictureImpl_SetEMF(OLEPictureImpl *This) +{ + ENHMETAHEADER emh; + + GetEnhMetaFileHeader(This->desc.emf.hemf, sizeof(emh), &emh); + + This->origWidth = 0; + This->origHeight = 0; + This->himetricWidth = emh.rclFrame.right - emh.rclFrame.left; + This->himetricHeight = emh.rclFrame.bottom - emh.rclFrame.top; +} + /************************************************************************ * OLEPictureImpl_Construct * @@ -339,8 +351,7 @@ static HRESULT OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn, OLEPictu break;
case PICTYPE_ENHMETAFILE: - FIXME("EMF is not supported\n"); - newObject->himetricWidth = newObject->himetricHeight = 0; + OLEPictureImpl_SetEMF(newObject); break;
default: @@ -1768,6 +1779,22 @@ static BOOL serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength) return success; }
+static HRESULT serializeEMF(HENHMETAFILE hemf, void **buf, unsigned *size) +{ + if (!(*size = GetEnhMetaFileBits(hemf, 0, NULL))) + return E_FAIL; + + if (!(*buf = HeapAlloc(GetProcessHeap(), 0, *size))) + return E_OUTOFMEMORY; + + if (!GetEnhMetaFileBits(hemf, *size, *buf)) + { + HeapFree(GetProcessHeap(), 0, *buf); + return E_FAIL; + } + return S_OK; +} + static HRESULT WINAPI OLEPictureImpl_Save( IPersistStream* iface,IStream*pStm,BOOL fClearDirty) { @@ -1839,12 +1866,28 @@ static HRESULT WINAPI OLEPictureImpl_Save( IStream_Write(pStm, This->data, This->datalen, &dummy); hResult = S_OK; break; + + case PICTYPE_ENHMETAFILE: + if (This->bIsDirty || !This->data) + { + hResult = serializeEMF(This->desc.emf.hemf, &pIconData, &iDataSize); + if (hResult != S_OK) + break; + + HeapFree(GetProcessHeap(), 0, This->data); + This->data = pIconData; + This->datalen = iDataSize; + } + header[0] = 0x0000746c; + header[1] = This->datalen; + IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy); + IStream_Write(pStm, This->data, This->datalen, &dummy); + hResult = S_OK; + break; + case PICTYPE_METAFILE: FIXME("(%p,%p,%d), PICTYPE_METAFILE not implemented!\n",This,pStm,fClearDirty); break; - case PICTYPE_ENHMETAFILE: - FIXME("(%p,%p,%d),PICTYPE_ENHMETAFILE not implemented!\n",This,pStm,fClearDirty); - break; default: FIXME("(%p,%p,%d), [unknown type] not implemented!\n",This,pStm,fClearDirty); break; diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c index 622d50ddd2e..2b2c84abe38 100644 --- a/dlls/oleaut32/tests/olepicture.c +++ b/dlls/oleaut32/tests/olepicture.c @@ -1689,21 +1689,18 @@ static void test_load_save_emf(void) ok(hr == S_OK, "QueryInterface error %#lx\n", hr);
hr = IPersistStream_Save(src_stream, dst_stream, TRUE); - todo_wine ok(hr == S_OK, "Save error %#lx\n", hr);
IPersistStream_Release(src_stream); IStream_Release(dst_stream);
mem = GlobalLock(hmem); - if (hr == S_OK) - { ok(!memcmp(mem, "lt\0\0", 4), "got wrong stream header %04lx\n", mem[0]); ok(mem[1] == 128, "expected 128, got %lu\n", mem[1]); emh = (ENHMETAHEADER *)(mem + 2); ok(emh->iType == EMR_HEADER, "wrong iType %04lx\n", emh->iType); ok(emh->dSignature == ENHMETA_SIGNATURE, "wrong dSignature %08lx\n", emh->dSignature); - } + GlobalUnlock(hmem); GlobalFree(hmem);