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 =
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;
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);
}
#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,
#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
// 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;
};
struct font_selector {
+ // uid counter
+ int uid;
+
// fallbacks
char *family_default;
char *path_default;
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);
}
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;
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);
}
* \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",
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,
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;
#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 *);
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