summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@blackbox>2011-07-10 04:08:55 +0200
committerGrigori Goronzy <greg@blackbox>2011-07-11 13:05:02 +0200
commit4805334bf91444ba7e818145944f8236a64b0563 (patch)
treec20374d43fc1e3e5e238dd2952ed2307f4a0c881
parente1b63bc3abfac4d1e994cbe46a4d3f820062b880 (diff)
downloadlibass-4805334bf91444ba7e818145944f8236a64b0563.tar.bz2
libass-4805334bf91444ba7e818145944f8236a64b0563.tar.xz
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.
-rw-r--r--libass/ass_font.c60
-rw-r--r--libass/ass_font.h5
-rw-r--r--libass/ass_render.c8
3 files changed, 50 insertions, 23 deletions
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);