mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-20 08:38:01 +00:00
- Fix scaling when converting MF -> EMF.
- Tests for conversions (although not for the above bug).
This commit is contained in:
parent
be428abd3e
commit
794dbaa38c
|
@ -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,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
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,42 +2541,29 @@ 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;
|
|
||||||
mfp.mm = MM_ANISOTROPIC;
|
|
||||||
mfp.xExt = -1;
|
|
||||||
mfp.yExt = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
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) &&
|
if (lpmfp && (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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write the original METAFILE into the enhanced metafile.
|
* Write the original METAFILE into the enhanced metafile.
|
||||||
* It is encapsulated in a GDICOMMENT_WINDOWS_METAFILE record.
|
* It is encapsulated in a GDICOMMENT_WINDOWS_METAFILE record.
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
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 */
|
/* set the initial viewport:window ratio as 1:1 */
|
||||||
SetViewportExtEx(hdc, horzres, vertres, NULL);
|
xext = lpmfp->xExt*horzres/(100*horzsize);
|
||||||
SetWindowExtEx(hdc, horzres, vertres, NULL);
|
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 @@
|
||||||
|
|
||||||
#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 @@
|
||||||
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)
|
||||||
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)
|
||||||
test_mf_Blank();
|
test_mf_Blank();
|
||||||
test_mf_Graphics();
|
test_mf_Graphics();
|
||||||
test_mf_PatternBrush();
|
test_mf_PatternBrush();
|
||||||
|
|
||||||
|
/* For metafile conversions */
|
||||||
|
test_mf_conversions();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue