Akihiro Sagawa : gdi32: Fix ABC width calculations when applying transformations internally.

Alexandre Julliard julliard at winehq.org
Thu Feb 8 15:33:07 CST 2018


Module: wine
Branch: master
Commit: 2a402a427a7d3bad1ea8043b9d7db011727cbc6b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=2a402a427a7d3bad1ea8043b9d7db011727cbc6b

Author: Akihiro Sagawa <sagawa.aki at gmail.com>
Date:   Sun Feb  4 21:02:07 2018 +0900

gdi32: Fix ABC width calculations when applying transformations internally.

This fixes a regression introduced by f6bc356860a1ea2e5b4aed43e38ddf8b7d24a8b0.

Signed-off-by: Akihiro Sagawa <sagawa.aki at gmail.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdi32/freetype.c   | 15 ++++++++-------
 dlls/gdi32/tests/font.c | 44 +++++++++++++++++++-------------------------
 2 files changed, 27 insertions(+), 32 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 4db1c7e..7016095 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -7008,7 +7008,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
         origin_x = left;
         origin_y = top;
         abc->abcA = origin_x >> 6;
-        abc->abcB = metrics.width >> 6;
+        abc->abcB = (metrics.width + 63) >> 6;
     } else {
         INT xc, yc;
 	FT_Vector vec;
@@ -7064,19 +7064,20 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
         gm.gmCellIncY = adv.y >> 6;
 
         adv = get_advance_metric(incoming_font, font, &metrics, &transMatUnrotated, vertical_metrics);
+        adv.x = pFT_Vector_Length(&adv);
+        adv.y = 0;
 
         vec.x = lsb;
         vec.y = 0;
         pFT_Vector_Transform(&vec, &transMatUnrotated);
-        abc->abcA = vec.x >> 6;
+        if(lsb > 0) abc->abcA = pFT_Vector_Length(&vec) >> 6;
+        else abc->abcA = -((pFT_Vector_Length(&vec) + 63) >> 6);
 
-        vec.x = metrics.width;
+        /* We use lsb again to avoid rounding errors */
+        vec.x = lsb + metrics.width;
         vec.y = 0;
         pFT_Vector_Transform(&vec, &transMatUnrotated);
-        if (vec.x >= 0)
-            abc->abcB = vec.x >> 6;
-        else
-            abc->abcB = -vec.x >> 6;
+        abc->abcB = ((pFT_Vector_Length(&vec) + 63) >> 6) - abc->abcA;
     }
 
     width  = (right - left) >> 6;
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index 70e44f3..4bac19a 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -1128,7 +1128,7 @@ static int CALLBACK create_font_proc(const LOGFONTA *lpelfe,
     return 1;
 }
 
