Commit 794dbaa3 authored by Robert Shearman's avatar Robert Shearman Committed by Alexandre Julliard

- Fix scaling when converting MF -> EMF.

- Tests for conversions (although not for the above bug).
parent be428abd
......@@ -2244,6 +2244,7 @@ BOOL WINAPI EnumEnhMetaFile(
WIDTH(emh->rclFrame) * xSrcPixSize;
yscale = (FLOAT) HEIGHT(*lpRect) * 100.0 /
HEIGHT(emh->rclFrame) * ySrcPixSize;
TRACE("xscale = %f, yscale = %f\n", xscale, yscale);
xform.eM11 = xscale;
xform.eM12 = 0;
......@@ -2527,14 +2528,12 @@ HENHMETAFILE WINAPI SetWinMetaFileBits(UINT cbBuffer,
)
{
static const WCHAR szDisplayW[] = { 'D','I','S','P','L','A','Y','\0' };
HMETAFILE hmf = 0;
HENHMETAFILE ret = 0;
HDC hdc = 0, hdcdisp = 0;
METAFILEPICT mfp;
HMETAFILE hmf = NULL;
HENHMETAFILE ret = NULL;
HDC hdc = NULL, hdcdisp = NULL;
RECT rc, *prcFrame = NULL;
gdi_mf_comment *mfcomment;
UINT mfcomment_size;
INT horzres, vertres;
TRACE("(%d, %p, %p, %p)\n", cbBuffer, lpbBuffer, hdcRef, lpmfp);
......@@ -2542,40 +2541,27 @@ HENHMETAFILE WINAPI SetWinMetaFileBits(UINT cbBuffer,
if(!hmf)
{
WARN("SetMetaFileBitsEx failed\n");
return 0;
return NULL;
}
if(!hdcRef)
hdcRef = hdcdisp = CreateDCW(szDisplayW, NULL, NULL, NULL);
if(!lpmfp) {
lpmfp = &mfp;
mfp.mm = MM_ANISOTROPIC;
mfp.xExt = -1;
mfp.yExt = -1;
}
if (lpmfp)
TRACE("mm = %ld %ldx%ld\n", lpmfp->mm, lpmfp->xExt, lpmfp->yExt);
TRACE("mm = %ld %ldx%ld\n", lpmfp->mm, lpmfp->xExt, lpmfp->yExt);
if((lpmfp->mm == MM_ISOTROPIC || lpmfp->mm == MM_ANISOTROPIC) &&
(lpmfp->xExt > 0) && (lpmfp->yExt > 0)) {
if (lpmfp && (lpmfp->mm == MM_ISOTROPIC || lpmfp->mm == MM_ANISOTROPIC))
{
rc.left = rc.top = 0;
rc.right = lpmfp->xExt;
rc.bottom = lpmfp->yExt;
prcFrame = &rc;
rc.right = lpmfp->xExt;
rc.bottom = lpmfp->yExt;
prcFrame = &rc;
}
if(!(hdc = CreateEnhMetaFileW(hdcRef, NULL, prcFrame, NULL))) {
if(!(hdc = CreateEnhMetaFileW(hdcRef, NULL, prcFrame, NULL)))
{
ERR("CreateEnhMetaFile fails?\n");
goto end;
}
horzres = GetDeviceCaps(hdcRef, HORZRES);
vertres = GetDeviceCaps(hdcRef, VERTRES);
if(hdcdisp) {
DeleteDC(hdcdisp);
hdcRef = 0;
goto end;
}
/*
......@@ -2597,17 +2583,30 @@ HENHMETAFILE WINAPI SetWinMetaFileBits(UINT cbBuffer,
HeapFree(GetProcessHeap(), 0, mfcomment);
}
if(lpmfp->mm != MM_TEXT)
if(lpmfp && lpmfp->mm != MM_TEXT)
SetMapMode(hdc, lpmfp->mm);
/* set the initial viewport:window ratio as 1:1 */
SetViewportExtEx(hdc, horzres, vertres, NULL);
SetWindowExtEx(hdc, horzres, vertres, NULL);
if (lpmfp && (lpmfp->mm == MM_ISOTROPIC || lpmfp->mm == MM_ANISOTROPIC))
{
INT horzres, vertres, horzsize, vertsize, xext, yext;
horzres = GetDeviceCaps(hdcRef, HORZRES);
vertres = GetDeviceCaps(hdcRef, VERTRES);
horzsize = GetDeviceCaps(hdcRef, HORZSIZE);
vertsize = GetDeviceCaps(hdcRef, VERTSIZE);
/* set the initial viewport:window ratio as 1:1 */
xext = lpmfp->xExt*horzres/(100*horzsize);
yext = lpmfp->yExt*vertres/(100*vertsize);
SetViewportExtEx(hdc, xext, yext, NULL);
SetWindowExtEx(hdc, xext, yext, NULL);
}
PlayMetaFile(hdc, hmf);
ret = CloseEnhMetaFile(hdc);
end:
if (hdcdisp) DeleteDC(hdcdisp);
DeleteMetaFile(hmf);
return ret;
}
......@@ -20,6 +20,7 @@
#include <assert.h>
#include <stdio.h>
#include <math.h>
#include "wine/test.h"
#include "winbase.h"
......@@ -30,6 +31,10 @@
static LOGFONTA orig_lf;
static BOOL emr_processed = FALSE;
/* Arbitrarily chosen values for the second co-ordinate of a metafile line */
#define LINE_X 55.0f
#define LINE_Y 15.0f
static int CALLBACK emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
const ENHMETARECORD *emr, int n_objs, LPARAM param)
{
......@@ -438,6 +443,125 @@ static void test_mf_PatternBrush(void)
HeapFree (GetProcessHeap(), 0, orig_lb);
}
static INT CALLBACK EmfMmTextEnumProc(HDC hdc, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, INT nObj, LPARAM lpData)
{
POINT mapping[2] = { { 0, 0 }, { 1000, 1000 } };
LPtoDP(hdc, mapping, 2);
trace("Meta record: iType = %ld, (%ld,%ld)-(%ld,%ld)\n", lpEMFR->iType, mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y);
if (lpEMFR->iType == EMR_LINETO)
{
FLOAT xSrcPixSize, ySrcPixSize, xscale, yscale;
INT xframe = LINE_X * (float)GetDeviceCaps(hdc, HORZSIZE) * 100.0f / (float)GetDeviceCaps(hdc, HORZRES);
INT yframe = LINE_Y * (float)GetDeviceCaps(hdc, VERTSIZE) * 100.0f / (float)GetDeviceCaps(hdc, VERTRES);
INT x0 = 0;
INT y0 = 0;
INT x1;
INT y1;
xSrcPixSize = (FLOAT) GetDeviceCaps(hdc, HORZSIZE) / GetDeviceCaps(hdc, HORZRES);
ySrcPixSize = (FLOAT) GetDeviceCaps(hdc, VERTSIZE) / GetDeviceCaps(hdc, VERTRES);
xscale = (FLOAT) 1000 * 100.0 /
xframe * xSrcPixSize;
yscale = (FLOAT) 1000 * 100.0 /
yframe * ySrcPixSize;
x1 = (INT)floor(xscale * 100.0 + 0.5f);
y1 = (INT)floor(yscale * 100.0 + 0.5f);
ok(mapping[0].x == x0 && mapping[0].y == y0 && mapping[1].x == x1 && mapping[1].y == y1,
"(%ld,%ld)->(%ld,%ld), expected (%d,%d)->(%d,%d)\n",
mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y,
x0, y0, x1, y1);
}
PlayEnhMetaFileRecord(hdc, lpHTable, lpEMFR, nObj);
return TRUE;
}
static INT CALLBACK EmfMmAnisotropicEnumProc(HDC hdc, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, INT nObj, LPARAM lpData)
{
POINT mapping[2] = { { 0, 0 }, { 1000, 1000 } };
LPtoDP(hdc, mapping, 2);
trace("Meta record: iType = %ld, (%ld,%ld)-(%ld,%ld)\n", lpEMFR->iType, mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y);
if (lpEMFR->iType == EMR_LINETO)
{
INT x0 = MulDiv(0, GetDeviceCaps(hdc, HORZSIZE) * 100, GetDeviceCaps(hdc, HORZRES));
INT y0 = MulDiv(0, GetDeviceCaps(hdc, VERTSIZE) * 100, GetDeviceCaps(hdc, VERTRES));
INT x1 = MulDiv(1000, GetDeviceCaps(hdc, HORZSIZE) * 100, GetDeviceCaps(hdc, HORZRES));
INT y1 = MulDiv(1000, GetDeviceCaps(hdc, VERTSIZE) * 100, GetDeviceCaps(hdc, VERTRES));
ok(mapping[0].x == x0 && mapping[0].y == y0 && mapping[1].x == x1 && mapping[1].y == y1,
"(%ld,%ld)->(%ld,%ld), expected (%d,%d)->(%d,%d)\n",
mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y,
x0, y0, x1, y1);
}
PlayEnhMetaFileRecord(hdc, lpHTable, lpEMFR, nObj);
return TRUE;
}
static HENHMETAFILE create_converted_emf(const METAFILEPICT *mfp)
{
HDC hdcMf;
HMETAFILE hmf;
BOOL ret;
UINT size;
LPBYTE pBits;
hdcMf = CreateMetaFile(NULL);
ok(hdcMf != NULL, "CreateMetaFile failed with error %ld\n", GetLastError());
ret = LineTo(hdcMf, (INT)LINE_X, (INT)LINE_Y);
ok(ret, "LineTo failed with error %ld\n", GetLastError());
hmf = CloseMetaFile(hdcMf);
ok(hmf != NULL, "CloseMetaFile failed with error %ld\n", GetLastError());
size = GetMetaFileBitsEx(hmf, 0, NULL);
ok(size, "GetMetaFileBitsEx failed with error %ld\n", GetLastError());
pBits = HeapAlloc(GetProcessHeap(), 0, size);
GetMetaFileBitsEx(hmf, size, pBits);
DeleteMetaFile(hmf);
return SetWinMetaFileBits(size, pBits, NULL, mfp);
}
static void test_mf_conversions()
{
trace("Testing MF->EMF conversion (MM_ANISOTROPIC)\n");
{
HDC hdcOffscreen = CreateCompatibleDC(NULL);
HENHMETAFILE hemf;
METAFILEPICT mfp;
RECT rect = { 0, 0, 100, 100 };
mfp.mm = MM_ANISOTROPIC;
mfp.xExt = 100;
mfp.yExt = 100;
mfp.hMF = NULL;
hemf = create_converted_emf(&mfp);
EnumEnhMetaFile(hdcOffscreen, hemf, EmfMmAnisotropicEnumProc, NULL, &rect);
DeleteEnhMetaFile(hemf);
DeleteDC(hdcOffscreen);
}
trace("Testing MF->EMF conversion (MM_TEXT)\n");
{
HDC hdcOffscreen = CreateCompatibleDC(NULL);
HENHMETAFILE hemf;
METAFILEPICT mfp;
RECT rect = { 0, 0, 100, 100 };
mfp.mm = MM_TEXT;
mfp.xExt = 0;
mfp.yExt = 0;
mfp.hMF = NULL;
hemf = create_converted_emf(&mfp);
EnumEnhMetaFile(hdcOffscreen, hemf, EmfMmTextEnumProc, NULL, &rect);
DeleteEnhMetaFile(hemf);
DeleteDC(hdcOffscreen);
}
trace("Testing MF->EMF conversion (NULL mfp)\n");
{
HDC hdcOffscreen = CreateCompatibleDC(NULL);
HENHMETAFILE hemf;
RECT rect = { 0, 0, 100, 100 };
hemf = create_converted_emf(NULL);
EnumEnhMetaFile(hdcOffscreen, hemf, EmfMmTextEnumProc, NULL, &rect);
DeleteEnhMetaFile(hemf);
DeleteDC(hdcOffscreen);
}
}
START_TEST(metafile)
{
/* For enhanced metafiles (enhmfdrv) */
......@@ -447,4 +571,7 @@ START_TEST(metafile)
test_mf_Blank();
test_mf_Graphics();
test_mf_PatternBrush();
/* For metafile conversions */
test_mf_conversions();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment