diff options
-rw-r--r-- | libass/ass_font.c | 18 | ||||
-rw-r--r-- | libass/ass_font.h | 2 | ||||
-rw-r--r-- | libass/ass_fontselect.h | 1 | ||||
-rw-r--r-- | libass/ass_shaper.c | 89 | ||||
-rw-r--r-- | libass/ass_shaper.h | 3 |
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 |