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( ...@@ -2244,6 +2244,7 @@ BOOL WINAPI EnumEnhMetaFile(
WIDTH(emh->rclFrame) * xSrcPixSize; WIDTH(emh->rclFrame) * xSrcPixSize;
yscale = (FLOAT) HEIGHT(*lpRect) * 100.0 / yscale = (FLOAT) HEIGHT(*lpRect) * 100.0 /
HEIGHT(emh->rclFrame) * ySrcPixSize; HEIGHT(emh->rclFrame) * ySrcPixSize;
TRACE("xscale = %f, yscale = %f\n", xscale, yscale);
xform.eM11 = xscale; xform.eM11 = xscale;
xform.eM12 = 0; xform.eM12 = 0;
...@@ -2527,14 +2528,12 @@ HENHMETAFILE WINAPI SetWinMetaFileBits(UINT cbBuffer, ...@@ -2527,14 +2528,12 @@ HENHMETAFILE WINAPI SetWinMetaFileBits(UINT cbBuffer,
) )
{ {
static const WCHAR szDisplayW[] = { 'D','I','S','P','L','A','Y','\0' }; static const WCHAR szDisplayW[] = { 'D','I','S','P','L','A','Y','\0' };
HMETAFILE hmf = 0; HMETAFILE hmf = NULL;
HENHMETAFILE ret = 0; HENHMETAFILE ret = NULL;
HDC hdc = 0, hdcdisp = 0; HDC hdc = NULL, hdcdisp = NULL;
METAFILEPICT mfp;
RECT rc, *prcFrame = NULL; RECT rc, *prcFrame = NULL;
gdi_mf_comment *mfcomment; gdi_mf_comment *mfcomment;
UINT mfcomment_size; UINT mfcomment_size;
INT horzres, vertres;
TRACE("(%d, %p, %p, %p)\n", cbBuffer, lpbBuffer, hdcRef, lpmfp); TRACE("(%d, %p, %p, %p)\n", cbBuffer, lpbBuffer, hdcRef, lpmfp);
...@@ -2542,40 +2541,27 @@ HENHMETAFILE WINAPI SetWinMetaFileBits(UINT cbBuffer, ...@@ -2542,40 +2541,27 @@ HENHMETAFILE WINAPI SetWinMetaFileBits(UINT cbBuffer,
if(!hmf) if(!hmf)
{ {
WARN("SetMetaFileBitsEx failed\n"); WARN("SetMetaFileBitsEx failed\n");
return 0; return NULL;
} }
if(!hdcRef) if(!hdcRef)
hdcRef = hdcdisp = CreateDCW(szDisplayW, NULL, NULL, NULL); hdcRef = hdcdisp = CreateDCW(szDisplayW, NULL, NULL, NULL);
if(!lpmfp) { if (lpmfp)
lpmfp = &mfp; TRACE("mm = %ld %ldx%ld\n", lpmfp->mm, lpmfp->xExt, lpmfp->yExt);
mfp.mm = MM_ANISOTROPIC;
mfp.xExt = -1;
mfp.yExt = -1;
}
TRACE("mm = %ld %ldx%ld\n", lpmfp->mm, lpmfp->xExt, lpmfp->yExt); if (lpmfp && (lpmfp->mm == MM_ISOTROPIC || lpmfp->mm == MM_ANISOTROPIC))
{
if((lpmfp->mm == MM_ISOTROPIC || lpmfp->mm == MM_ANISOTROPIC) &&
(lpmfp->xExt > 0) && (lpmfp->yExt > 0)) {
rc.left = rc.top = 0; rc.left = rc.top = 0;
rc.right = lpmfp->xExt; rc.right = lpmfp->xExt;
rc.bottom = lpmfp->yExt; rc.bottom = lpmfp->yExt;
prcFrame = &rc; prcFrame = &rc;
} }
if(!(hdc = CreateEnhMetaFileW(hdcRef, NULL, prcFrame, NULL))) { if(!(hdc = CreateEnhMetaFileW(hdcRef, NULL, prcFrame, NULL)))
{
ERR("CreateEnhMetaFile fails?\n"); ERR("CreateEnhMetaFile fails?\n");
goto end; goto end;
}
horzres = GetDeviceCaps(hdcRef, HORZRES);
vertres = GetDeviceCaps(hdcRef, VERTRES);
if(hdcdisp) {
DeleteDC(hdcdisp);
hdcRef = 0;
} }
/* /*
...@@ -2597,17 +2583,30 @@ HENHMETAFILE WINAPI SetWinMetaFileBits(UINT cbBuffer, ...@@ -2597,17 +2583,30 @@ HENHMETAFILE WINAPI SetWinMetaFileBits(UINT cbBuffer,
HeapFree(GetProcessHeap(), 0, mfcomment); HeapFree(GetProcessHeap(), 0, mfcomment);
} }
if(lpmfp->mm != MM_TEXT) if(lpmfp && lpmfp->mm != MM_TEXT)
SetMapMode(hdc, lpmfp->mm); SetMapMode(hdc, lpmfp->mm);
/* set the initial viewport:window ratio as 1:1 */ if (lpmfp && (lpmfp->mm == MM_ISOTROPIC || lpmfp->mm == MM_ANISOTROPIC))
SetViewportExtEx(hdc, horzres, vertres, NULL); {
SetWindowExtEx(hdc, horzres, vertres, NULL); 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); PlayMetaFile(hdc, hmf);
ret = CloseEnhMetaFile(hdc); ret = CloseEnhMetaFile(hdc);
end: end:
if (hdcdisp) DeleteDC(hdcdisp);
DeleteMetaFile(hmf); DeleteMetaFile(hmf);
return ret; return ret;
} }
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <math.h>
#include "wine/test.h" #include "wine/test.h"
#include "winbase.h" #include "winbase.h"
...@@ -30,6 +31,10 @@ ...@@ -30,6 +31,10 @@
static LOGFONTA orig_lf; static LOGFONTA orig_lf;
static BOOL emr_processed = FALSE; 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, static int CALLBACK emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
const ENHMETARECORD *emr, int n_objs, LPARAM param) const ENHMETARECORD *emr, int n_objs, LPARAM param)
{ {
...@@ -438,6 +443,125 @@ static void test_mf_PatternBrush(void) ...@@ -438,6 +443,125 @@ static void test_mf_PatternBrush(void)
HeapFree (GetProcessHeap(), 0, orig_lb); 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) START_TEST(metafile)
{ {
/* For enhanced metafiles (enhmfdrv) */ /* For enhanced metafiles (enhmfdrv) */
...@@ -447,4 +571,7 @@ START_TEST(metafile) ...@@ -447,4 +571,7 @@ START_TEST(metafile)
test_mf_Blank(); test_mf_Blank();
test_mf_Graphics(); test_mf_Graphics();
test_mf_PatternBrush(); 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