gdi32: Move the glyph metrics cache out of freetype.c.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c44c347dd5
commit
b3d55e2ce5
|
@ -430,8 +430,12 @@ struct gdi_font *alloc_gdi_font(void)
|
||||||
|
|
||||||
void free_gdi_font( struct gdi_font *font )
|
void free_gdi_font( struct gdi_font *font )
|
||||||
{
|
{
|
||||||
|
DWORD i;
|
||||||
|
|
||||||
if (font->private) font_funcs->destroy_font( font );
|
if (font->private) font_funcs->destroy_font( font );
|
||||||
free_font_handle( font->handle );
|
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->name );
|
||||||
HeapFree( GetProcessHeap(), 0, font->fileinfo );
|
HeapFree( GetProcessHeap(), 0, font->fileinfo );
|
||||||
HeapFree( GetProcessHeap(), 0, font );
|
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;
|
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 */
|
/* font cache */
|
||||||
|
|
||||||
static struct list gdi_font_list = LIST_INIT( gdi_font_list );
|
static struct list gdi_font_list = LIST_INIT( gdi_font_list );
|
||||||
|
|
|
@ -304,12 +304,6 @@ typedef struct tagFamily {
|
||||||
struct list *replacement;
|
struct list *replacement;
|
||||||
} Family;
|
} Family;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
GLYPHMETRICS gm;
|
|
||||||
ABC abc; /* metrics of the unrotated char */
|
|
||||||
BOOL init;
|
|
||||||
} GM;
|
|
||||||
|
|
||||||
typedef struct tagGdiFont GdiFont;
|
typedef struct tagGdiFont GdiFont;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -320,8 +314,6 @@ typedef struct {
|
||||||
|
|
||||||
struct tagGdiFont {
|
struct tagGdiFont {
|
||||||
struct gdi_font *gdi_font;
|
struct gdi_font *gdi_font;
|
||||||
GM **gm;
|
|
||||||
DWORD gmsize;
|
|
||||||
OUTLINETEXTMETRICW *potm;
|
OUTLINETEXTMETRICW *potm;
|
||||||
DWORD total_kern_pairs;
|
DWORD total_kern_pairs;
|
||||||
KERNINGPAIR *kern_pairs;
|
KERNINGPAIR *kern_pairs;
|
||||||
|
@ -356,9 +348,6 @@ struct enum_charset_list {
|
||||||
struct enum_charset_element element[32];
|
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 system_links = LIST_INIT(system_links);
|
||||||
|
|
||||||
static struct list font_subst_list = LIST_INIT(font_subst_list);
|
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 )
|
static BOOL CDECL freetype_alloc_font( struct gdi_font *font )
|
||||||
{
|
{
|
||||||
GdiFont *ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
|
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->potm = NULL;
|
||||||
ret->total_kern_pairs = (DWORD)-1;
|
ret->total_kern_pairs = (DWORD)-1;
|
||||||
ret->kern_pairs = NULL;
|
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 );
|
GdiFont *font = get_font_ptr( gdi_font );
|
||||||
CHILD_FONT *child, *child_next;
|
CHILD_FONT *child, *child_next;
|
||||||
DWORD i;
|
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY_SAFE( child, child_next, &font->child_fonts, CHILD_FONT, entry )
|
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 );
|
if (font->mapping) unmap_font_file( font->mapping );
|
||||||
HeapFree(GetProcessHeap(), 0, font->kern_pairs);
|
HeapFree(GetProcessHeap(), 0, font->kern_pairs);
|
||||||
HeapFree(GetProcessHeap(), 0, font->potm);
|
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->GSUB_Table);
|
||||||
HeapFree(GetProcessHeap(), 0, 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)
|
static DWORD get_font_data( GdiFont *font, DWORD table, DWORD offset, LPVOID buf, DWORD cbData)
|
||||||
{
|
{
|
||||||
FT_Face ft_face = font->ft_face;
|
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;
|
format &= ~GGO_UNHINTED;
|
||||||
|
|
||||||
if (format == GGO_METRICS && is_identity_MAT2(lpmat) &&
|
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 */
|
return 1; /* FIXME */
|
||||||
|
|
||||||
needsTransform = get_transform_matrices( font, tategaki, lpmat, matrices );
|
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) &&
|
if ((format == GGO_METRICS || format == GGO_BITMAP || format == WINE_GGO_GRAY16_BITMAP) &&
|
||||||
is_identity_MAT2(lpmat)) /* don't cache custom transforms */
|
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)
|
if(format == GGO_METRICS)
|
||||||
{
|
{
|
||||||
|
|
|
@ -303,11 +303,15 @@ struct char_width_info
|
||||||
|
|
||||||
typedef struct { FLOAT eM11, eM12, eM21, eM22; } FMAT2;
|
typedef struct { FLOAT eM11, eM12, eM21, eM22; } FMAT2;
|
||||||
|
|
||||||
|
struct glyph_metrics;
|
||||||
|
|
||||||
struct gdi_font
|
struct gdi_font
|
||||||
{
|
{
|
||||||
struct list entry;
|
struct list entry;
|
||||||
struct list unused_entry;
|
struct list unused_entry;
|
||||||
DWORD refcount;
|
DWORD refcount;
|
||||||
|
DWORD gm_size;
|
||||||
|
struct glyph_metrics **gm;
|
||||||
/* the following members can be accessed without locking, they are never modified after creation */
|
/* the following members can be accessed without locking, they are never modified after creation */
|
||||||
void *private; /* font backend private data */
|
void *private; /* font backend private data */
|
||||||
DWORD handle;
|
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;
|
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_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 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;
|
extern void font_init(void) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* freetype.c */
|
/* freetype.c */
|
||||||
|
|
Loading…
Reference in New Issue