gdiplus: Add initial GdipGetMetafileHeaderFromEmf implementation.
Signed-off-by: Vincent Povirk <vincent@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
09c16eb5d3
commit
233f1c1b88
|
@ -941,18 +941,87 @@ GpStatus WINGDIPAPI GdipGetMetafileHeaderFromMetafile(GpMetafile * metafile,
|
||||||
return Ok;
|
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)
|
MetafileHeader *header)
|
||||||
{
|
{
|
||||||
static int calls;
|
ENHMETAHEADER3 emfheader;
|
||||||
|
EmfPlusHeader emfplusheader;
|
||||||
|
MetafileType metafile_type;
|
||||||
|
|
||||||
if(!hEmf || !header)
|
TRACE("(%p,%p)\n", hemf, header);
|
||||||
|
|
||||||
|
if(!hemf || !header)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
if(!(calls++))
|
if (GetEnhMetaFileHeader(hemf, sizeof(emfheader), (ENHMETAHEADER*)&emfheader) == 0)
|
||||||
FIXME("not implemented\n");
|
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;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
|
@ -369,26 +369,26 @@ static void test_empty(void)
|
||||||
memset(&header, 0xaa, sizeof(header));
|
memset(&header, 0xaa, sizeof(header));
|
||||||
stat = GdipGetMetafileHeaderFromEmf(hemf, &header);
|
stat = GdipGetMetafileHeaderFromEmf(hemf, &header);
|
||||||
expect(Ok, stat);
|
expect(Ok, stat);
|
||||||
todo_wine expect(MetafileTypeEmfPlusOnly, header.Type);
|
expect(MetafileTypeEmfPlusOnly, header.Type);
|
||||||
expect(U(header).EmfHeader.nBytes, header.Size);
|
expect(U(header).EmfHeader.nBytes, header.Size);
|
||||||
todo_wine ok(header.Version == 0xdbc01001 || header.Version == 0xdbc01002, "Unexpected version %x\n", header.Version);
|
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 */
|
expect(1, header.EmfPlusFlags); /* reference device was display, not printer */
|
||||||
todo_wine expectf(xres, header.DpiX);
|
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(xres, U(header).EmfHeader.szlDevice.cx / (REAL)U(header).EmfHeader.szlMillimeters.cx * 25.4);
|
||||||
todo_wine expectf(yres, header.DpiY);
|
todo_wine expectf(yres, header.DpiY);
|
||||||
todo_wine expectf(yres, U(header).EmfHeader.szlDevice.cy / (REAL)U(header).EmfHeader.szlMillimeters.cy * 25.4);
|
todo_wine expectf(yres, U(header).EmfHeader.szlDevice.cy / (REAL)U(header).EmfHeader.szlMillimeters.cy * 25.4);
|
||||||
expect(0, header.X);
|
expect(0, header.X);
|
||||||
expect(0, header.Y);
|
expect(0, header.Y);
|
||||||
todo_wine expect(100, header.Width);
|
expect(100, header.Width);
|
||||||
todo_wine expect(100, header.Height);
|
expect(100, header.Height);
|
||||||
todo_wine expect(28, header.EmfPlusHeaderSize);
|
expect(28, header.EmfPlusHeaderSize);
|
||||||
todo_wine expect(96, header.LogicalDpiX);
|
expect(96, header.LogicalDpiX);
|
||||||
todo_wine expect(96, header.LogicalDpiX);
|
expect(96, header.LogicalDpiX);
|
||||||
todo_wine expect(EMR_HEADER, U(header).EmfHeader.iType);
|
expect(EMR_HEADER, U(header).EmfHeader.iType);
|
||||||
expect(0, U(header).EmfHeader.rclBounds.left);
|
expect(0, U(header).EmfHeader.rclBounds.left);
|
||||||
expect(0, U(header).EmfHeader.rclBounds.top);
|
expect(0, U(header).EmfHeader.rclBounds.top);
|
||||||
todo_wine expect(-1, U(header).EmfHeader.rclBounds.right);
|
expect(-1, U(header).EmfHeader.rclBounds.right);
|
||||||
todo_wine expect(-1, U(header).EmfHeader.rclBounds.bottom);
|
expect(-1, U(header).EmfHeader.rclBounds.bottom);
|
||||||
expect(0, U(header).EmfHeader.rclFrame.left);
|
expect(0, U(header).EmfHeader.rclFrame.left);
|
||||||
expect(0, U(header).EmfHeader.rclFrame.top);
|
expect(0, U(header).EmfHeader.rclFrame.top);
|
||||||
todo_wine expectf_(100.0, U(header).EmfHeader.rclFrame.right * xres / 2540.0, 2.0);
|
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));
|
memset(&header, 0xaa, sizeof(header));
|
||||||
stat = GdipGetMetafileHeaderFromEmf(hemf, &header);
|
stat = GdipGetMetafileHeaderFromEmf(hemf, &header);
|
||||||
expect(Ok, stat);
|
expect(Ok, stat);
|
||||||
todo_wine expect(MetafileTypeEmf, header.Type);
|
expect(MetafileTypeEmf, header.Type);
|
||||||
expect(U(header).EmfHeader.nBytes, header.Size);
|
expect(U(header).EmfHeader.nBytes, header.Size);
|
||||||
todo_wine expect(0x10000, header.Version);
|
expect(0x10000, header.Version);
|
||||||
expect(0, header.EmfPlusFlags);
|
expect(0, header.EmfPlusFlags);
|
||||||
todo_wine expectf(xres, header.DpiX);
|
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(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);
|
todo_wine expectf(yres, U(header).EmfHeader.szlDevice.cy / (REAL)U(header).EmfHeader.szlMillimeters.cy * 25.4);
|
||||||
expect(0, header.X);
|
expect(0, header.X);
|
||||||
expect(0, header.Y);
|
expect(0, header.Y);
|
||||||
todo_wine expect(100, header.Width);
|
expect(100, header.Width);
|
||||||
todo_wine expect(100, header.Height);
|
expect(100, header.Height);
|
||||||
expect(0, header.EmfPlusHeaderSize);
|
expect(0, header.EmfPlusHeaderSize);
|
||||||
expect(0, header.LogicalDpiX);
|
expect(0, header.LogicalDpiX);
|
||||||
expect(0, header.LogicalDpiX);
|
expect(0, header.LogicalDpiX);
|
||||||
todo_wine expect(EMR_HEADER, U(header).EmfHeader.iType);
|
expect(EMR_HEADER, U(header).EmfHeader.iType);
|
||||||
todo_wine expect(25, U(header).EmfHeader.rclBounds.left);
|
expect(25, U(header).EmfHeader.rclBounds.left);
|
||||||
todo_wine expect(25, U(header).EmfHeader.rclBounds.top);
|
expect(25, U(header).EmfHeader.rclBounds.top);
|
||||||
todo_wine expect(74, U(header).EmfHeader.rclBounds.right);
|
expect(74, U(header).EmfHeader.rclBounds.right);
|
||||||
todo_wine expect(74, U(header).EmfHeader.rclBounds.bottom);
|
expect(74, U(header).EmfHeader.rclBounds.bottom);
|
||||||
expect(0, U(header).EmfHeader.rclFrame.left);
|
expect(0, U(header).EmfHeader.rclFrame.left);
|
||||||
expect(0, U(header).EmfHeader.rclFrame.top);
|
expect(0, U(header).EmfHeader.rclFrame.top);
|
||||||
todo_wine expectf_(100.0, U(header).EmfHeader.rclFrame.right * xres / 2540.0, 2.0);
|
todo_wine expectf_(100.0, U(header).EmfHeader.rclFrame.right * xres / 2540.0, 2.0);
|
||||||
|
|
Loading…
Reference in New Issue