From 5e9e174e71873e12e00ef42c818d6222904cbb73 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 27 Apr 2016 16:24:34 +0200 Subject: [PATCH] Added patch to implement support for loading and saving EMF to IPicture interface. --- ...dd-some-tests-for-loading-and-saving.patch | 121 ++++++++++++++++ ...port-for-loading-and-saving-EMF-to-I.patch | 130 ++++++++++++++++++ patches/oleaut32-Load_Save_EMF/definition | 1 + patches/patchinstall.sh | 21 +++ 4 files changed, 273 insertions(+) create mode 100644 patches/oleaut32-Load_Save_EMF/0001-oleaut32-tests-Add-some-tests-for-loading-and-saving.patch create mode 100644 patches/oleaut32-Load_Save_EMF/0002-oleaut32-Add-support-for-loading-and-saving-EMF-to-I.patch create mode 100644 patches/oleaut32-Load_Save_EMF/definition diff --git a/patches/oleaut32-Load_Save_EMF/0001-oleaut32-tests-Add-some-tests-for-loading-and-saving.patch b/patches/oleaut32-Load_Save_EMF/0001-oleaut32-tests-Add-some-tests-for-loading-and-saving.patch new file mode 100644 index 00000000..778e1188 --- /dev/null +++ b/patches/oleaut32-Load_Save_EMF/0001-oleaut32-tests-Add-some-tests-for-loading-and-saving.patch @@ -0,0 +1,121 @@ +From f68ed438045727c64905bee9356a46320e4cb489 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Tue, 26 Apr 2016 12:11:17 +0800 +Subject: oleaut32/tests: Add some tests for loading and saving EMF using + IPicture interface. + +--- + dlls/oleaut32/tests/olepicture.c | 90 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 90 insertions(+) + +diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c +index 0903298..de45603 100644 +--- a/dlls/oleaut32/tests/olepicture.c ++++ b/dlls/oleaut32/tests/olepicture.c +@@ -1305,6 +1305,95 @@ todo_wine + IStream_Release(stream); + } + ++static void test_load_save_emf(void) ++{ ++ HDC hdc; ++ IPicture *pic; ++ PICTDESC desc; ++ short type; ++ OLE_HANDLE handle; ++ HGLOBAL hmem; ++ DWORD *mem; ++ ENHMETAHEADER *emh; ++ IPersistStream *src_stream; ++ IStream *dst_stream; ++ LARGE_INTEGER offset; ++ HRESULT hr; ++ LONG size; ++ ++ hdc = CreateEnhMetaFileA(0, NULL, NULL, NULL); ++ ok(hdc != 0, "CreateEnhMetaFileA failed\n"); ++ ++ desc.cbSizeofstruct = sizeof(desc); ++ desc.picType = PICTYPE_ENHMETAFILE; ++ desc.u.emf.hemf = CloseEnhMetaFile(hdc); ++ ok(desc.u.emf.hemf != 0, "CloseEnhMetaFile failed\n"); ++ hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic); ++ ok(hr == S_OK, "OleCreatePictureIndirect error %#x\n", hr); ++ ++ type = -1; ++ hr = IPicture_get_Type(pic, &type); ++ ok(hr == S_OK,"get_Type error %#8x\n", hr); ++ ok(type == PICTYPE_ENHMETAFILE,"expected PICTYPE_ENHMETAFILE, got %d\n", type); ++ ++ hr = IPicture_get_Handle(pic, &handle); ++ ok(hr == S_OK,"get_Handle error %#8x\n", hr); ++ ok(IntToPtr(handle) == desc.u.emf.hemf, "get_Handle returned wrong handle %#x\n", handle); ++ ++ hmem = GlobalAlloc(GMEM_MOVEABLE, 0); ++ hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream); ++ ok(hr == S_OK, "createstreamonhglobal error %#x\n", hr); ++ ++ size = -1; ++ hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size); ++ ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr); ++todo_wine ++ ok(size == 128, "expected 128, got %d\n", size); ++ emh = GlobalLock(hmem); ++if (size) ++{ ++ ok(emh->iType == EMR_HEADER, "wrong iType %04x\n", emh->iType); ++ ok(emh->dSignature == ENHMETA_SIGNATURE, "wrong dSignature %08x\n", emh->dSignature); ++} ++ GlobalUnlock(hmem); ++ ++ size = -1; ++ hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size); ++todo_wine ++ ok(hr == E_FAIL, "expected E_FAIL, got %#x\n", hr); ++todo_wine ++ ok(size == -1, "expected -1, got %d\n", size); ++ ++ offset.QuadPart = 0; ++ hr = IStream_Seek(dst_stream, offset, SEEK_SET, NULL); ++ ok(hr == S_OK, "IStream_Seek %#x\n", hr); ++ ++ hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream); ++ ok(hr == S_OK, "QueryInterface error %#x\n", hr); ++ ++ hr = IPersistStream_Save(src_stream, dst_stream, TRUE); ++todo_wine ++ ok(hr == S_OK, "Save error %#x\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 %04x\n", mem[0]); ++ ok(mem[1] == 128, "expected 128, got %u\n", mem[1]); ++ emh = (ENHMETAHEADER *)(mem + 2); ++ ok(emh->iType == EMR_HEADER, "wrong iType %04x\n", emh->iType); ++ ok(emh->dSignature == ENHMETA_SIGNATURE, "wrong dSignature %08x\n", emh->dSignature); ++} ++ GlobalUnlock(hmem); ++ GlobalFree(hmem); ++ ++ DeleteEnhMetaFile(desc.u.emf.hemf); ++ IPicture_Release(pic); ++} ++ + START_TEST(olepicture) + { + hOleaut32 = GetModuleHandleA("oleaut32.dll"); +@@ -1344,6 +1433,7 @@ START_TEST(olepicture) + test_load_save_bmp(); + test_load_save_icon(); + test_load_save_empty_picture(); ++ test_load_save_emf(); + } + + +-- +2.8.0 + diff --git a/patches/oleaut32-Load_Save_EMF/0002-oleaut32-Add-support-for-loading-and-saving-EMF-to-I.patch b/patches/oleaut32-Load_Save_EMF/0002-oleaut32-Add-support-for-loading-and-saving-EMF-to-I.patch new file mode 100644 index 00000000..d85ec2b0 --- /dev/null +++ b/patches/oleaut32-Load_Save_EMF/0002-oleaut32-Add-support-for-loading-and-saving-EMF-to-I.patch @@ -0,0 +1,130 @@ +From a7d49a0453ce0947b66f881e7c0e2966bf5549bc Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Tue, 26 Apr 2016 13:15:41 +0800 +Subject: oleaut32: Add support for loading and saving EMF to IPicture + interface. + +For bug #40523. +--- + dlls/oleaut32/olepicture.c | 52 +++++++++++++++++++++++++++++++++++++--- + dlls/oleaut32/tests/olepicture.c | 5 +--- + 2 files changed, 50 insertions(+), 7 deletions(-) + +diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c +index 96c109a..b82031d 100644 +--- a/dlls/oleaut32/olepicture.c ++++ b/dlls/oleaut32/olepicture.c +@@ -266,6 +266,18 @@ static void OLEPictureImpl_SetIcon(OLEPictureImpl * This) + } + } + ++static void OLEPictureImpl_SetEMF(OLEPictureImpl *This) ++{ ++ ENHMETAHEADER emh; ++ ++ GetEnhMetaFileHeader(This->desc.u.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 + * +@@ -346,7 +358,11 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn) + case PICTYPE_ICON: + OLEPictureImpl_SetIcon(newObject); + break; ++ + case PICTYPE_ENHMETAFILE: ++ OLEPictureImpl_SetEMF(newObject); ++ break; ++ + default: + FIXME("Unsupported type %d\n", pictDesc->picType); + newObject->himetricWidth = newObject->himetricHeight = 0; +@@ -1761,6 +1777,17 @@ static BOOL serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength) + return success; + } + ++static BOOL serializeEMF(HENHMETAFILE hemf, void **buf, unsigned *size) ++{ ++ *size = GetEnhMetaFileBits(hemf, 0, NULL); ++ if (!*size) return FALSE; ++ ++ *buf = HeapAlloc(GetProcessHeap(), 0, *size); ++ if (!*buf) return FALSE; ++ ++ return GetEnhMetaFileBits(hemf, *size, *buf) != 0; ++} ++ + static HRESULT WINAPI OLEPictureImpl_Save( + IPersistStream* iface,IStream*pStm,BOOL fClearDirty) + { +@@ -1836,12 +1863,31 @@ 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) ++ { ++ serializeResult = serializeEMF(This->desc.u.emf.hemf, &pIconData, &iDataSize); ++ if (!serializeResult) ++ { ++ hResult = E_FAIL; ++ 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 de45603..7503265 100644 +--- a/dlls/oleaut32/tests/olepicture.c ++++ b/dlls/oleaut32/tests/olepicture.c +@@ -1372,21 +1372,18 @@ todo_wine + ok(hr == S_OK, "QueryInterface error %#x\n", hr); + + hr = IPersistStream_Save(src_stream, dst_stream, TRUE); +-todo_wine + ok(hr == S_OK, "Save error %#x\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 %04x\n", mem[0]); + ok(mem[1] == 128, "expected 128, got %u\n", mem[1]); + emh = (ENHMETAHEADER *)(mem + 2); + ok(emh->iType == EMR_HEADER, "wrong iType %04x\n", emh->iType); + ok(emh->dSignature == ENHMETA_SIGNATURE, "wrong dSignature %08x\n", emh->dSignature); +-} ++ + GlobalUnlock(hmem); + GlobalFree(hmem); + +-- +2.8.0 + diff --git a/patches/oleaut32-Load_Save_EMF/definition b/patches/oleaut32-Load_Save_EMF/definition new file mode 100644 index 00000000..0bb7c3c2 --- /dev/null +++ b/patches/oleaut32-Load_Save_EMF/definition @@ -0,0 +1 @@ +Fixes: [40523] Implement support for loading and saving EMF to IPicture interface diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 697023a2..c992eede 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -252,6 +252,7 @@ patch_enable_all () enable_nvencodeapi_Video_Encoder="$1" enable_ole32_HGLOBALStream="$1" enable_oleaut32_CreateTypeLib="$1" + enable_oleaut32_Load_Save_EMF="$1" enable_oleaut32_OLEPictureImpl_SaveAsFile="$1" enable_oleaut32_OleLoadPicture="$1" enable_oleaut32_OleLoadPictureFile="$1" @@ -925,6 +926,9 @@ patch_enable () oleaut32-CreateTypeLib) enable_oleaut32_CreateTypeLib="$2" ;; + oleaut32-Load_Save_EMF) + enable_oleaut32_Load_Save_EMF="$2" + ;; oleaut32-OLEPictureImpl_SaveAsFile) enable_oleaut32_OLEPictureImpl_SaveAsFile="$2" ;; @@ -5527,6 +5531,23 @@ if test "$enable_oleaut32_CreateTypeLib" -eq 1; then ) >> "$patchlist" fi +# Patchset oleaut32-Load_Save_EMF +# | +# | This patchset fixes the following Wine bugs: +# | * [#40523] Implement support for loading and saving EMF to IPicture interface +# | +# | Modified files: +# | * dlls/oleaut32/olepicture.c, dlls/oleaut32/tests/olepicture.c +# | +if test "$enable_oleaut32_Load_Save_EMF" -eq 1; then + patch_apply oleaut32-Load_Save_EMF/0001-oleaut32-tests-Add-some-tests-for-loading-and-saving.patch + patch_apply oleaut32-Load_Save_EMF/0002-oleaut32-Add-support-for-loading-and-saving-EMF-to-I.patch + ( + echo '+ { "Dmitry Timoshkov", "oleaut32/tests: Add some tests for loading and saving EMF using IPicture interface.", 1 },'; + echo '+ { "Dmitry Timoshkov", "oleaut32: Add support for loading and saving EMF to IPicture interface.", 1 },'; + ) >> "$patchlist" +fi + # Patchset oleaut32-OLEPictureImpl_SaveAsFile # | # | This patchset fixes the following Wine bugs: