Byeongsik Jeon : gdi32: Add helper functions to cache the glyph metrics.

Alexandre Julliard julliard at winehq.org
Fri Feb 8 16:16:27 CST 2019


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

Author: Byeongsik Jeon <bsjeon at hanmail.net>
Date:   Fri Feb  8 10:51:29 2019 +0900

gdi32: Add helper functions to cache the glyph metrics.

Signed-off-by: Byeongsik Jeon <bsjeon at hanmail.net>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdi32/freetype.c | 77 +++++++++++++++++++++++++++++++++------------------
 1 file changed, 50 insertions(+), 27 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index b21365d..f4cb5d5 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -4697,6 +4697,52 @@ static void free_font(GdiFont *font)
     HeapFree(GetProcessHeap(), 0, font);
 }
 
+/* TODO: GGO format support */
+static BOOL get_cached_metrics( GdiFont *font, UINT index, GLYPHMETRICS *gm, ABC *abc )
+{
+    UINT block = index / GM_BLOCK_SIZE;
+    UINT entry = index % GM_BLOCK_SIZE;
+
+    if (block < font->gmsize && font->gm[block] && font->gm[block][entry].init)
+    {
+        *gm  = font->gm[block][entry].gm;
+        *abc = font->gm[block][entry].abc;
+
+        TRACE( "cached gm: %u, %u, %s, %d, %d abc: %d, %u, %d\n",
+               gm->gmBlackBoxX, gm->gmBlackBoxY, wine_dbgstr_point( &gm->gmptGlyphOrigin ),
+               gm->gmCellIncX, gm->gmCellIncY, abc->abcA, abc->abcB, abc->abcC );
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+static void set_cached_metrics( GdiFont *font, UINT index, const GLYPHMETRICS *gm, const ABC *abc )
+{
+    UINT block = index / GM_BLOCK_SIZE;
+    UINT entry = index % GM_BLOCK_SIZE;
+
+    if (block >= font->gmsize)
+    {
+        GM **ptr = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                font->gm, (block + 1) * sizeof(GM *) );
+        if (!ptr) return;
+
+        font->gmsize = block + 1;
+        font->gm = ptr;
+    }
+
+    if (!font->gm[block])
+    {
+        font->gm[block] = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                     sizeof(GM) * GM_BLOCK_SIZE );
+        if (!font->gm[block]) return;
+    }
+
+    font->gm[block][entry].gm   = *gm;
+    font->gm[block][entry].abc  = *abc;
+    font->gm[block][entry].init = TRUE;
+}
 
 static DWORD get_font_data( GdiFont *font, DWORD table, DWORD offset, LPVOID buf, DWORD cbData)
 {
@@ -7063,7 +7109,6 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
     BOOL needsTransform = FALSE;
     BOOL tategaki = (font->name[0] == '@');
     BOOL vertical_metrics;
-    UINT original_index;
 
     TRACE("%p, %04x, %08x, %p, %08x, %p, %p\n", font, glyph, format, lpgm,
 	  buflen, buf, lpmat);
@@ -7080,7 +7125,6 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
             TRACE("translate glyph index %04x -> %04x\n", glyph, glyph_index);
         } else
             glyph_index = glyph;
-        original_index = glyph_index;
 	format &= ~GGO_GLYPH_INDEX;
         /* TODO: Window also turns off tategaki for glyphs passed in by index
             if their unicode code points fall outside of the range that is
@@ -7089,32 +7133,15 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
         BOOL vert;
         get_glyph_index_linked(incoming_font, glyph, &font, &glyph_index, &vert);
         ft_face = font->ft_face;
-        original_index = glyph_index;
         if (!vert && tategaki)
             tategaki = check_unicode_tategaki(glyph);
     }
 
     format &= ~GGO_UNHINTED;
 
-    if(original_index >= font->gmsize * GM_BLOCK_SIZE) {
-	font->gmsize = (original_index / GM_BLOCK_SIZE + 1);
-	font->gm = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, font->gm,
-			       font->gmsize * sizeof(GM*));
-    } else {
-        if (format == GGO_METRICS && font->gm[original_index / GM_BLOCK_SIZE] != NULL &&
-            FONT_GM(font,original_index)->init && is_identity_MAT2(lpmat))
-        {
-            *lpgm = FONT_GM(font,original_index)->gm;
-            *abc = FONT_GM(font,original_index)->abc;
-            TRACE("cached: %u,%u,%s,%d,%d\n", lpgm->gmBlackBoxX, lpgm->gmBlackBoxY,
-                  wine_dbgstr_point(&lpgm->gmptGlyphOrigin),
-                  lpgm->gmCellIncX, lpgm->gmCellIncY);
-	    return 1; /* FIXME */
-	}
-    }
-
-    if (!font->gm[original_index / GM_BLOCK_SIZE])
-        font->gm[original_index / GM_BLOCK_SIZE] = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(GM) * GM_BLOCK_SIZE);
+    if (format == GGO_METRICS && is_identity_MAT2(lpmat) &&
+        get_cached_metrics( font, glyph_index, lpgm, abc ))
+        return 1; /* FIXME */
 
     needsTransform = get_transform_matrices( font, tategaki, lpmat, matrices );
 
@@ -7254,11 +7281,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
 
     if ((format == GGO_METRICS || format == GGO_BITMAP || format ==  WINE_GGO_GRAY16_BITMAP) &&
         is_identity_MAT2(lpmat)) /* don't cache custom transforms */
-    {
-        FONT_GM(font,original_index)->gm = gm;
-        FONT_GM(font,original_index)->abc = *abc;
-        FONT_GM(font,original_index)->init = TRUE;
-    }
+        set_cached_metrics( font, glyph_index, &gm, abc );
 
     if(format == GGO_METRICS)
     {




More information about the wine-cvs mailing list