-static void ABCWidths_helper(const char* description, HDC hdc, WORD *glyphs, ABC *base_abci, ABC *base_abcw, ABCFLOAT *base_abcf, INT todo)
+static void ABCWidths_helper(const char* description, HDC hdc, WORD *glyphs, const ABC *base_abci, const ABC *base_abcw, const ABCFLOAT *base_abcf)
 {
     ABC abc[1];
     ABCFLOAT abcf[1];
@@ -1137,26 +1137,20 @@ static void ABCWidths_helper(const char* description, HDC hdc, WORD *glyphs, ABC
     ret = pGetCharABCWidthsI(hdc, 0, 1, glyphs, abc);
     ok(ret, "%s: GetCharABCWidthsI should have succeeded\n", description);
     ok ((INT)abc->abcB > 0, "%s: abcB should be positive\n", description);
-    todo_wine_if (todo)
-        ok(abc->abcA * base_abci->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
-    todo_wine_if (todo)
-        ok(abc->abcC * base_abci->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
+    ok(abc->abcA * base_abci->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
+    ok(abc->abcC * base_abci->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
 
     ret = pGetCharABCWidthsW(hdc, 'i', 'i', abc);
     ok(ret, "%s: GetCharABCWidthsW should have succeeded\n", description);
     ok ((INT)abc->abcB > 0, "%s: abcB should be positive\n", description);
-    todo_wine_if (todo)
-        ok(abc->abcA * base_abcw->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
-    todo_wine_if (todo)
-        ok(abc->abcC * base_abcw->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
+    ok(abc->abcA * base_abcw->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
+    ok(abc->abcC * base_abcw->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
 
     ret = pGetCharABCWidthsFloatW(hdc, 'i', 'i', abcf);
     ok(ret, "%s: GetCharABCWidthsFloatW should have succeeded\n", description);
     ok (abcf->abcfB > 0.0, "%s: abcfB should be positive\n", description);
-    todo_wine_if (todo)
-        ok(abcf->abcfA * base_abcf->abcfA >= 0.0, "%s: abcfA's sign should be unchanged\n", description);
-    todo_wine_if (todo)
-        ok(abcf->abcfC * base_abcf->abcfC >= 0.0, "%s: abcfC's sign should be unchanged\n", description);
+    ok(abcf->abcfA * base_abcf->abcfA >= 0.0, "%s: abcfA's sign should be unchanged\n", description);
+    ok(abcf->abcfC * base_abcf->abcfC >= 0.0, "%s: abcfC's sign should be unchanged\n", description);
 }
 
 static void test_GetCharABCWidths(void)
@@ -1369,17 +1363,17 @@ static void test_GetCharABCWidths(void)
     ret = pGetCharABCWidthsFloatW(hdc, 'i', 'i', abcf);
     ok(ret, "GetCharABCWidthsFloatW should have succeeded\n");
 
-    ABCWidths_helper("LTR", hdc, glyphs, abc, abcw, abcf, 0);
+    ABCWidths_helper("LTR", hdc, glyphs, abc, abcw, abcf);
     SetWindowExtEx(hdc, -1, -1, NULL);
     SetGraphicsMode(hdc, GM_COMPATIBLE);
-    ABCWidths_helper("LTR -1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+    ABCWidths_helper("LTR -1 compatible", hdc, glyphs, abc, abcw, abcf);
     SetGraphicsMode(hdc, GM_ADVANCED);
-    ABCWidths_helper("LTR -1 advanced", hdc, glyphs, abc, abcw, abcf, 1);
+    ABCWidths_helper("LTR -1 advanced", hdc, glyphs, abc, abcw, abcf);
     SetWindowExtEx(hdc, 1, 1, NULL);
     SetGraphicsMode(hdc, GM_COMPATIBLE);
-    ABCWidths_helper("LTR 1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+    ABCWidths_helper("LTR 1 compatible", hdc, glyphs, abc, abcw, abcf);
     SetGraphicsMode(hdc, GM_ADVANCED);
-    ABCWidths_helper("LTR 1 advanced", hdc, glyphs, abc, abcw, abcf, 0);
+    ABCWidths_helper("LTR 1 advanced", hdc, glyphs, abc, abcw, abcf);
 
     ReleaseDC(hwnd, hdc);
     DestroyWindow(hwnd);
@@ -1391,17 +1385,17 @@ static void test_GetCharABCWidths(void)
     SetMapMode(hdc, MM_ANISOTROPIC);
     SelectObject(hdc, hfont);
 
-    ABCWidths_helper("RTL", hdc, glyphs, abc, abcw, abcf, 0);
+    ABCWidths_helper("RTL", hdc, glyphs, abc, abcw, abcf);
     SetWindowExtEx(hdc, -1, -1, NULL);
     SetGraphicsMode(hdc, GM_COMPATIBLE);
-    ABCWidths_helper("RTL -1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+    ABCWidths_helper("RTL -1 compatible", hdc, glyphs, abc, abcw, abcf);
     SetGraphicsMode(hdc, GM_ADVANCED);
-    ABCWidths_helper("RTL -1 advanced", hdc, glyphs, abc, abcw, abcf, 0);
+    ABCWidths_helper("RTL -1 advanced", hdc, glyphs, abc, abcw, abcf);
     SetWindowExtEx(hdc, 1, 1, NULL);
     SetGraphicsMode(hdc, GM_COMPATIBLE);
-    ABCWidths_helper("RTL 1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+    ABCWidths_helper("RTL 1 compatible", hdc, glyphs, abc, abcw, abcf);
     SetGraphicsMode(hdc, GM_ADVANCED);
-    ABCWidths_helper("RTL 1 advanced", hdc, glyphs, abc, abcw, abcf, 1);
+    ABCWidths_helper("RTL 1 advanced", hdc, glyphs, abc, abcw, abcf);
 
     ReleaseDC(hwnd, hdc);
     DestroyWindow(hwnd);
@@ -6372,7 +6366,7 @@ static void test_GetCharWidth32(void)
     SetGraphicsMode(hdc, GM_ADVANCED);
     ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
     ok(ret, "GetCharWidth32W should have succeeded\n");
-    todo_wine ok (bufferW > 0," Width should be greater than zero\n");
+    ok (bufferW > 0," Width should be greater than zero\n");
     SetWindowExtEx(hdc, 1,1,NULL);
     SetGraphicsMode(hdc, GM_COMPATIBLE);
     ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
@@ -6412,7 +6406,7 @@ static void test_GetCharWidth32(void)
     SetGraphicsMode(hdc, GM_ADVANCED);
     ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
     ok(ret, "GetCharWidth32W should have succeeded\n");
-    todo_wine ok (bufferW > 0," Width should be greater than zero\n");
+    ok (bufferW > 0," Width should be greater than zero\n");
 
     ReleaseDC(hwnd, hdc);
     DestroyWindow(hwnd);




More information about the wine-cvs mailing list