From: Aric Stewart Subject: [try3] gdi32: abc values remain the same despite any changes in layout direction or Viewport Message-Id: <52306330.9080103@codeweavers.com> Date: Wed, 11 Sep 2013 07:33:52 -0500 The TODO tests here are a result of errors in the freetype driver GetCharABCWidths Clean up tests a big, We only care if the sign changes not the value, the value could (and does on some windows versions) change as the viewport is scaled. --- dlls/gdi32/font.c | 30 +++++++++++----- dlls/gdi32/tests/font.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 114 insertions(+), 10 deletions(-) diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index cc66000..fbea9f7 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -2703,11 +2703,15 @@ BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar, ret = dev->funcs->pGetCharABCWidths( dev, firstChar, lastChar, abc ); if (ret) { +#define WDPTOLP(x) ((x<0)? \ + (-abs(INTERNAL_XDSTOWS(dc, (x)))): \ + (abs(INTERNAL_XDSTOWS(dc, (x))))) /* convert device units to logical */ for( i = firstChar; i <= lastChar; i++, abc++ ) { - abc->abcA = INTERNAL_XDSTOWS(dc, abc->abcA); - abc->abcB = INTERNAL_XDSTOWS(dc, abc->abcB); - abc->abcC = INTERNAL_XDSTOWS(dc, abc->abcC); + abc->abcA = WDPTOLP(abc->abcA); + abc->abcB = WDPTOLP(abc->abcB); + abc->abcC = WDPTOLP(abc->abcC); +#undef WDPTOLP } } @@ -2755,11 +2759,15 @@ BOOL WINAPI GetCharABCWidthsI( HDC hdc, UINT firstChar, UINT count, ret = dev->funcs->pGetCharABCWidthsI( dev, firstChar, count, pgi, abc ); if (ret) { +#define WDPTOLP(x) ((x<0)? \ + (-abs(INTERNAL_XDSTOWS(dc, (x)))): \ + (abs(INTERNAL_XDSTOWS(dc, (x))))) /* convert device units to logical */ for( i = 0; i < count; i++, abc++ ) { - abc->abcA = INTERNAL_XDSTOWS(dc, abc->abcA); - abc->abcB = INTERNAL_XDSTOWS(dc, abc->abcB); - abc->abcC = INTERNAL_XDSTOWS(dc, abc->abcC); + abc->abcA = WDPTOLP(abc->abcA); + abc->abcB = WDPTOLP(abc->abcB); + abc->abcC = WDPTOLP(abc->abcC); +#undef WDPTOLP } } @@ -3356,13 +3364,17 @@ BOOL WINAPI GetCharABCWidthsFloatW( HDC hdc, UINT first, UINT last, LPABCFLOAT a ret = dev->funcs->pGetCharABCWidths( dev, first, last, abc ); if (ret) { +#define WDPTOLP(x) ((x<0)? \ + (-abs((x) * dc->xformVport2World.eM11)): \ + (abs((x) * dc->xformVport2World.eM11))) /* convert device units to logical */ for (i = first; i <= last; i++, abcf++) { - abcf->abcfA = abc[i - first].abcA * dc->xformVport2World.eM11; - abcf->abcfB = abc[i - first].abcB * dc->xformVport2World.eM11; - abcf->abcfC = abc[i - first].abcC * dc->xformVport2World.eM11; + abcf->abcfA = WDPTOLP(abc[i - first].abcA); + abcf->abcfB = WDPTOLP(abc[i - first].abcB); + abcf->abcfC = WDPTOLP(abc[i - first].abcC); } +#undef WDPTOLP } HeapFree( GetProcessHeap(), 0, abc ); diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 84e47ed..97156b5 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -1109,17 +1109,45 @@ static int CALLBACK create_font_proc(const LOGFONT *lpelfe, return 1; } + +static void helper_ABCWidths(HDC hdc, WORD *glyphs, ABC *base_abci, ABC *base_abcw, ABCFLOAT *base_abcf, INT todo) +{ + ABC abc[1]; + ABCFLOAT abcf[1]; + BOOL ret = FALSE; + + ret = pGetCharABCWidthsI(hdc, 0, 1, glyphs, abc); + winetest_ok(ret, "GetCharABCWidthsI should have succeeded\n"); + winetest_ok ((INT)abc->abcB > 0, "abcB should be positive\n"); + if (todo) todo_wine winetest_ok(abc->abcA * base_abci->abcA >= 0, "abcA's sign should be unchanged\n"); else winetest_ok(abc->abcA * base_abci->abcA >= 0, "abcA's sign should be unchanged\n"); + if (todo) todo_wine winetest_ok(abc->abcC * base_abci->abcC >= 0, "abcC's sign should be unchanged\n"); else winetest_ok(abc->abcC * base_abci->abcC >= 0, "abcC's sign should be unchanged\n"); + + ret = pGetCharABCWidthsW(hdc, 'i', 'i', abc); + winetest_ok(ret, "GetCharABCWidthsW should have succeeded\n"); + winetest_ok ((INT)abc->abcB > 0, "abcB should be positive\n"); + if (todo) todo_wine winetest_ok(abc->abcA * base_abcw->abcA >= 0, "abcA's sign should be unchanged\n"); else winetest_ok(abc->abcA * base_abcw->abcA >= 0, "abcA's sign should be unchanged\n"); + if (todo) todo_wine winetest_ok(abc->abcC * base_abcw->abcC >= 0, "abcC's sign should be unchanged\n"); else winetest_ok(abc->abcC * base_abcw->abcC >= 0, "abcC's should be unchanged\n"); + + ret = pGetCharABCWidthsFloatW(hdc, 'i', 'i', abcf); + winetest_ok(ret, "GetCharABCWidthsFloatW should have succeeded\n"); + winetest_ok (abcf->abcfB > 0.0, "abcfB should be positive\n"); + if (todo) todo_wine winetest_ok(abcf->abcfA * base_abcf->abcfA >= 0.0, "abcfA's sign should be unchanged\n"); else winetest_ok(abcf->abcfA * base_abcf->abcfA >= 0.0, "abcfA's should be unchanged\n"); + if (todo) todo_wine winetest_ok(abcf->abcfC * base_abcf->abcfC >= 0.0, "abcfC's sign should be unchanged\n"); else winetest_ok(abcf->abcfC * base_abcf->abcfC >= 0.0, "abcfC's sign should be unchanged\n"); +} + static void test_GetCharABCWidths(void) { - static const WCHAR str[] = {'a',0}; + static const WCHAR str[] = {'i',0}; BOOL ret; HDC hdc; LOGFONTA lf; HFONT hfont; ABC abc[1]; + ABC abcw[1]; ABCFLOAT abcf[1]; WORD glyphs[1]; DWORD nb; + HWND hwnd; static const struct { UINT first; @@ -1262,6 +1290,70 @@ static void test_GetCharABCWidths(void) } ReleaseDC(NULL, hdc); + + memset(&lf, 0, sizeof(lf)); + strcpy(lf.lfFaceName, "Tahoma"); + lf.lfHeight = 20; + +#define helper_ABC(a) (winetest_set_location(__FILE__,__LINE__), 0) ? 0 : helper_ABCWidths(hdc, glyphs, abc, abcw, abcf, a) + + trace("ABC sign test for a varity of transforms:\n"); + hfont = CreateFontIndirectA(&lf); + hwnd = CreateWindowEx(0, "static", "", WS_POPUP, 0,0,100,100, + 0, 0, 0, NULL); + hdc = GetDC(hwnd); + SetMapMode(hdc, MM_ANISOTROPIC); + SelectObject(hdc, hfont); + + nb = pGetGlyphIndicesW(hdc, str, 1, glyphs, 0); + ok(nb == 1, "GetGlyphIndicesW should have returned 1\n"); + + ret = pGetCharABCWidthsI(hdc, 0, 1, glyphs, abc); + ok(ret, "GetCharABCWidthsI should have succeeded\n"); + ret = pGetCharABCWidthsW(hdc, 'i', 'i', abcw); + ok(ret, "GetCharABCWidthsI should have succeeded\n"); + ret = pGetCharABCWidthsFloatW(hdc, 'i', 'i', abcf); + ok(ret, "GetCharABCWidthsFloatW should have succeeded\n"); + + helper_ABC(0); + SetWindowExtEx(hdc, -1, -1, NULL); + SetGraphicsMode(hdc, GM_COMPATIBLE); + helper_ABC(0); + SetGraphicsMode(hdc, GM_ADVANCED); + helper_ABC(1); + SetWindowExtEx(hdc, 1, 1, NULL); + SetGraphicsMode(hdc, GM_COMPATIBLE); + helper_ABC(0); + SetGraphicsMode(hdc, GM_ADVANCED); + helper_ABC(0); + + ReleaseDC(hwnd, hdc); + DestroyWindow(hwnd); + + trace("RTL layout\n"); + hwnd = CreateWindowEx(WS_EX_LAYOUTRTL, "static", "", WS_POPUP, 0,0,100,100, + 0, 0, 0, NULL); + hdc = GetDC(hwnd); + SetMapMode(hdc, MM_ANISOTROPIC); + SelectObject(hdc, hfont); + + helper_ABC(0); + SetWindowExtEx(hdc, -1, -1, NULL); + SetGraphicsMode(hdc, GM_COMPATIBLE); + helper_ABC(0); + SetGraphicsMode(hdc, GM_ADVANCED); + helper_ABC(0); + SetWindowExtEx(hdc, 1, 1, NULL); + SetGraphicsMode(hdc, GM_COMPATIBLE); + helper_ABC(0); + SetGraphicsMode(hdc, GM_ADVANCED); + helper_ABC(1); + +#undef helper_ABC + + ReleaseDC(hwnd, hdc); + DestroyWindow(hwnd); + DeleteObject(hfont); } static void test_text_extents(void)