From 9f34be2732f4c1460a36de86e8cdeac92e821042 Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Thu, 11 Jun 2015 22:46:10 +0200 Subject: fontselect: simplify cmap lookup for embedded fonts FreeType can do it for us and is probably more efficient. Also fixes deinitialization order of ASS_Renderer to make this work. --- libass/ass_fontselect.c | 74 ++++++++----------------------------------------- libass/ass_render.c | 4 +-- 2 files changed, 13 insertions(+), 65 deletions(-) (limited to 'libass') diff --git a/libass/ass_fontselect.c b/libass/ass_fontselect.c index 7d00a7b..b1ead55 100644 --- a/libass/ass_fontselect.c +++ b/libass/ass_fontselect.c @@ -106,52 +106,29 @@ struct font_provider { void *priv; }; -// simple glyph coverage map -typedef struct coverage_map CoverageMap; -struct coverage_map { - int n_codepoint; - uint32_t *codepoints; -}; - typedef struct font_data_ft FontDataFT; struct font_data_ft { ASS_Library *lib; - CoverageMap *coverage; + FT_Face face; char *name; int idx; }; static int check_glyph_ft(void *data, uint32_t codepoint) { - int i; - CoverageMap *coverage = ((FontDataFT *)data)->coverage; + FontDataFT *fd = (FontDataFT *)data; if (!codepoint) return 1; - // XXX: sort at map creation and use bsearch here - is this worth it? - for (i = 0; i < coverage->n_codepoint; i++) - if (coverage->codepoints[i] == codepoint) - return 1; - - return 0; -} - -static void coverage_map_destroy(void *data) -{ - CoverageMap *coverage = (CoverageMap *)data; - - free(coverage->codepoints); - free(coverage); + return !!FT_Get_Char_Index(fd->face, codepoint); } static void destroy_font_ft(void *data) { FontDataFT *fd = (FontDataFT *)data; - if (fd->coverage) - coverage_map_destroy(fd->coverage); - + FT_Done_Face(fd->face); free(fd->name); free(fd); } @@ -694,39 +671,6 @@ static void free_font_info(ASS_FontProviderMetaData *meta) free(meta->fullnames); } -/** - * \brief Calculate a coverage map (array with codepoints) from a FreeType - * face. This can be used to check glyph coverage quickly. - * \param face FreeType face - * \return CoverageMap structure - */ -static CoverageMap *get_coverage_map(FT_Face face) -{ - int i = 0; - int n_codepoint = 0; - uint32_t codepoint; - unsigned index; - CoverageMap *coverage = calloc(1, sizeof(CoverageMap)); - - // determine number of codepoints first - codepoint = FT_Get_First_Char(face, &index); - while (index) { - n_codepoint++; - codepoint = FT_Get_Next_Char(face, codepoint, &index); - } - - coverage->codepoints = calloc(n_codepoint, sizeof(uint32_t)); - codepoint = FT_Get_First_Char(face, &index); - while (index) { - coverage->codepoints[i++] = codepoint; - codepoint = FT_Get_Next_Char(face, codepoint, &index); - } - - coverage->n_codepoint = n_codepoint; - - return coverage; -} - /** * \brief Process memory font. * \param priv private data @@ -771,14 +715,13 @@ static void process_fontdata(ASS_FontProvider *priv, ASS_Library *library, ft = calloc(1, sizeof(FontDataFT)); ft->lib = library; - ft->coverage = get_coverage_map(face); + ft->face = face; ft->name = strdup(name); ft->idx = -1; ass_font_provider_add_font(priv, &info, NULL, face_index, NULL, ft); free_font_info(&info); - FT_Done_Face(face); } } @@ -846,6 +789,10 @@ ass_fontselect_init(ASS_Library *library, priv->embedded_provider = ass_embedded_fonts_add_provider(library, priv, ftlibrary); + if (priv->embedded_provider == NULL) { + ass_msg(library, MSGL_WARN, "failed to create embedded font provider"); + } + if (dfp >= ASS_FONTPROVIDER_AUTODETECT) { int found = 0; for (int i = 0; !found && font_constructors[i].constructor; i++ ) @@ -887,7 +834,8 @@ void ass_fontselect_free(ASS_FontSelector *priv) { if (priv->default_provider) ass_font_provider_free(priv->default_provider); - ass_font_provider_free(priv->embedded_provider); + if (priv->embedded_provider) + ass_font_provider_free(priv->embedded_provider); // XXX: not quite sure, maybe we should track all registered // providers and free them right here. or should that be the diff --git a/libass/ass_render.c b/libass/ass_render.c index 5122128..4ce56f8 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -145,11 +145,11 @@ void ass_renderer_done(ASS_Renderer *render_priv) FT_Stroker_Done(render_priv->state.stroker); render_priv->state.stroker = 0; } - if (render_priv->ftlibrary) - FT_Done_FreeType(render_priv->ftlibrary); if (render_priv->fontselect) ass_fontselect_free(render_priv->fontselect); ass_shaper_free(render_priv->shaper); + if (render_priv->ftlibrary) + FT_Done_FreeType(render_priv->ftlibrary); free(render_priv->eimg); free(render_priv->text_info.glyphs); free(render_priv->text_info.lines); -- cgit v1.2.3