[3/3] gdi32: Make generated EMFs fully match Windows ones
Dmitry Timoshkov
dmitry at codeweavers.com
Sun May 25 07:32:31 CDT 2008
Hello,
all this patch does is adds saving/restoring clipping region, and removes
saving/restoring current font on MF/EMF playing, doesn't write an original
metafile as a GDI comment EMF record if mapping mode is MM_TEXT, adds
saving/restoring current palette on old metafile creation (as the generated
EMFs show).
I had to change indentation of some parts of the code, and that makes
the patch look large.
As a result no compare_emf_bits() calls have the todo parameter set to TRUE.
I decided to not remove the todo parameter altogether to allow adding new
tests with possibly incompatible with Wine EMF structure.
Changelog:
gdi32: Make generated EMFs fully match Windows ones.
---
dlls/gdi32/enhmetafile.c | 89 +++++++++++++++++++++++-------------------
dlls/gdi32/metafile.c | 19 ++++++++-
dlls/gdi32/tests/metafile.c | 10 ++--
3 files changed, 70 insertions(+), 48 deletions(-)
diff --git a/dlls/gdi32/enhmetafile.c b/dlls/gdi32/enhmetafile.c
index 1041594..b20f442 100644
--- a/dlls/gdi32/enhmetafile.c
+++ b/dlls/gdi32/enhmetafile.c
@@ -2257,6 +2257,7 @@ BOOL WINAPI EnumEnhMetaFile(
HPEN hPen = NULL;
HBRUSH hBrush = NULL;
HFONT hFont = NULL;
+ HRGN hRgn = NULL;
enum_emh_data *info;
SIZE vp_size, win_size;
POINT vp_org, win_org;
@@ -2311,11 +2312,18 @@ BOOL WINAPI EnumEnhMetaFile(
GetWindowOrgEx(hdc, &win_org);
mapMode = GetMapMode(hdc);
- /* save the current pen, brush and font */
+ /* save DC */
hPen = GetCurrentObject(hdc, OBJ_PEN);
hBrush = GetCurrentObject(hdc, OBJ_BRUSH);
hFont = GetCurrentObject(hdc, OBJ_FONT);
+ hRgn = CreateRectRgn(0, 0, 0, 0);
+ if (!GetClipRgn(hdc, hRgn))
+ {
+ DeleteObject(hRgn);
+ hRgn = 0;
+ }
+
old_text_color = SetTextColor(hdc, RGB(0,0,0));
old_bk_color = SetBkColor(hdc, RGB(0xff, 0xff, 0xff));
old_align = SetTextAlign(hdc, 0);
@@ -2410,10 +2418,12 @@ BOOL WINAPI EnumEnhMetaFile(
SetBkColor(hdc, old_bk_color);
SetTextColor(hdc, old_text_color);
- /* restore pen, brush and font */
+ /* restore DC */
SelectObject(hdc, hBrush);
SelectObject(hdc, hPen);
SelectObject(hdc, hFont);
+ ExtSelectClipRgn(hdc, hRgn, RGN_COPY);
+ DeleteObject(hRgn);
SetWorldTransform(hdc, &savedXform);
if (savedMode)
@@ -2673,9 +2683,8 @@ HENHMETAFILE WINAPI SetWinMetaFileBits(UINT cbBuffer,
HENHMETAFILE ret = NULL;
HDC hdc = NULL, hdcdisp = NULL;
RECT rc, *prcFrame = NULL;
- gdi_mf_comment *mfcomment;
- UINT mfcomment_size;
LONG mm, xExt, yExt;
+ INT horzsize, vertsize, horzres, vertres;
TRACE("(%d, %p, %p, %p)\n", cbBuffer, lpbBuffer, hdcRef, lpmfp);
@@ -2736,49 +2745,49 @@ HENHMETAFILE WINAPI SetWinMetaFileBits(UINT cbBuffer,
* Write the original METAFILE into the enhanced metafile.
* It is encapsulated in a GDICOMMENT_WINDOWS_METAFILE record.
*/
- mfcomment_size = sizeof (gdi_mf_comment) + cbBuffer;
- mfcomment = HeapAlloc(GetProcessHeap(), 0, mfcomment_size);
- if(mfcomment)
- {
- mfcomment->ident = GDICOMMENT_IDENTIFIER;
- mfcomment->iComment = GDICOMMENT_WINDOWS_METAFILE;
- mfcomment->nVersion = 0x00000300;
- mfcomment->nChecksum = 0; /* FIXME */
- mfcomment->fFlags = 0;
- mfcomment->cbWinMetaFile = cbBuffer;
- memcpy(&mfcomment[1], lpbBuffer, cbBuffer);
- GdiComment(hdc, mfcomment_size, (BYTE*) mfcomment);
- HeapFree(GetProcessHeap(), 0, mfcomment);
- }
-
if (mm != MM_TEXT)
- SetMapMode(hdc, mm);
-
- if (mm == MM_ISOTROPIC || mm == MM_ANISOTROPIC)
{
- INT horzsize, vertsize, horzres, vertres;
+ gdi_mf_comment *mfcomment;
+ UINT mfcomment_size;
- horzsize = GetDeviceCaps(hdcRef, HORZSIZE);
- vertsize = GetDeviceCaps(hdcRef, VERTSIZE);
- horzres = GetDeviceCaps(hdcRef, HORZRES);
- vertres = GetDeviceCaps(hdcRef, VERTRES);
-
- if (!xExt || !yExt)
+ mfcomment_size = sizeof (gdi_mf_comment) + cbBuffer;
+ mfcomment = HeapAlloc(GetProcessHeap(), 0, mfcomment_size);
+ if (mfcomment)
{
- /* Use the whole device surface */
- xExt = horzres;
- yExt = vertres;
- }
- else
- {
- xExt = MulDiv(xExt, horzres, 100 * horzsize);
- yExt = MulDiv(yExt, vertres, 100 * vertsize);
+ mfcomment->ident = GDICOMMENT_IDENTIFIER;
+ mfcomment->iComment = GDICOMMENT_WINDOWS_METAFILE;
+ mfcomment->nVersion = 0x00000300;
+ mfcomment->nChecksum = 0; /* FIXME */
+ mfcomment->fFlags = 0;
+ mfcomment->cbWinMetaFile = cbBuffer;
+ memcpy(&mfcomment[1], lpbBuffer, cbBuffer);
+ GdiComment(hdc, mfcomment_size, (BYTE*) mfcomment);
+ HeapFree(GetProcessHeap(), 0, mfcomment);
}
+ SetMapMode(hdc, mm);
+ }
- /* set the initial viewport:window ratio as 1:1 */
- SetViewportExtEx(hdc, xExt, yExt, NULL);
- SetWindowExtEx(hdc, xExt, yExt, NULL);
+
+ horzsize = GetDeviceCaps(hdcRef, HORZSIZE);
+ vertsize = GetDeviceCaps(hdcRef, VERTSIZE);
+ horzres = GetDeviceCaps(hdcRef, HORZRES);
+ vertres = GetDeviceCaps(hdcRef, VERTRES);
+
+ if (!xExt || !yExt)
+ {
+ /* Use the whole device surface */
+ xExt = horzres;
+ yExt = vertres;
}
+ else
+ {
+ xExt = MulDiv(xExt, horzres, 100 * horzsize);
+ yExt = MulDiv(yExt, vertres, 100 * vertsize);
+ }
+
+ /* set the initial viewport:window ratio as 1:1 */
+ SetViewportExtEx(hdc, xExt, yExt, NULL);
+ SetWindowExtEx(hdc, xExt, yExt, NULL);
PlayMetaFile(hdc, hmf);
diff --git a/dlls/gdi32/metafile.c b/dlls/gdi32/metafile.c
index 56404a0..68ec203 100644
--- a/dlls/gdi32/metafile.c
+++ b/dlls/gdi32/metafile.c
@@ -396,6 +396,8 @@ BOOL MF_PlayMetaFile( HDC hdc, METAHEADER *mh)
HPEN hPen;
HBRUSH hBrush;
HFONT hFont;
+ HPALETTE hPal;
+ HRGN hRgn;
BOOL loaded = FALSE;
if (!mh) return FALSE;
@@ -405,10 +407,18 @@ BOOL MF_PlayMetaFile( HDC hdc, METAHEADER *mh)
loaded = TRUE;
}
- /* save the current pen, brush and font */
+ /* save DC */
hPen = GetCurrentObject(hdc, OBJ_PEN);
hBrush = GetCurrentObject(hdc, OBJ_BRUSH);
hFont = GetCurrentObject(hdc, OBJ_FONT);
+ hPal = GetCurrentObject(hdc, OBJ_PAL);
+
+ hRgn = CreateRectRgn(0, 0, 0, 0);
+ if (!GetClipRgn(hdc, hRgn))
+ {
+ DeleteObject(hRgn);
+ hRgn = 0;
+ }
/* create the handle table */
ht = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
@@ -436,9 +446,12 @@ BOOL MF_PlayMetaFile( HDC hdc, METAHEADER *mh)
PlayMetaFileRecord( hdc, ht, mr, mh->mtNoObjects );
}
- SelectObject(hdc, hBrush);
+ /* restore DC */
SelectObject(hdc, hPen);
- SelectObject(hdc, hFont);
+ SelectObject(hdc, hBrush);
+ SelectPalette(hdc, hPal, FALSE);
+ ExtSelectClipRgn(hdc, hRgn, RGN_COPY);
+ DeleteObject(hRgn);
/* free objects in handle table */
for(i = 0; i < mh->mtNoObjects; i++)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index 40c7445..5f295bb 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -1480,7 +1480,7 @@ static void test_emf_ExtTextOut_on_path(void)
* are there, but their contents don't match for different reasons.
*/
if (compare_emf_bits(hMetafile, EMF_TEXTOUT_ON_PATH_BITS, sizeof(EMF_TEXTOUT_ON_PATH_BITS),
- "emf_TextOut_on_path", FALSE, TRUE) != 0)
+ "emf_TextOut_on_path", FALSE, FALSE) != 0)
{
dump_emf_bits(hMetafile, "emf_TextOut_on_path");
dump_emf_records(hMetafile, "emf_TextOut_on_path");
@@ -1676,7 +1676,7 @@ static void test_emf_clipping(void)
ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
if (compare_emf_bits(hemf, EMF_CLIPPING, sizeof(EMF_CLIPPING),
- "emf_clipping", FALSE, TRUE) != 0)
+ "emf_clipping", FALSE, FALSE) != 0)
{
dump_emf_bits(hemf, "emf_clipping");
dump_emf_records(hemf, "emf_clipping");
@@ -1785,7 +1785,7 @@ static void test_mf_conversions(void)
hemf = create_converted_emf(&mfp);
if (compare_emf_bits(hemf, EMF_LINETO_MM_ANISOTROPIC_BITS, sizeof(EMF_LINETO_MM_ANISOTROPIC_BITS),
- "emf_LineTo MM_ANISOTROPIC", TRUE, TRUE) != 0)
+ "emf_LineTo MM_ANISOTROPIC", TRUE, FALSE) != 0)
{
dump_emf_bits(hemf, "emf_LineTo MM_ANISOTROPIC");
dump_emf_records(hemf, "emf_LineTo MM_ANISOTROPIC");
@@ -1810,7 +1810,7 @@ static void test_mf_conversions(void)
hemf = create_converted_emf(&mfp);
if (compare_emf_bits(hemf, EMF_LINETO_MM_TEXT_BITS, sizeof(EMF_LINETO_MM_TEXT_BITS),
- "emf_LineTo MM_TEXT", TRUE, TRUE) != 0)
+ "emf_LineTo MM_TEXT", TRUE, FALSE) != 0)
{
dump_emf_bits(hemf, "emf_LineTo MM_TEXT");
dump_emf_records(hemf, "emf_LineTo MM_TEXT");
@@ -1830,7 +1830,7 @@ static void test_mf_conversions(void)
hemf = create_converted_emf(NULL);
if (compare_emf_bits(hemf, EMF_LINETO_BITS, sizeof(EMF_LINETO_BITS),
- "emf_LineTo NULL", TRUE, TRUE) != 0)
+ "emf_LineTo NULL", TRUE, FALSE) != 0)
{
dump_emf_bits(hemf, "emf_LineTo NULL");
dump_emf_records(hemf, "emf_LineTo NULL");
--
1.5.5.1
More information about the wine-patches
mailing list