summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@chown.ath.cx>2011-08-17 18:59:00 +0200
committerGrigori Goronzy <greg@chown.ath.cx>2015-07-10 10:42:40 +0200
commit38f4a39bdbe6090d39e86b620c772ba5cd88c8a5 (patch)
tree8e67b50042c1c732c3100838eb22e4dcd90545dd
parentd5091c88d10cbea95f3e45b31a8738d7cd8e3819 (diff)
downloadlibass-38f4a39bdbe6090d39e86b620c772ba5cd88c8a5.tar.bz2
libass-38f4a39bdbe6090d39e86b620c772ba5cd88c8a5.tar.xz
Never add a face twice to an ASS_Font
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.
-rw-r--r--libass/ass_font.c23
-rw-r--r--libass/ass_font.h17
-rw-r--r--libass/ass_fontselect.c27
-rw-r--r--libass/ass_fontselect.h12
4 files changed, 52 insertions, 27 deletions
diff --git a/libass/ass_font.c b/libass/ass_font.c
index 13ec654..16207d3 100644
--- a/libass/ass_font.c
+++ b/libass/ass_font.c
@@ -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);
}
diff --git a/libass/ass_font.h b/libass/ass_font.h
index 9ccc83a..f29e301 100644
--- a/libass/ass_font.h
+++ b/libass/ass_font.h
@@ -24,9 +24,13 @@
#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
@@ -34,28 +38,25 @@
#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,
diff --git a/libass/ass_fontselect.c b/libass/ass_fontselect.c
index 2ca6f9d..e1a57f2 100644
--- a/libass/ass_fontselect.c
+++ b/libass/ass_fontselect.c
@@ -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;
diff --git a/libass/ass_fontselect.h b/libass/ass_fontselect.h
index 09c606b..43a32fb 100644
--- a/libass/ass_fontselect.h
+++ b/libass/ass_fontselect.h
@@ -20,15 +20,18 @@
#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