]> granicus.if.org Git - libass/commitdiff
Separate glyph font face matching and glyph loading
authorGrigori Goronzy <greg@blackbox>
Sun, 10 Jul 2011 02:08:55 +0000 (04:08 +0200)
committerGrigori Goronzy <greg@blackbox>
Mon, 11 Jul 2011 11:05:02 +0000 (13:05 +0200)
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.

libass/ass_font.c
libass/ass_font.h
libass/ass_render.c

index 39c591e220e4734c211f9cff177aacd4a7af5396..af1f350dc60fe2f9b7ecfc3e420dcef0c9bf8c8a 100644 (file)
@@ -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;
index af40ce2fb850fed36942c2ad42081845a50689a1..6b45adf5319c44a1596ee74aadf3609d62b5ab14 100644 (file)
@@ -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);
index b418bb18264c9a615e12b3ce96cab6ba97aff992..3aaf94358a6d704aab847034c5c9fbd3aa891941 100644 (file)
@@ -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);