summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libass/ass_font.c18
-rw-r--r--libass/ass_font.h2
-rw-r--r--libass/ass_fontselect.h1
-rw-r--r--libass/ass_shaper.c89
-rw-r--r--libass/ass_shaper.h3
5 files changed, 47 insertions, 66 deletions
diff --git a/libass/ass_font.c b/libass/ass_font.c
index bd36f79..72ec888 100644
--- a/libass/ass_font.c
+++ b/libass/ass_font.c
@@ -424,6 +424,7 @@ static int add_face(ASS_FontSelector *fontsel, ASS_Font *font, uint32_t ch)
int i, index, uid;
ASS_FontStream stream = { NULL, NULL };
FT_Face face;
+ int ret = -1;
if (font->n_faces == ASS_FONT_MAX_FACES)
return -1;
@@ -457,8 +458,16 @@ static int add_face(ASS_FontSelector *fontsel, ASS_Font *font, uint32_t ch)
set_font_metrics(face);
font->faces[font->n_faces] = face;
- font->faces_uid[font->n_faces++] = uid;
- return font->n_faces - 1;
+ font->faces_uid[font->n_faces] = uid;
+ if (!ass_create_hb_font(font, font->n_faces)) {
+ FT_Done_Face(face);
+ goto fail;
+ }
+
+ ret = font->n_faces++;
+
+fail:
+ return ret;
}
/**
@@ -483,7 +492,6 @@ size_t ass_font_construct(void *key, void *value, void *priv)
font->library = render_priv->library;
font->ftlibrary = render_priv->ftlibrary;
- font->shaper_priv = NULL;
font->n_faces = 0;
font->desc.family = desc->family;
font->desc.bold = desc->bold;
@@ -698,11 +706,11 @@ bool ass_font_get_glyph(ASS_Font *font, int face_index, int index,
void ass_font_clear(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) {
if (font->faces[i])
FT_Done_Face(font->faces[i]);
+ if (font->hb_fonts[i])
+ hb_font_destroy(font->hb_fonts[i]);
}
free((char *) font->desc.family.str);
}
diff --git a/libass/ass_font.h b/libass/ass_font.h
index 8288a19..df9fb30 100644
--- a/libass/ass_font.h
+++ b/libass/ass_font.h
@@ -44,7 +44,7 @@ struct ass_font {
FT_Library ftlibrary;
int faces_uid[ASS_FONT_MAX_FACES];
FT_Face faces[ASS_FONT_MAX_FACES];
- ASS_ShaperFontData *shaper_priv;
+ struct hb_font_t *hb_fonts[ASS_FONT_MAX_FACES];
int n_faces;
};
diff --git a/libass/ass_fontselect.h b/libass/ass_fontselect.h
index 43366bb..23bcad4 100644
--- a/libass/ass_fontselect.h
+++ b/libass/ass_fontselect.h
@@ -24,7 +24,6 @@
#include <ft2build.h>
#include FT_FREETYPE_H
-typedef struct ass_shaper_font_data ASS_ShaperFontData;
typedef struct font_selector ASS_FontSelector;
typedef struct font_info ASS_FontInfo;
typedef struct ass_font_stream ASS_FontStream;
diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c
index a5efdca..fa445da 100644
--- a/libass/ass_shaper.c
+++ b/libass/ass_shaper.c
@@ -82,11 +82,6 @@ struct ass_shaper_metrics_data {
int vertical;
};
-struct ass_shaper_font_data {
- hb_font_t *fonts[ASS_FONT_MAX_FACES];
- struct ass_shaper_metrics_data *metrics_data[ASS_FONT_MAX_FACES];
-};
-
/**
* \brief Print version information
*/
@@ -149,17 +144,6 @@ void ass_shaper_free(ASS_Shaper *shaper)
free(shaper);
}
-void ass_shaper_font_data_free(ASS_ShaperFontData *priv)
-{
- int i;
- for (i = 0; i < ASS_FONT_MAX_FACES; i++)
- if (priv->fonts[i]) {
- free(priv->metrics_data[i]);
- hb_font_destroy(priv->fonts[i]);
- }
- free(priv);
-}
-
/**
* \brief set up the HarfBuzz OpenType feature list with some
* standard features.
@@ -442,6 +426,26 @@ get_contour_point(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
return true;
}
+bool ass_create_hb_font(ASS_Font *font, int index)
+{
+ FT_Face face = font->faces[index];
+ hb_face_t *hb_face = hb_face_create_for_tables(get_reference_table, face, NULL);
+ if (!hb_face)
+ return false;
+
+ hb_face_set_index(hb_face, face->face_index);
+ hb_face_set_upem(hb_face, face->units_per_EM);
+
+ hb_font_t *hb_font = hb_font_create(hb_face);
+ hb_face_destroy(hb_face);
+ if (!hb_font)
+ return false;
+
+ font->hb_fonts[index] = hb_font;
+
+ return true;
+}
+
/**
* \brief Retrieve HarfBuzz font from cache.
* Create it from FreeType font, if needed.
@@ -451,54 +455,25 @@ get_contour_point(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
static hb_font_t *get_hb_font(ASS_Shaper *shaper, GlyphInfo *info)
{
ASS_Font *font = info->font;
- hb_font_t **hb_fonts;
-
- if (!font->shaper_priv)
- font->shaper_priv = calloc(sizeof(ASS_ShaperFontData), 1);
- if (!font->shaper_priv)
+ hb_font_t *hb_font = font->hb_fonts[info->face_index];
+ if (!hb_font)
return NULL;
- hb_fonts = font->shaper_priv->fonts;
- if (!hb_fonts[info->face_index]) {
- FT_Face face = font->faces[info->face_index];
- hb_face_t *hb_face = hb_face_create_for_tables(get_reference_table, face, NULL);
- if (!hb_face)
- return NULL;
- hb_face_set_index(hb_face, face->face_index);
- hb_face_set_upem(hb_face, face->units_per_EM);
-
- hb_font_t *hb_font = hb_fonts[info->face_index] = hb_font_create(hb_face);
- hb_face_destroy(hb_face);
- if (!hb_font)
- return NULL;
-
- hb_font_set_scale(hb_font,
- (int)(((uint64_t)face->size->metrics.x_scale * face->units_per_EM + (1<<15)) >> 16),
- (int)(((uint64_t)face->size->metrics.y_scale * face->units_per_EM + (1<<15)) >> 16));
-
- // set up cached metrics access
- struct ass_shaper_metrics_data *metrics =
- font->shaper_priv->metrics_data[info->face_index] =
- calloc(sizeof(struct ass_shaper_metrics_data), 1);
- if (!metrics)
- return NULL;
- metrics->metrics_cache = shaper->metrics_cache;
- metrics->vertical = info->font->desc.vertical;
-
- hb_font_set_funcs(hb_font, shaper->font_funcs, metrics, NULL);
- }
-
+ // set up cached metrics access
+ struct ass_shaper_metrics_data *metrics = calloc(sizeof(struct ass_shaper_metrics_data), 1);
+ if (!metrics)
+ return NULL;
ass_face_set_size(font->faces[info->face_index], info->font_size);
- update_hb_size(hb_fonts[info->face_index], font->faces[info->face_index]);
-
- // update hash key for cached metrics
- struct ass_shaper_metrics_data *metrics =
- font->shaper_priv->metrics_data[info->face_index];
+ update_hb_size(hb_font, font->faces[info->face_index]);
+ metrics->metrics_cache = shaper->metrics_cache;
metrics->hash_key.font = info->font;
metrics->hash_key.face_index = info->face_index;
metrics->hash_key.size = info->font_size;
+ metrics->vertical = info->font->desc.vertical;
+
+ hb_font_set_funcs(hb_font, shaper->font_funcs, metrics, free);
- return hb_fonts[info->face_index];
+ return hb_font;
}
/**
diff --git a/libass/ass_shaper.h b/libass/ass_shaper.h
index 819a3fd..b4694b0 100644
--- a/libass/ass_shaper.h
+++ b/libass/ass_shaper.h
@@ -33,6 +33,7 @@ typedef struct ass_shaper ASS_Shaper;
void ass_shaper_info(ASS_Library *lib);
ASS_Shaper *ass_shaper_new(Cache *metrics_cache);
void ass_shaper_free(ASS_Shaper *shaper);
+bool ass_create_hb_font(ASS_Font *font, int index);
void ass_shaper_set_kerning(ASS_Shaper *shaper, bool kern);
void ass_shaper_find_runs(ASS_Shaper *shaper, ASS_Renderer *render_priv,
GlyphInfo *glyphs, size_t len);
@@ -49,6 +50,4 @@ FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info);
FriBidiStrIndex *ass_shaper_get_reorder_map(ASS_Shaper *shaper);
FriBidiParType ass_resolve_base_direction(int font_encoding);
-void ass_shaper_font_data_free(ASS_ShaperFontData *priv);
-
#endif