gdi32: Store child font objects directly on the child font list.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
8631506270
commit
54bdbd3c03
|
@ -473,6 +473,7 @@ struct gdi_font *alloc_gdi_font( const WCHAR *file, void *data_ptr, SIZE_T data_
|
|||
font->matrix.eM11 = font->matrix.eM22 = 1.0;
|
||||
font->scale_y = 1.0;
|
||||
font->kern_count = -1;
|
||||
list_init( &font->child_fonts );
|
||||
|
||||
if (file)
|
||||
{
|
||||
|
@ -501,9 +502,15 @@ struct gdi_font *alloc_gdi_font( const WCHAR *file, void *data_ptr, SIZE_T data_
|
|||
void free_gdi_font( struct gdi_font *font )
|
||||
{
|
||||
DWORD i;
|
||||
struct gdi_font *child, *child_next;
|
||||
|
||||
if (font->private) font_funcs->destroy_font( font );
|
||||
free_font_handle( font->handle );
|
||||
LIST_FOR_EACH_ENTRY_SAFE( child, child_next, &font->child_fonts, struct gdi_font, entry )
|
||||
{
|
||||
list_remove( &child->entry );
|
||||
free_gdi_font( child );
|
||||
}
|
||||
for (i = 0; i < font->gm_size; i++) HeapFree( GetProcessHeap(), 0, font->gm[i] );
|
||||
HeapFree( GetProcessHeap(), 0, font->otm.otmpFamilyName );
|
||||
HeapFree( GetProcessHeap(), 0, font->otm.otmpStyleName );
|
||||
|
@ -1282,17 +1289,13 @@ static BOOL CDECL font_EnumFonts( PHYSDEV dev, LOGFONTW *lf, FONTENUMPROCW proc,
|
|||
static BOOL CDECL font_FontIsLinked( PHYSDEV dev )
|
||||
{
|
||||
struct font_physdev *physdev = get_font_dev( dev );
|
||||
BOOL ret;
|
||||
|
||||
if (!physdev->font)
|
||||
{
|
||||
dev = GET_NEXT_PHYSDEV( dev, pFontIsLinked );
|
||||
return dev->funcs->pFontIsLinked( dev );
|
||||
}
|
||||
EnterCriticalSection( &font_cs );
|
||||
ret = font_funcs->pFontIsLinked( physdev->font );
|
||||
LeaveCriticalSection( &font_cs );
|
||||
return ret;
|
||||
return !list_empty( &physdev->font->child_fonts );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -291,9 +291,6 @@ typedef struct {
|
|||
|
||||
struct tagGdiFont {
|
||||
struct gdi_font *gdi_font;
|
||||
struct list child_fonts;
|
||||
|
||||
/* the following members can be accessed without locking, they are never modified after creation */
|
||||
FT_Face ft_face;
|
||||
struct font_mapping *mapping;
|
||||
};
|
||||
|
@ -3276,16 +3273,6 @@ static UINT get_nearest_charset(const WCHAR *family_name, Face *face, UINT *cp)
|
|||
static void CDECL freetype_destroy_font( struct gdi_font *gdi_font )
|
||||
{
|
||||
GdiFont *font = get_font_ptr( gdi_font );
|
||||
CHILD_FONT *child, *child_next;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE( child, child_next, &font->child_fonts, CHILD_FONT, entry )
|
||||
{
|
||||
list_remove(&child->entry);
|
||||
if(child->font)
|
||||
free_gdi_font(child->font->gdi_font);
|
||||
release_face( child->face );
|
||||
HeapFree(GetProcessHeap(), 0, child);
|
||||
}
|
||||
|
||||
if (font->ft_face) pFT_Done_Face(font->ft_face);
|
||||
if (font->mapping) unmap_font_file( font->mapping );
|
||||
|
@ -3500,41 +3487,73 @@ static LONG load_VDMX(GdiFont *font, LONG height)
|
|||
return ppem;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* add_child_font
|
||||
*/
|
||||
static void add_child_font( struct gdi_font *font, Face *face )
|
||||
{
|
||||
struct gdi_font *child;
|
||||
Face *child_face, *best_face = NULL;
|
||||
UINT penalty = 0, new_penalty = 0;
|
||||
BOOL bold, italic, bd, it;
|
||||
|
||||
italic = !!font->lf.lfItalic;
|
||||
bold = font->lf.lfWeight > FW_MEDIUM;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( child_face, get_face_list_from_family( face->family ), Face, entry )
|
||||
{
|
||||
it = !!(child_face->ntmFlags & NTM_ITALIC);
|
||||
bd = !!(child_face->ntmFlags & NTM_BOLD);
|
||||
new_penalty = ( it ^ italic ) + ( bd ^ bold );
|
||||
if (!best_face || new_penalty < penalty)
|
||||
{
|
||||
penalty = new_penalty;
|
||||
best_face = child_face;
|
||||
}
|
||||
}
|
||||
if (best_face) face = best_face;
|
||||
|
||||
child = alloc_gdi_font( face->file, face->font_data_ptr, face->font_data_size );
|
||||
child->fake_italic = italic && !(face->ntmFlags & NTM_ITALIC);
|
||||
child->fake_bold = bold && !(face->ntmFlags & NTM_BOLD);
|
||||
child->lf = font->lf;
|
||||
child->matrix = font->matrix;
|
||||
child->can_use_bitmap = font->can_use_bitmap;
|
||||
child->face_index = face->face_index;
|
||||
child->ntmFlags = face->ntmFlags;
|
||||
child->aa_flags = HIWORD( face->flags );
|
||||
child->scale_y = font->scale_y;
|
||||
child->base_font = font;
|
||||
set_gdi_font_names( child, face->family->family_name, face->style_name, face->full_name );
|
||||
|
||||
list_add_tail( &font->child_fonts, &child->entry );
|
||||
TRACE( "created child font %p for base %p\n", child, font );
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* create_child_font_list
|
||||
*/
|
||||
static BOOL create_child_font_list(GdiFont *font)
|
||||
static void create_child_font_list( struct gdi_font *font )
|
||||
{
|
||||
struct gdi_font *gdi_font = font->gdi_font;
|
||||
BOOL ret = FALSE;
|
||||
SYSTEM_LINKS *font_link;
|
||||
CHILD_FONT *font_link_entry, *new_child;
|
||||
CHILD_FONT *font_link_entry;
|
||||
FontSubst *psub;
|
||||
const WCHAR* font_name;
|
||||
|
||||
psub = get_font_subst(&font_subst_list, get_gdi_font_name(gdi_font), -1);
|
||||
font_name = psub ? psub->to.name : get_gdi_font_name(gdi_font);
|
||||
psub = get_font_subst(&font_subst_list, get_gdi_font_name(font), -1);
|
||||
font_name = psub ? psub->to.name : get_gdi_font_name(font);
|
||||
font_link = find_font_link(font_name);
|
||||
if (font_link != NULL)
|
||||
{
|
||||
TRACE("found entry in system list\n");
|
||||
LIST_FOR_EACH_ENTRY(font_link_entry, &font_link->links, CHILD_FONT, entry)
|
||||
{
|
||||
new_child = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_child));
|
||||
new_child->face = font_link_entry->face;
|
||||
new_child->font = NULL;
|
||||
new_child->face->refcount++;
|
||||
list_add_tail(&font->child_fonts, &new_child->entry);
|
||||
TRACE("font %s %ld\n", debugstr_w(new_child->face->file), new_child->face->face_index);
|
||||
}
|
||||
ret = TRUE;
|
||||
add_child_font( font, font_link_entry->face );
|
||||
}
|
||||
/*
|
||||
* if not SYMBOL or OEM then we also get all the fonts for Microsoft
|
||||
* Sans Serif. This is how asian windows get default fallbacks for fonts
|
||||
*/
|
||||
if (is_dbcs_ansi_cp(GetACP()) && gdi_font->charset != SYMBOL_CHARSET &&
|
||||
gdi_font->charset != OEM_CHARSET &&
|
||||
if (is_dbcs_ansi_cp(GetACP()) && font->charset != SYMBOL_CHARSET && font->charset != OEM_CHARSET &&
|
||||
strcmpiW(font_name,szDefaultFallbackLink) != 0)
|
||||
{
|
||||
font_link = find_font_link(szDefaultFallbackLink);
|
||||
|
@ -3542,19 +3561,9 @@ static BOOL create_child_font_list(GdiFont *font)
|
|||
{
|
||||
TRACE("found entry in default fallback list\n");
|
||||
LIST_FOR_EACH_ENTRY(font_link_entry, &font_link->links, CHILD_FONT, entry)
|
||||
{
|
||||
new_child = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_child));
|
||||
new_child->face = font_link_entry->face;
|
||||
new_child->font = NULL;
|
||||
new_child->face->refcount++;
|
||||
list_add_tail(&font->child_fonts, &new_child->entry);
|
||||
TRACE("font %s %ld\n", debugstr_w(new_child->face->file), new_child->face->face_index);
|
||||
}
|
||||
ret = TRUE;
|
||||
add_child_font( font, font_link_entry->face );
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL select_charmap(FT_Face ft_face, FT_Encoding encoding)
|
||||
|
@ -3791,7 +3800,6 @@ static BOOL CDECL freetype_load_font( struct gdi_font *gdi_font )
|
|||
if (!(font = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*font) ))) return FALSE;
|
||||
gdi_font->private = font;
|
||||
font->gdi_font = gdi_font;
|
||||
list_init( &font->child_fonts );
|
||||
|
||||
if (gdi_font->file[0])
|
||||
{
|
||||
|
@ -4244,7 +4252,7 @@ found_face:
|
|||
if (face->flags & ADDFONT_VERTICAL_FONT) /* We need to try to load the GSUB table */
|
||||
gdi_font->vert_feature = get_GSUB_vert_feature( gdi_font );
|
||||
|
||||
create_child_font_list(ret);
|
||||
create_child_font_list( gdi_font );
|
||||
|
||||
TRACE("caching: gdiFont=%p hfont=%p\n", ret, hfont);
|
||||
|
||||
|
@ -6199,61 +6207,13 @@ static BOOL CDECL freetype_set_outline_text_metrics( struct gdi_font *font )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL load_child_font(GdiFont *font, CHILD_FONT *child)
|
||||
{
|
||||
struct gdi_font *gdi_font = font->gdi_font;
|
||||
struct gdi_font *child_font;
|
||||
const struct list *face_list;
|
||||
Face *child_face = NULL, *best_face = NULL;
|
||||
UINT penalty = 0, new_penalty = 0;
|
||||
BOOL bold, italic, bd, it;
|
||||
|
||||
italic = !!gdi_font->lf.lfItalic;
|
||||
bold = gdi_font->lf.lfWeight > FW_MEDIUM;
|
||||
|
||||
face_list = get_face_list_from_family( child->face->family );
|
||||
LIST_FOR_EACH_ENTRY( child_face, face_list, Face, entry )
|
||||
{
|
||||
it = !!(child_face->ntmFlags & NTM_ITALIC);
|
||||
bd = !!(child_face->ntmFlags & NTM_BOLD);
|
||||
new_penalty = ( it ^ italic ) + ( bd ^ bold );
|
||||
if (!best_face || new_penalty < penalty)
|
||||
{
|
||||
penalty = new_penalty;
|
||||
best_face = child_face;
|
||||
}
|
||||
}
|
||||
child_face = best_face ? best_face : child->face;
|
||||
|
||||
child_font = alloc_gdi_font( child_face->file, child_face->font_data_ptr, child_face->font_data_size );
|
||||
child_font->fake_italic = italic && !( child_face->ntmFlags & NTM_ITALIC );
|
||||
child_font->fake_bold = bold && !( child_face->ntmFlags & NTM_BOLD );
|
||||
child_font->lf = gdi_font->lf;
|
||||
child_font->matrix = gdi_font->matrix;
|
||||
child_font->can_use_bitmap = gdi_font->can_use_bitmap;
|
||||
child_font->face_index = child_face->face_index;
|
||||
child_font->ntmFlags = child_face->ntmFlags;
|
||||
child_font->aa_flags = HIWORD( child_face->flags );
|
||||
child_font->scale_y = gdi_font->scale_y;
|
||||
child_font->base_font = gdi_font;
|
||||
set_gdi_font_names( child_font, child_face->family->family_name,
|
||||
child_face->style_name, child_face->full_name );
|
||||
if (!freetype_load_font( child_font ))
|
||||
{
|
||||
free_gdi_font(child_font);
|
||||
return FALSE;
|
||||
}
|
||||
child->font = get_font_ptr( child_font );
|
||||
TRACE("created child font %p for base %p\n", child->font, font);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL get_glyph_index_linked( struct gdi_font *gdi_font, UINT c, struct gdi_font **linked_font,
|
||||
FT_UInt *glyph, BOOL* vert)
|
||||
{
|
||||
GdiFont *font = get_font_ptr( gdi_font );
|
||||
FT_UInt g,o;
|
||||
CHILD_FONT *child_font;
|
||||
struct gdi_font *child;
|
||||
|
||||
if (gdi_font->base_font) gdi_font = gdi_font->base_font;
|
||||
*linked_font = gdi_font;
|
||||
|
@ -6268,21 +6228,17 @@ static BOOL get_glyph_index_linked( struct gdi_font *gdi_font, UINT c, struct gd
|
|||
|
||||
if (c < 32) goto done; /* don't check linked fonts for control characters */
|
||||
|
||||
LIST_FOR_EACH_ENTRY(child_font, &font->child_fonts, CHILD_FONT, entry)
|
||||
LIST_FOR_EACH_ENTRY( child, &gdi_font->child_fonts, struct gdi_font, entry )
|
||||
{
|
||||
if(!child_font->font)
|
||||
if(!load_child_font(font, child_font))
|
||||
continue;
|
||||
if (!child->private && !freetype_load_font( child )) continue;
|
||||
|
||||
if(!child_font->font->ft_face)
|
||||
continue;
|
||||
g = get_glyph_index(child_font->font, c);
|
||||
g = get_glyph_index(get_font_ptr(child), c);
|
||||
o = g;
|
||||
g = get_GSUB_vert_glyph(child_font->font->gdi_font, g);
|
||||
g = get_GSUB_vert_glyph(child, g);
|
||||
if(g)
|
||||
{
|
||||
*glyph = g;
|
||||
*linked_font = child_font->font->gdi_font;
|
||||
*linked_font = child;
|
||||
*vert = (o != g);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -6382,14 +6338,6 @@ static DWORD CDECL freetype_get_unicode_ranges( struct gdi_font *font, GLYPHSET
|
|||
return num_ranges;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* freetype_FontIsLinked
|
||||
*/
|
||||
static BOOL CDECL freetype_FontIsLinked( struct gdi_font *font )
|
||||
{
|
||||
return !list_empty( &get_font_ptr(font)->child_fonts );
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Kerning support for TrueType fonts
|
||||
*/
|
||||
|
@ -6606,7 +6554,6 @@ static DWORD CDECL freetype_get_kerning_pairs( struct gdi_font *gdi_font, KERNIN
|
|||
static const struct font_backend_funcs font_funcs =
|
||||
{
|
||||
freetype_EnumFonts,
|
||||
freetype_FontIsLinked,
|
||||
freetype_SelectFont,
|
||||
freetype_add_font,
|
||||
freetype_add_mem_font,
|
||||
|
|
|
@ -317,6 +317,7 @@ struct gdi_font
|
|||
int kern_count;
|
||||
/* the following members can be accessed without locking, they are never modified after creation */
|
||||
void *private; /* font backend private data */
|
||||
struct list child_fonts;
|
||||
DWORD handle;
|
||||
DWORD cache_num;
|
||||
DWORD hash;
|
||||
|
@ -368,7 +369,6 @@ struct gdi_font
|
|||
struct font_backend_funcs
|
||||
{
|
||||
BOOL (CDECL *pEnumFonts)( LOGFONTW *lf, FONTENUMPROCW proc, LPARAM lparam );
|
||||
BOOL (CDECL *pFontIsLinked)( struct gdi_font *font );
|
||||
struct gdi_font * (CDECL *pSelectFont)( DC *dc, HFONT hfont, UINT *aa_flags, UINT default_aa_flags );
|
||||
|
||||
INT (CDECL *add_font)( const WCHAR *file, DWORD flags );
|
||||
|
|
Loading…
Reference in New Issue