From: Grigori Goronzy Date: Sun, 10 Jul 2011 02:08:55 +0000 (+0200) Subject: Separate glyph font face matching and glyph loading X-Git-Tag: 0.10.0~50 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4805334bf91444ba7e818145944f8236a64b0563;p=libass Separate glyph font face matching and glyph loading Split up ass_font_get_glyph into two functions: one function matches checks the fonts for support of the requested codepoint and returns a face_index and glyph_index to later load the glyph, with a second function. This approach is very useful for shaping, which needs to be done on runs with the same font face and font size and changes the glyph_index. --- diff --git a/libass/ass_font.c b/libass/ass_font.c index 39c591e..af1f350 100644 --- a/libass/ass_font.c +++ b/libass/ass_font.c @@ -422,33 +422,35 @@ static void ass_glyph_embolden(FT_GlyphSlot slot) } /** - * \brief Get a glyph - * \param ch character code - **/ -FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font, - uint32_t ch, ASS_Hinting hinting, int deco) + * \brief Get glyph and face index + * Finds a face that has the requested codepoint and returns both face + * and glyph index. + */ +int ass_font_get_index(void *fcpriv, ASS_Font *font, uint32_t symbol, + int *face_index, int *glyph_index) { - int error; int index = 0; int i; - FT_Glyph glyph; FT_Face face = 0; - int flags = 0; - int vertical = font->desc.vertical; - if (ch < 0x20) + *face_index = 0; + *face_index = 0; + + if (symbol < 0x20) return 0; // Handle NBSP like a regular space when rendering the glyph - if (ch == 0xa0) - ch = ' '; + if (symbol == 0xa0) + symbol = ' '; if (font->n_faces == 0) return 0; for (i = 0; i < font->n_faces; ++i) { face = font->faces[i]; - index = FT_Get_Char_Index(face, ch); - if (index) + index = FT_Get_Char_Index(face, symbol); + if (index) { + *face_index = i; break; + } } #ifdef CONFIG_FONTCONFIG @@ -456,30 +458,48 @@ FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font, int face_idx; ass_msg(font->library, MSGL_INFO, "Glyph 0x%X not found, selecting one more " - "font for (%s, %d, %d)", ch, font->desc.family, + "font for (%s, %d, %d)", symbol, font->desc.family, font->desc.bold, font->desc.italic); - face_idx = add_face(fontconfig_priv, font, ch); + face_idx = *face_index = add_face(fcpriv, font, symbol); if (face_idx >= 0) { face = font->faces[face_idx]; - index = FT_Get_Char_Index(face, ch); + index = FT_Get_Char_Index(face, symbol); if (index == 0 && face->num_charmaps > 0) { int i; ass_msg(font->library, MSGL_WARN, - "Glyph 0x%X not found, broken font? Trying all charmaps", ch); + "Glyph 0x%X not found, broken font? Trying all charmaps", symbol); for (i = 0; i < face->num_charmaps; i++) { FT_Set_Charmap(face, face->charmaps[i]); - if ((index = FT_Get_Char_Index(face, ch)) != 0) break; + if ((index = FT_Get_Char_Index(face, symbol)) != 0) break; } } if (index == 0) { ass_msg(font->library, MSGL_ERR, "Glyph 0x%X not found in font for (%s, %d, %d)", - ch, font->desc.family, font->desc.bold, + symbol, font->desc.family, font->desc.bold, font->desc.italic); } } } #endif + *glyph_index = index; + + return 1; +} + +/** + * \brief Get a glyph + * \param ch character code + **/ +FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font, + uint32_t ch, int face_index, int index, + ASS_Hinting hinting, int deco) +{ + int error; + FT_Glyph glyph; + FT_Face face = font->faces[face_index]; + int flags = 0; + int vertical = font->desc.vertical; flags = FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_IGNORE_TRANSFORM; diff --git a/libass/ass_font.h b/libass/ass_font.h index af40ce2..6b45adf 100644 --- a/libass/ass_font.h +++ b/libass/ass_font.h @@ -60,8 +60,11 @@ void ass_font_set_transform(ASS_Font *font, double scale_x, void ass_font_set_size(ASS_Font *font, double size); void ass_font_get_asc_desc(ASS_Font *font, uint32_t ch, int *asc, int *desc); +int ass_font_get_index(void *fcpriv, ASS_Font *font, uint32_t symbol, + int *face_index, int *glyph_index); FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font, - uint32_t ch, ASS_Hinting hinting, int flags); + uint32_t ch, int face_index, int index, + ASS_Hinting hinting, int deco); FT_Vector ass_font_get_kerning(ASS_Font *font, uint32_t c1, uint32_t c2); void ass_font_free(ASS_Font *font); void fix_freetype_stroker(FT_Outline *outline, int border_x, int border_y); diff --git a/libass/ass_render.c b/libass/ass_render.c index b418bb1..3aaf943 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -1106,13 +1106,17 @@ get_outline_glyph(ASS_Renderer *render_priv, GlyphInfo *info) } else { double size_scaled = ensure_font_size(render_priv, info->font_size * render_priv->font_scale); + int face_index = 0; + int index = 0; ass_font_set_size(info->font, size_scaled); ass_font_set_transform(info->font, info->scale_x, info->scale_y, NULL); + ass_font_get_index(render_priv->fontconfig_priv, info->font, + info->symbol, &face_index, &index); FT_Glyph glyph = ass_font_get_glyph(render_priv->fontconfig_priv, info->font, - info->symbol, render_priv->settings.hinting, - info->flags); + info->symbol, face_index, index, + render_priv->settings.hinting, info->flags); if (glyph != NULL) { outline_copy(render_priv->ftlibrary, &((FT_OutlineGlyph)glyph)->outline, &info->outline);