Alexandre Julliard : gdi32: Move the glyph metrics cache out of freetype.c.

Alexandre Julliard julliard at winehq.org
Thu Oct 22 15:27:30 CDT 2020


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Oct 22 11:51:07 2020 +0200

gdi32: Move the glyph metrics cache out of freetype.c.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdi32/font.c        | 60 +++++++++++++++++++++++++++++++++++++++++
 dlls/gdi32/freetype.c    | 69 ++----------------------------------------------
 dlls/gdi32/gdi_private.h |  8 ++++++
 3 files changed, 70 insertions(+), 67 deletions(-)

diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 31c9d1561a5..0882b5ef1ba 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -430,8 +430,12 @@ struct gdi_font *alloc_gdi_font(void)
 
 void free_gdi_font( struct gdi_font *font )
 {
+    DWORD i;
+
     if (font->private) font_funcs->destroy_font( font );
     free_font_handle( font->handle );
+    for (i = 0; i < font->gm_size; i++) HeapFree( GetProcessHeap(), 0, font->gm[i] );
+    HeapFree( GetProcessHeap(), 0, font->gm );
     HeapFree( GetProcessHeap(), 0, font->name );
     HeapFree( GetProcessHeap(), 0, font->fileinfo );
     HeapFree( GetProcessHeap(), 0, font );
@@ -469,6 +473,62 @@ void set_gdi_font_file_info( struct gdi_font *font, const WCHAR *file, SIZE_T da
     else font->fileinfo->size.QuadPart = data_size;
 }
 
+struct glyph_metrics
+{
+    GLYPHMETRICS gm;
+    ABC          abc;  /* metrics of the unrotated char */
+    BOOL         init;
+};
+
+#define GM_BLOCK_SIZE 128
+
+/* TODO: GGO format support */
+BOOL get_gdi_font_glyph_metrics( struct gdi_font *font, UINT index, GLYPHMETRICS *gm, ABC *abc )
+{
+    UINT block = index / GM_BLOCK_SIZE;
+    UINT entry = index % GM_BLOCK_SIZE;
+
+    if (block < font->gm_size && 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;
+}
+
+void set_gdi_font_glyph_metrics( struct gdi_font *font, UINT index, const GLYPHMETRICS *gm, const ABC *abc )
+{
+    UINT block = index / GM_BLOCK_SIZE;
+    UINT entry = index % GM_BLOCK_SIZE;
+
+    if (block >= font->gm_size)
+    {
+        struct glyph_metrics **ptr;
+
+        if (font->gm)
+            ptr = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, font->gm, (block + 1) * sizeof(*ptr) );
+        else
+            ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, (block + 1) * sizeof(*ptr) );
+        if (!ptr) return;
+        font->gm_size = block + 1;
+        font->gm = ptr;
+    }
+    if (!font->gm[block])
+    {
+        font->gm[block] = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**font->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;
+}
+
 /* font cache */
 
 static struct list gdi_font_list = LIST_INIT( gdi_font_list );
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 58e85a4515e..8251b257a3d 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -304,12 +304,6 @@ typedef struct tagFamily {
     struct list *replacement;
 } Family;
 
-typedef struct {
-    GLYPHMETRICS gm;
-    ABC          abc;  /* metrics of the unrotated char */
-    BOOL         init;
-} GM;
-
 typedef struct tagGdiFont GdiFont;
 
 typedef struct {
@@ -320,8 +314,6 @@ typedef struct {
 
 struct tagGdiFont {
     struct gdi_font *gdi_font;
-    GM **gm;
-    DWORD gmsize;
     OUTLINETEXTMETRICW *potm;
     DWORD total_kern_pairs;
     KERNINGPAIR *kern_pairs;
@@ -356,9 +348,6 @@ struct enum_charset_list {
     struct enum_charset_element element[32];
 };
 
-#define GM_BLOCK_SIZE 128
-#define FONT_GM(font,idx) (&(font)->gm[(idx) / GM_BLOCK_SIZE][(idx) % GM_BLOCK_SIZE])
-
 static struct list system_links = LIST_INIT(system_links);
 
 static struct list font_subst_list = LIST_INIT(font_subst_list);
@@ -4068,9 +4057,6 @@ static UINT get_nearest_charset(const WCHAR *family_name, Face *face, UINT *cp)
 static BOOL CDECL freetype_alloc_font( struct gdi_font *font )
 {
     GdiFont *ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
-    ret->gmsize = 1;
-    ret->gm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GM*));
-    ret->gm[0] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GM) * GM_BLOCK_SIZE);
     ret->potm = NULL;
     ret->total_kern_pairs = (DWORD)-1;
     ret->kern_pairs = NULL;
@@ -4087,7 +4073,6 @@ static void CDECL freetype_destroy_font( struct gdi_font *gdi_font )
 {
     GdiFont *font = get_font_ptr( gdi_font );
     CHILD_FONT *child, *child_next;
-    DWORD i;
 
     LIST_FOR_EACH_ENTRY_SAFE( child, child_next, &font->child_fonts, CHILD_FONT, entry )
     {
@@ -4102,60 +4087,10 @@ static void CDECL freetype_destroy_font( struct gdi_font *gdi_font )
     if (font->mapping) unmap_font_file( font->mapping );
     HeapFree(GetProcessHeap(), 0, font->kern_pairs);
     HeapFree(GetProcessHeap(), 0, font->potm);
-    for (i = 0; i < font->gmsize; i++)
-        HeapFree(GetProcessHeap(),0,font->gm[i]);
-    HeapFree(GetProcessHeap(), 0, font->gm);
     HeapFree(GetProcessHeap(), 0, font->GSUB_Table);
     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)
 {
     FT_Face ft_face = font->ft_face;
@@ -6805,7 +6740,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
     format &= ~GGO_UNHINTED;
 
     if (format == GGO_METRICS && is_identity_MAT2(lpmat) &&
-        get_cached_metrics( font, glyph_index, lpgm, abc ))
+        get_gdi_font_glyph_metrics( gdi_font, glyph_index, lpgm, abc ))
         return 1; /* FIXME */
 
     needsTransform = get_transform_matrices( font, tategaki, lpmat, matrices );
@@ -6860,7 +6795,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 */
-        set_cached_metrics( font, glyph_index, &gm, abc );
+        set_gdi_font_glyph_metrics( gdi_font, glyph_index, &gm, abc );
 
     if(format == GGO_METRICS)
     {
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 3968b62d8db..29ec84f9e97 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -303,11 +303,15 @@ struct char_width_info
 
 typedef struct { FLOAT eM11, eM12, eM21, eM22; } FMAT2;
 
+struct glyph_metrics;
+
 struct gdi_font
 {
     struct list            entry;
     struct list            unused_entry;
     DWORD                  refcount;
+    DWORD                  gm_size;
+    struct glyph_metrics **gm;
     /* the following members can be accessed without locking, they are never modified after creation */
     void                  *private;  /* font backend private data */
     DWORD                  handle;
@@ -375,6 +379,10 @@ extern struct gdi_font *find_cached_gdi_font( const LOGFONTW *lf, const FMAT2 *m
                                               BOOL can_use_bitmap ) DECLSPEC_HIDDEN;
 extern void set_gdi_font_name( struct gdi_font *font, const WCHAR *name ) DECLSPEC_HIDDEN;
 extern void set_gdi_font_file_info( struct gdi_font *font, const WCHAR *file, SIZE_T data_size ) DECLSPEC_HIDDEN;
+extern BOOL get_gdi_font_glyph_metrics( struct gdi_font *font, UINT index,
+                                        GLYPHMETRICS *gm, ABC *abc ) DECLSPEC_HIDDEN;
+extern void set_gdi_font_glyph_metrics( struct gdi_font *font, UINT index,
+                                        const GLYPHMETRICS *gm, const ABC *abc ) DECLSPEC_HIDDEN;
 extern void font_init(void) DECLSPEC_HIDDEN;
 
 /* freetype.c */




More information about the wine-cvs mailing list