Module: wine Branch: master Commit: 233f1c1b8807eed6a9b1c2b65664d717efe72596 URL: http://source.winehq.org/git/wine.git/?a=commit;h=233f1c1b8807eed6a9b1c2b656...
Author: Vincent Povirk vincent@codeweavers.com Date: Fri Oct 30 13:54:05 2015 -0500
gdiplus: Add initial GdipGetMetafileHeaderFromEmf implementation.
Signed-off-by: Vincent Povirk vincent@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/gdiplus/metafile.c | 81 +++++++++++++++++++++++++++++++++++++++---- dlls/gdiplus/tests/metafile.c | 40 ++++++++++----------- 2 files changed, 95 insertions(+), 26 deletions(-)
diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c index c46be76..20b8e20 100644 --- a/dlls/gdiplus/metafile.c +++ b/dlls/gdiplus/metafile.c @@ -941,18 +941,87 @@ GpStatus WINGDIPAPI GdipGetMetafileHeaderFromMetafile(GpMetafile * metafile, return Ok; }
-GpStatus WINGDIPAPI GdipGetMetafileHeaderFromEmf(HENHMETAFILE hEmf, +static int CALLBACK get_emfplus_header_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, + int nObj, LPARAM lpData) +{ + EmfPlusHeader *dst_header = (EmfPlusHeader*)lpData; + + if (lpEMFR->iType == EMR_GDICOMMENT) + { + const EMRGDICOMMENT *comment = (const EMRGDICOMMENT*)lpEMFR; + + if (comment->cbData >= 4 && memcmp(comment->Data, "EMF+", 4) == 0) + { + const EmfPlusRecordHeader *header = (const EmfPlusRecordHeader*)&comment->Data[4]; + + if (4 + sizeof(EmfPlusHeader) <= comment->cbData && + header->Type == EmfPlusRecordTypeHeader) + { + memcpy(dst_header, header, sizeof(*dst_header)); + } + } + } + else if (lpEMFR->iType == EMR_HEADER) + return TRUE; + + return FALSE; +} + +GpStatus WINGDIPAPI GdipGetMetafileHeaderFromEmf(HENHMETAFILE hemf, MetafileHeader *header) { - static int calls; + ENHMETAHEADER3 emfheader; + EmfPlusHeader emfplusheader; + MetafileType metafile_type; + + TRACE("(%p,%p)\n", hemf, header);
- if(!hEmf || !header) + if(!hemf || !header) return InvalidParameter;
- if(!(calls++)) - FIXME("not implemented\n"); + if (GetEnhMetaFileHeader(hemf, sizeof(emfheader), (ENHMETAHEADER*)&emfheader) == 0) + return GenericError;
- memset(header, 0, sizeof(MetafileHeader)); + emfplusheader.Header.Type = 0; + + EnumEnhMetaFile(NULL, hemf, get_emfplus_header_proc, &emfplusheader, NULL); + + if (emfplusheader.Header.Type == EmfPlusRecordTypeHeader) + { + if ((emfplusheader.Header.Flags & 1) == 1) + metafile_type = MetafileTypeEmfPlusDual; + else + metafile_type = MetafileTypeEmfPlusOnly; + } + else + metafile_type = MetafileTypeEmf; + + header->Type = metafile_type; + header->Size = emfheader.nBytes; + header->DpiX = (REAL)emfheader.szlDevice.cx * 25.4 / emfheader.szlMillimeters.cx; + header->DpiY = (REAL)emfheader.szlDevice.cy * 25.4 / emfheader.szlMillimeters.cy; + header->X = gdip_round((REAL)emfheader.rclFrame.left / 2540.0 * header->DpiX); + header->Y = gdip_round((REAL)emfheader.rclFrame.top / 2540.0 * header->DpiY); + header->Width = gdip_round((REAL)(emfheader.rclFrame.right - emfheader.rclFrame.left) / 2540.0 * header->DpiX); + header->Height = gdip_round((REAL)(emfheader.rclFrame.bottom - emfheader.rclFrame.top) / 2540.0 * header->DpiY); + header->EmfHeader = emfheader; + + if (metafile_type == MetafileTypeEmfPlusDual || metafile_type == MetafileTypeEmfPlusOnly) + { + header->Version = emfplusheader.Version; + header->EmfPlusFlags = emfplusheader.EmfPlusFlags; + header->EmfPlusHeaderSize = emfplusheader.Header.Size; + header->LogicalDpiX = emfplusheader.LogicalDpiX; + header->LogicalDpiY = emfplusheader.LogicalDpiY; + } + else + { + header->Version = emfheader.nVersion; + header->EmfPlusFlags = 0; + header->EmfPlusHeaderSize = 0; + header->LogicalDpiX = 0; + header->LogicalDpiY = 0; + }
return Ok; } diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c index ae4c713..82e803d 100644 --- a/dlls/gdiplus/tests/metafile.c +++ b/dlls/gdiplus/tests/metafile.c @@ -369,26 +369,26 @@ static void test_empty(void) memset(&header, 0xaa, sizeof(header)); stat = GdipGetMetafileHeaderFromEmf(hemf, &header); expect(Ok, stat); - todo_wine expect(MetafileTypeEmfPlusOnly, header.Type); + expect(MetafileTypeEmfPlusOnly, header.Type); expect(U(header).EmfHeader.nBytes, header.Size); - todo_wine ok(header.Version == 0xdbc01001 || header.Version == 0xdbc01002, "Unexpected version %x\n", header.Version); - todo_wine expect(1, header.EmfPlusFlags); /* reference device was display, not printer */ + ok(header.Version == 0xdbc01001 || header.Version == 0xdbc01002, "Unexpected version %x\n", header.Version); + expect(1, header.EmfPlusFlags); /* reference device was display, not printer */ todo_wine expectf(xres, header.DpiX); todo_wine expectf(xres, U(header).EmfHeader.szlDevice.cx / (REAL)U(header).EmfHeader.szlMillimeters.cx * 25.4); todo_wine expectf(yres, header.DpiY); todo_wine expectf(yres, U(header).EmfHeader.szlDevice.cy / (REAL)U(header).EmfHeader.szlMillimeters.cy * 25.4); expect(0, header.X); expect(0, header.Y); - todo_wine expect(100, header.Width); - todo_wine expect(100, header.Height); - todo_wine expect(28, header.EmfPlusHeaderSize); - todo_wine expect(96, header.LogicalDpiX); - todo_wine expect(96, header.LogicalDpiX); - todo_wine expect(EMR_HEADER, U(header).EmfHeader.iType); + expect(100, header.Width); + expect(100, header.Height); + expect(28, header.EmfPlusHeaderSize); + expect(96, header.LogicalDpiX); + expect(96, header.LogicalDpiX); + expect(EMR_HEADER, U(header).EmfHeader.iType); expect(0, U(header).EmfHeader.rclBounds.left); expect(0, U(header).EmfHeader.rclBounds.top); - todo_wine expect(-1, U(header).EmfHeader.rclBounds.right); - todo_wine expect(-1, U(header).EmfHeader.rclBounds.bottom); + expect(-1, U(header).EmfHeader.rclBounds.right); + expect(-1, U(header).EmfHeader.rclBounds.bottom); expect(0, U(header).EmfHeader.rclFrame.left); expect(0, U(header).EmfHeader.rclFrame.top); todo_wine expectf_(100.0, U(header).EmfHeader.rclFrame.right * xres / 2540.0, 2.0); @@ -716,9 +716,9 @@ static void test_emfonly(void) memset(&header, 0xaa, sizeof(header)); stat = GdipGetMetafileHeaderFromEmf(hemf, &header); expect(Ok, stat); - todo_wine expect(MetafileTypeEmf, header.Type); + expect(MetafileTypeEmf, header.Type); expect(U(header).EmfHeader.nBytes, header.Size); - todo_wine expect(0x10000, header.Version); + expect(0x10000, header.Version); expect(0, header.EmfPlusFlags); todo_wine expectf(xres, header.DpiX); todo_wine expectf(xres, U(header).EmfHeader.szlDevice.cx / (REAL)U(header).EmfHeader.szlMillimeters.cx * 25.4); @@ -726,16 +726,16 @@ static void test_emfonly(void) todo_wine expectf(yres, U(header).EmfHeader.szlDevice.cy / (REAL)U(header).EmfHeader.szlMillimeters.cy * 25.4); expect(0, header.X); expect(0, header.Y); - todo_wine expect(100, header.Width); - todo_wine expect(100, header.Height); + expect(100, header.Width); + expect(100, header.Height); expect(0, header.EmfPlusHeaderSize); expect(0, header.LogicalDpiX); expect(0, header.LogicalDpiX); - todo_wine expect(EMR_HEADER, U(header).EmfHeader.iType); - todo_wine expect(25, U(header).EmfHeader.rclBounds.left); - todo_wine expect(25, U(header).EmfHeader.rclBounds.top); - todo_wine expect(74, U(header).EmfHeader.rclBounds.right); - todo_wine expect(74, U(header).EmfHeader.rclBounds.bottom); + expect(EMR_HEADER, U(header).EmfHeader.iType); + expect(25, U(header).EmfHeader.rclBounds.left); + expect(25, U(header).EmfHeader.rclBounds.top); + expect(74, U(header).EmfHeader.rclBounds.right); + expect(74, U(header).EmfHeader.rclBounds.bottom); expect(0, U(header).EmfHeader.rclFrame.left); expect(0, U(header).EmfHeader.rclFrame.top); todo_wine expectf_(100.0, U(header).EmfHeader.rclFrame.right * xres / 2540.0, 2.0);