]> granicus.if.org Git - libass/commitdiff
Never add a face twice to an ASS_Font
authorGrigori Goronzy <greg@chown.ath.cx>
Wed, 17 Aug 2011 16:59:00 +0000 (18:59 +0200)
committerGrigori Goronzy <greg@chown.ath.cx>
Fri, 10 Jul 2015 08:42:40 +0000 (10:42 +0200)
Introduce a unique ID per font face and check it in add_face to make
sure we never add a font face twice. This is useful in case the glyph
coverage report is unreliable.

libass/ass_font.c
libass/ass_font.h
libass/ass_fontselect.c
libass/ass_fontselect.h

index 13ec654929d0b2a39909886d9af7658fe017ae73..16207d30bf789c7494ad02116df8ced780522700 100644 (file)
@@ -130,20 +130,27 @@ static void buggy_font_workaround(FT_Face face)
 static int add_face(ASS_FontSelector *fontsel, ASS_Font *font, uint32_t ch)
 {
     char *path;
-    int index;
+    int i, index, uid;
+    int error, mem_idx;
     FT_Face face;
-    int error;
-    int mem_idx;
 
     if (font->n_faces == ASS_FONT_MAX_FACES)
         return -1;
 
-    path = ass_font_select(fontsel, font->library, font->desc.family,
-            font->desc.bold, font->desc.italic, &index, ch);
+    path = ass_font_select(fontsel, font->library, font , &index, &uid, ch);
 
     if (!path)
         return -1;
 
+    for (i = 0; i < font->n_faces; i++) {
+        if (font->faces_uid[i] == uid) {
+            ass_msg(font->library, MSGL_INFO,
+                    "Got a font face that already is available! Skipping.");
+            free(path);
+            return -1;
+        }
+    }
+
     mem_idx = find_font(font->library, path);
     if (mem_idx >= 0) {
         error =
@@ -170,7 +177,8 @@ static int add_face(ASS_FontSelector *fontsel, ASS_Font *font, uint32_t ch)
     charmap_magic(font->library, face);
     buggy_font_workaround(face);
 
-    font->faces[font->n_faces++] = face;
+    font->faces[font->n_faces] = face;
+    font->faces_uid[font->n_faces++] = uid;
     ass_face_set_size(face, font->size);
     free(path);
     return font->n_faces - 1;
@@ -667,9 +675,10 @@ void ass_font_free(ASS_Font *font)
     int i;
     if (font->shaper_priv)
         ass_shaper_font_data_free(font->shaper_priv);
-    for (i = 0; i < font->n_faces; ++i)
+    for (i = 0; i < font->n_faces; ++i) {
         if (font->faces[i])
             FT_Done_Face(font->faces[i]);
+    }
     free(font->desc.family);
     free(font);
 }
index 9ccc83a2e7d42cebbddf7c4b679008dfa8d91999..f29e301f3ae6838870fa2ad9bc4ba25d5eaacc17 100644 (file)
 #include FT_GLYPH_H
 #include FT_OUTLINE_H
 
+typedef struct ass_font ASS_Font;
+typedef struct ass_font_desc ASS_FontDesc;
+
 #include "ass.h"
 #include "ass_types.h"
 #include "ass_fontselect.h"
+#include "ass_cache.h"
 
 #define VERTICAL_LOWER_BOUND 0x02f1
 
 #define DECO_UNDERLINE 1
 #define DECO_STRIKETHROUGH 2
 
-typedef struct ass_shaper_font_data ASS_ShaperFontData;
-
-typedef struct {
+struct ass_font_desc {
     char *family;
     unsigned bold;
     unsigned italic;
     int vertical;               // @font vertical layout
-} ASS_FontDesc;
+};
 
-typedef struct {
+struct ass_font {
     ASS_FontDesc desc;
     ASS_Library *library;
     FT_Library ftlibrary;
+    int faces_uid[ASS_FONT_MAX_FACES];
     FT_Face faces[ASS_FONT_MAX_FACES];
     ASS_ShaperFontData *shaper_priv;
     int n_faces;
     double scale_x, scale_y;    // current transform
     FT_Vector v;                // current shift
     double size;
-} ASS_Font;
-
-#include "ass_cache.h"
+};
 
 ASS_Font *ass_font_new(Cache *font_cache, ASS_Library *library,
                        FT_Library ftlibrary, ASS_FontSelector *fontsel,
index 2ca6f9dcbb6810fb5155a5bf8b2f8ddb009b280f..e1a57f2ca24f27cef0b6ff18ab534e00f5e75be6 100644 (file)
@@ -37,6 +37,7 @@
 #include "ass_library.h"
 #include "ass_fontselect.h"
 #include "ass_fontconfig.h"
+#include "ass_font.h"
 
 #define ABS(x) ((x) < 0 ? -(x) : (x))
 #define MAX_FULLNAME 100
@@ -44,6 +45,8 @@
 // proposed structure for holding font data, used for collection
 // and matching. strings are utf-8.
 struct font_info {
+    int uid;            // unique font face id
+
     char *family;       // family name
     char **fullnames;   // list of localized fullnames (e.g. Arial Bold Italic)
     int n_fullname;
@@ -66,6 +69,9 @@ struct font_info {
 };
 
 struct font_selector {
+    // uid counter
+    int uid;
+
     // fallbacks
     char *family_default;
     char *path_default;
@@ -121,6 +127,9 @@ ass_font_provider_add_font(ASS_FontProvider *provider,
     info = selector->font_infos + selector->n_font;
     memset(info, 0, sizeof(ASS_FontInfo));
 
+    // set uid
+    info->uid = selector->uid++;
+
     info->slant       = meta->slant;
     info->weight      = meta->weight;
     info->family      = strdup(meta->family);
@@ -245,8 +254,8 @@ static int font_info_compare(const void *av, const void *bv)
 }
 
 static char *select_font(ASS_FontSelector *priv, ASS_Library *library,
-                          const char *family, unsigned bold,
-                          unsigned italic, int *index, uint32_t code)
+                         const char *family, unsigned bold, unsigned italic,
+                         int *index, int *uid, uint32_t code)
 {
     int num_fonts = priv->n_font;
     ASS_FontInfo *font_infos = priv->font_infos;
@@ -288,6 +297,7 @@ static char *select_font(ASS_FontSelector *priv, ASS_Library *library,
     if (!font_infos[info_index].path)
         return NULL;
     *index = font_infos[info_index].index;
+    *uid   = font_infos[info_index].uid;
     return strdup(font_infos[info_index].path);
 }
 
@@ -304,17 +314,19 @@ static char *select_font(ASS_FontSelector *priv, ASS_Library *library,
  * \return font file path
 */
 char *ass_font_select(ASS_FontSelector *priv, ASS_Library *library,
-                      const char *family, unsigned bold, unsigned italic,
-                      int *index, uint32_t code)
+                      ASS_Font *font, int *index, int *uid, uint32_t code)
 {
     char *res = 0;
+    const char *family = font->desc.family;
+    unsigned bold = font->desc.bold;
+    unsigned italic = font->desc.italic;
 
     if (family && *family)
-        res = select_font(priv, library, family, bold, italic, index, code);
+        res = select_font(priv, library, family, bold, italic, index, uid, code);
 
     if (!res && priv->family_default) {
         res = select_font(priv, library, priv->family_default, bold,
-                italic, index, code);
+                italic, index, uid, code);
         if (res)
             ass_msg(library, MSGL_WARN, "fontselect: Using default "
                     "font family: (%s, %d, %d) -> %s, %d",
@@ -331,7 +343,7 @@ char *ass_font_select(ASS_FontSelector *priv, ASS_Library *library,
 
     if (!res) {
         res = select_font(priv, library, "Arial", bold, italic,
-                           index, code);
+                           index, uid, code);
         if (res)
             ass_msg(library, MSGL_WARN, "fontselect: Using 'Arial' "
                     "font family: (%s, %d, %d) -> %s, %d", family, bold,
@@ -467,6 +479,7 @@ ass_fontselect_init(ASS_Library *library,
     int i;
     ASS_FontSelector *priv = calloc(1, sizeof(ASS_FontSelector));
 
+    priv->uid = 1;
     priv->family_default = family ? strdup(family) : NULL;
     priv->path_default = path ? strdup(path) : NULL;
     priv->index_default = 0;
index 09c606be1ce850ac46da6929d191a936a61a8766..43a32fbb86a593620698e61d0727ffedfb3bcc6e 100644 (file)
 #define LIBASS_FONTCONFIG_H
 
 #include <stdint.h>
-#include "ass_types.h"
-#include "ass.h"
 #include <ft2build.h>
 #include FT_FREETYPE_H
 
+typedef struct ass_shaper_font_data ASS_ShaperFontData;
 typedef struct font_selector ASS_FontSelector;
 typedef struct font_provider ASS_FontProvider;
 typedef struct font_info ASS_FontInfo;
 
+#include "ass_types.h"
+#include "ass.h"
+#include "ass_font.h"
+
 // get face data
 typedef void *(*GetFaceFunc)(void *);
 
@@ -58,9 +61,8 @@ ASS_FontSelector *
 ass_fontselect_init(ASS_Library *library,
                     FT_Library ftlibrary, const char *family,
                     const char *path);
-char *ass_font_select(ASS_FontSelector *priv, ASS_Library *lib,
-                      const char *family, unsigned bold, unsigned italic,
-                      int *index, uint32_t code);
+char *ass_font_select(ASS_FontSelector *priv, ASS_Library *library,
+                      ASS_Font *font, int *index, int *uid, uint32_t code);
 void ass_fontselect_free(ASS_FontSelector *priv);
 
 // Font provider functions