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