[PATCH] gdi32/enhmfdrv: Fix scaling factors for EMR_EXTTEXTOUTW
Alexander Kochetkov
al.kochet at gmail.com
Fri Feb 18 17:09:57 CST 2011
The patch fixes one problem related to bug #22996.
-------------- next part --------------
From c39646418c896fd2b4d29135a4e9744f61d2e857 Mon Sep 17 00:00:00 2001
From: Alexander Kochetkov <al.kochet at gmail.com>
Date: Sat, 19 Feb 2011 01:56:01 +0300
Subject: [PATCH] gdi32/enhmfdrv: Fix scaling factors for EMR_EXTTEXTOUTW
---
dlls/gdi32/enhmfdrv/graphics.c | 30 ++++++++-
dlls/gdi32/tests/metafile.c | 136 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 162 insertions(+), 4 deletions(-)
diff --git a/dlls/gdi32/enhmfdrv/graphics.c b/dlls/gdi32/enhmfdrv/graphics.c
index e066d0d..95a8353 100644
--- a/dlls/gdi32/enhmfdrv/graphics.c
+++ b/dlls/gdi32/enhmfdrv/graphics.c
@@ -728,6 +728,8 @@ BOOL CDECL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
int textHeight = 0;
int textWidth = 0;
const UINT textAlign = GetTextAlign(physDev->hdc);
+ const INT graphicsMode = GetGraphicsMode(physDev->hdc);
+ FLOAT exScale, eyScale;
nSize = sizeof(*pemr) + ((count+1) & ~1) * sizeof(WCHAR) + count * sizeof(INT);
@@ -735,12 +737,32 @@ BOOL CDECL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
wine_dbgstr_rect(lprect), count, nSize);
pemr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nSize);
+ if (graphicsMode == GM_COMPATIBLE)
+ {
+ const INT horzSize = GetDeviceCaps(physDev->hdc, HORZSIZE);
+ const INT horzRes = GetDeviceCaps(physDev->hdc, HORZRES);
+ const INT vertSize = GetDeviceCaps(physDev->hdc, VERTSIZE);
+ const INT vertRes = GetDeviceCaps(physDev->hdc, VERTRES);
+ SIZE wndext, vportext;
+
+ GetViewportExtEx(physDev->hdc, &vportext);
+ GetWindowExtEx(physDev->hdc, &wndext);
+ exScale = 100.0 * ((FLOAT)horzSize / (FLOAT)horzRes) /
+ ((FLOAT)wndext.cx / (FLOAT)vportext.cx);
+ eyScale = 100.0 * ((FLOAT)vertSize / (FLOAT)vertRes) /
+ ((FLOAT)wndext.cy / (FLOAT)vportext.cy);
+ }
+ else
+ {
+ exScale = 0.0;
+ eyScale = 0.0;
+ }
+
pemr->emr.iType = EMR_EXTTEXTOUTW;
pemr->emr.nSize = nSize;
-
- pemr->iGraphicsMode = GetGraphicsMode(physDev->hdc);
- pemr->exScale = pemr->eyScale = 1.0; /* FIXME */
-
+ pemr->iGraphicsMode = graphicsMode;
+ pemr->exScale = exScale;
+ pemr->eyScale = eyScale;
pemr->emrtext.ptlReference.x = x;
pemr->emrtext.ptlReference.y = y;
pemr->emrtext.nChars = count;
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index a4630f1..9ccb9ce 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -264,6 +264,141 @@ static void test_ExtTextOut(void)
DestroyWindow(hwnd);
}
+struct eto_scale_test_record
+{
+ INT graphics_mode;
+ INT map_mode;
+ double ex_scale;
+ double ey_scale;
+ BOOL processed;
+};
+
+static int CALLBACK eto_scale_enum_proc(HDC hdc, HANDLETABLE *handle_table,
+ const ENHMETARECORD *emr, int n_objs, LPARAM param)
+{
+ struct eto_scale_test_record *test = (struct eto_scale_test_record*)param;
+
+ if (emr->iType == EMR_EXTTEXTOUTW)
+ {
+ const EMREXTTEXTOUTW *pExtTextOutW = (const EMREXTTEXTOUTW *)emr;
+ trace("gm %d, mm %d, scale %f, %f, expected %f, %f\n",
+ test->graphics_mode, test->map_mode,
+ pExtTextOutW->exScale, pExtTextOutW->eyScale,
+ test->ex_scale, test->ey_scale);
+ ok(fabs(test->ex_scale - pExtTextOutW->exScale) < 0.001,
+ "Got exScale %f, expected %f\n", pExtTextOutW->exScale, test->ex_scale);
+ ok(fabs(test->ey_scale - pExtTextOutW->eyScale) < 0.001,
+ "Got eyScale %f, expected %f\n", pExtTextOutW->eyScale, test->ey_scale);
+ test->processed = TRUE;
+ }
+
+ return 1;
+}
+
+static void test_ExtTextOutScale(void)
+{
+ const RECT rc = { 0, 0, 100, 100 };
+ const WCHAR str[] = {'a',0 };
+ struct eto_scale_test_record test;
+ HDC hdcDisplay, hdcMetafile;
+ HENHMETAFILE hMetafile;
+ HWND hwnd;
+ SIZE wndext, vportext;
+ int horzSize, vertSize, horzRes, vertRes;
+ int ret;
+ int i;
+
+ hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
+ 0, 0, 200, 200, 0, 0, 0, NULL);
+ ok(hwnd != 0, "CreateWindowExA failed\n");
+
+ hdcDisplay = GetDC(hwnd);
+ ok(hdcDisplay != 0, "GetDC failed\n");
+
+ horzSize = GetDeviceCaps(hdcDisplay, HORZSIZE);
+ horzRes = GetDeviceCaps(hdcDisplay, HORZRES);
+ vertSize = GetDeviceCaps(hdcDisplay, VERTSIZE);
+ vertRes = GetDeviceCaps(hdcDisplay, VERTRES);
+ ok(horzSize && horzRes && vertSize && vertRes, "GetDeviceCaps failed\n");
+
+ for (i = 0; i < 16; i++)
+ {
+ test.graphics_mode = i / 8 + 1;
+ test.map_mode = i % 8 + 1;
+
+ ret = SetGraphicsMode(hdcDisplay, test.graphics_mode);
+ ok(ret, "SetGraphicsMode failed\n");
+ ret = SetMapMode(hdcDisplay, test.map_mode);
+ ok(ret, "SetMapMode failed\n");
+
+ if ((test.map_mode == MM_ISOTROPIC) || (test.map_mode == MM_ANISOTROPIC))
+ {
+ ret = SetWindowExtEx(hdcDisplay, 1, 1, NULL);
+ ok(ret, "SetWindowExtEx failed\n");
+ ret = SetViewportExtEx(hdcDisplay, -20, -10, NULL);
+ ok(ret, "SetViewportExtEx failed\n");
+ }
+
+ ret = GetViewportExtEx(hdcDisplay, &vportext);
+ ok(ret, "GetViewportExtEx failed\n");
+ ret = GetWindowExtEx(hdcDisplay, &wndext);
+ ok(ret, "GetWindowExtEx failed\n");
+
+ trace("gm %d, mm %d, wnd %d,%d, vp %d,%d horz %d,%d vert %d,%d\n",
+ test.graphics_mode, test.map_mode,
+ wndext.cx, wndext.cy, vportext.cx, vportext.cy,
+ horzSize, horzRes, vertSize, vertRes);
+
+ if (test.graphics_mode == GM_COMPATIBLE)
+ {
+ test.ex_scale = 100.0 * ((FLOAT)horzSize / (FLOAT)horzRes) /
+ ((FLOAT)wndext.cx / (FLOAT)vportext.cx);
+ test.ey_scale = 100.0 * ((FLOAT)vertSize / (FLOAT)vertRes) /
+ ((FLOAT)wndext.cy / (FLOAT)vportext.cy);
+ }
+ else
+ {
+ test.ex_scale = 0.0;
+ test.ey_scale = 0.0;
+ }
+
+ hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
+ ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
+
+ ret = SetGraphicsMode(hdcMetafile, test.graphics_mode);
+ ok(ret, "SetGraphicsMode failed\n");
+ ret = SetMapMode(hdcMetafile, test.map_mode);
+ ok(ret, "SetMapMode failed\n");
+
+ if ((test.map_mode == MM_ISOTROPIC) || (test.map_mode == MM_ANISOTROPIC))
+ {
+ ret = SetWindowExtEx(hdcMetafile, 1, 1, NULL);
+ ok(ret, "SetWindowExtEx failed\n");
+ ret = SetViewportExtEx(hdcMetafile, -20, -10, NULL);
+ ok(ret, "SetViewportExtEx failed\n");
+ }
+
+ ret = ExtTextOutW(hdcMetafile, 0, 0, 0, 0, str, 1, NULL);
+ ok(ret, "ExtTextOutW failed\n");
+
+ hMetafile = CloseEnhMetaFile(hdcMetafile);
+ ok(hMetafile != 0, "CloseEnhMetaFile failed\n");
+
+ test.processed = 0;
+ ret = EnumEnhMetaFile(hdcDisplay, hMetafile, eto_scale_enum_proc, &test, &rc);
+ ok(ret, "EnumEnhMetaFile failed\n");
+ ok(test.processed, "EnumEnhMetaFile couldn't find EMR_EXTTEXTOUTW record\n");
+
+ ret = DeleteEnhMetaFile(hMetafile);
+ ok(ret, "DeleteEnhMetaFile failed\n");
+ }
+
+ ret = ReleaseDC(hwnd, hdcDisplay);
+ ok(ret, "ReleaseDC failed\n");
+ DestroyWindow(hwnd);
+}
+
+
static void check_dc_state(HDC hdc, int restore_no,
int wnd_org_x, int wnd_org_y, int wnd_ext_x, int wnd_ext_y,
int vp_org_x, int vp_org_y, int vp_ext_x, int vp_ext_y)
@@ -2779,6 +2914,7 @@ START_TEST(metafile)
/* For enhanced metafiles (enhmfdrv) */
test_ExtTextOut();
+ test_ExtTextOutScale();
test_SaveDC();
test_emf_BitBlt();
--
1.7.0.4
More information about the wine-patches
mailing list