From b3d55e2ce509bf2e75246da54e080adde2c76b2f Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 22 Oct 2020 11:51:07 +0200 Subject: [PATCH] gdi32: Move the glyph metrics cache out of freetype.c. Signed-off-by: Alexandre Julliard --- 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 */ -- 2.11.4.GIT