[PATCH 4/6] gdi32: Reuse the bbox value for the abc{A, B} if possible.

Byeongsik Jeon bsjeon at hanmail.net
Mon Feb 11 02:20:19 CST 2019


Signed-off-by: Byeongsik Jeon <bsjeon at hanmail.net>
---
- The abc{A,B} value reflects the subpixel rendering metrics modification when
  the glyph unrotated.

- fake_italic==TRUE, rotation==ZERO situation does not require a recalculation
  of abc{A,B}. and Wine current method can not calculate it.

- Even if font_desc.matrix != identity, there are more situations where abc{A,B}
  recalculation is not needed. There are some solutions, but I need more
  investigation.

 dlls/gdi32/freetype.c   | 25 +++++++++++++++++--------
 dlls/gdi32/tests/font.c | 21 ++++++++++++---------
 2 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 1f1957f2ca..8abffe121d 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -6917,15 +6917,26 @@ static void compute_metrics( GdiFont *incoming_font, GdiFont *font,
 {
     FT_Vector adv, vec, origin;
 
-    if (!needs_transform)
+    if (!(font->orientation % 3600) && is_identity_FMAT2( &font->font_desc.matrix ) &&
+        !vertical)
     {
-        adv = get_advance_metric( incoming_font, font, metrics, NULL, vertical_metrics );
-        gm->gmCellIncX = adv.x >> 6;
-        gm->gmCellIncY = 0;
+        if (!needs_transform)
+        {
+            adv = get_advance_metric( incoming_font, font, metrics, NULL, vertical_metrics );
+            gm->gmCellIncX = adv.x >> 6;
+            gm->gmCellIncY = 0;
+        }
+        else
+        {
+            adv = get_advance_metric( incoming_font, font, metrics, &matrices[matrix_hori],
+                                      vertical_metrics );
+            gm->gmCellIncX = adv.x >> 6;
+            gm->gmCellIncY = adv.y >> 6;
+        }
         origin.x = bbox.xMin;
         origin.y = bbox.yMax;
         abc->abcA = origin.x >> 6;
-        abc->abcB = (metrics->width + 63) >> 6;
+        abc->abcB = (bbox.xMax - bbox.xMin) >> 6;
     }
     else
     {
@@ -6959,8 +6970,6 @@ static void compute_metrics( GdiFont *incoming_font, GdiFont *font,
 
         adv = get_advance_metric( incoming_font, font, metrics, &matrices[matrix_unrotated],
                                   vertical_metrics );
-        adv.x = pFT_Vector_Length( &adv );
-        adv.y = 0;
 
         vec.x = lsb;
         vec.y = 0;
@@ -6975,7 +6984,7 @@ static void compute_metrics( GdiFont *incoming_font, GdiFont *font,
         abc->abcB = ((pFT_Vector_Length( &vec ) + 63) >> 6) - abc->abcA;
     }
     if (!abc->abcB) abc->abcB = 1;
-    abc->abcC = (adv.x >> 6) - abc->abcA - abc->abcB;
+    abc->abcC = (pFT_Vector_Length( &adv ) >> 6) - abc->abcA - abc->abcB;
 
     gm->gmptGlyphOrigin.x = origin.x >> 6;
     gm->gmptGlyphOrigin.y = origin.y >> 6;
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index 53035cfb9b..f14e6f80c8 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -1347,7 +1347,7 @@ static void test_GetCharABCWidths(void)
 
     /* test abcA == gmptGlyphOrigin.x && abcB == gmBlackBoxX
        in various widths. */
-    for (i = 1; i <= 2; i++)
+    for (i = 1; i <= 3; i++)
     {
         UINT j;
         UINT code;
@@ -1365,6 +1365,11 @@ static void test_GetCharABCWidths(void)
             lf.lfItalic = TRUE;
             code = 'f';
             break;
+        case 3:
+            strcpy(lf.lfFaceName, "Tahoma");
+            lf.lfItalic = TRUE; /* simulated italic */
+            code = 'V';
+            break;
         }
         if (!is_truetype_font_installed(lf.lfFaceName))
         {
@@ -1380,19 +1385,17 @@ static void test_GetCharABCWidths(void)
             hfont = SelectObject(hdc, hfont);
 
             nb = GetGlyphOutlineA(hdc, code, GGO_METRICS, &gm, 0, NULL, &mat);
-            ok(nb, "GetGlyphOutlineA should have succeeded at width %d\n", i);
+            ok(nb, "%d: GetGlyphOutlineA should have succeeded at width %d\n", i, j);
 
             ret = GetCharABCWidthsA(hdc, code, code, abc);
-            ok(ret, "GetCharABCWidthsA should have succeeded at width %d\n", i);
+            ok(ret, "%d: GetCharABCWidthsA should have succeeded at width %d\n", i, j);
 
-            todo_wine
             ok(abc[0].abcA == gm.gmptGlyphOrigin.x,
-               "abcA(%d) and gmptGlyphOrigin.x(%d) values are different at width %d\n",
-               abc[0].abcA, gm.gmptGlyphOrigin.x, i);
-            todo_wine
+               "%d: abcA(%d) and gmptGlyphOrigin.x(%d) values are different at width %d\n",
+               i, abc[0].abcA, gm.gmptGlyphOrigin.x, j);
             ok(abc[0].abcB == gm.gmBlackBoxX,
-               "abcB(%d) and gmBlackBoxX(%d) values are different at width %d\n",
-               abc[0].abcB, gm.gmBlackBoxX, i);
+               "%d: abcB(%d) and gmBlackBoxX(%d) values are different at width %d\n",
+               i, abc[0].abcB, gm.gmBlackBoxX, j);
             DeleteObject(SelectObject(hdc, hfont));
         }
     }
-- 
2.20.1




More information about the wine-devel mailing list