diff --git a/libass/ass_cache.c b/libass/ass_cache.c index 7100d6c069..2ed746c576 100644 --- a/libass/ass_cache.c +++ b/libass/ass_cache.c @@ -34,7 +34,7 @@ #define MAX_FONT_CACHE_SIZE 100 -static ass_font_t* font_cache; +static ass_font_t** font_cache; static int font_cache_size; static int font_compare(ass_font_desc_t* a, ass_font_desc_t* b) { @@ -48,39 +48,40 @@ static int font_compare(ass_font_desc_t* a, ass_font_desc_t* b) { } /** - * \brief Get a face object, either from cache or created through FreeType+FontConfig. - * \param library FreeType library object - * \param fontconfig_priv fontconfig private data + * \brief Get a face struct from cache. * \param desc required face description - * \return new font struct -*/ -ass_font_t* ass_new_font(FT_Library library, void* fontconfig_priv, ass_font_desc_t* desc) + * \return font struct +*/ +ass_font_t* ass_font_cache_find(ass_font_desc_t* desc) { int i; - ass_font_t* item; - int error; for (i=0; idesc))) + return font_cache[i]; + return 0; +} + +/** + * \brief Add a face struct to cache. + * \param font font struct +*/ +void ass_font_cache_add(ass_font_t* font) +{ if (font_cache_size == MAX_FONT_CACHE_SIZE) { mp_msg(MSGT_ASS, MSGL_FATAL, MSGTR_LIBASS_TooManyFonts); - return 0; + // FIXME: possible memory leak + return; } - item = font_cache + font_cache_size; - error = ass_font_init(library, fontconfig_priv, item, desc); - if (error) // FIXME: mp_msg - return 0; + font_cache[font_cache_size] = font; font_cache_size++; - - return item; } void ass_font_cache_init(void) { - font_cache = calloc(MAX_FONT_CACHE_SIZE, sizeof(ass_font_t)); + font_cache = calloc(MAX_FONT_CACHE_SIZE, sizeof(ass_font_t*)); font_cache_size = 0; } @@ -88,7 +89,7 @@ void ass_font_cache_done(void) { int i; for (i = 0; i < font_cache_size; ++i) { - ass_font_t* item = font_cache + i; + ass_font_t* item = font_cache[i]; ass_font_free(item); } free(font_cache); diff --git a/libass/ass_cache.h b/libass/ass_cache.h index 4fd5f79463..fb99e3418b 100644 --- a/libass/ass_cache.h +++ b/libass/ass_cache.h @@ -44,7 +44,8 @@ typedef struct ass_font_s { } ass_font_t; void ass_font_cache_init(void); -ass_font_t* ass_new_font(FT_Library library, void* fontconfig_priv, ass_font_desc_t* desc); +ass_font_t* ass_font_cache_find(ass_font_desc_t* desc); +void ass_font_cache_add(ass_font_t* font); void ass_font_cache_done(void); diff --git a/libass/ass_font.c b/libass/ass_font.c index 56e89a5c7f..189173e6b8 100644 --- a/libass/ass_font.c +++ b/libass/ass_font.c @@ -48,23 +48,29 @@ static void charmap_magic(FT_Face face) } } -int ass_font_init(FT_Library ftlibrary, void* fc_priv, ass_font_t* font, ass_font_desc_t* desc) +ass_font_t* ass_font_new(FT_Library ftlibrary, void* fc_priv, ass_font_desc_t* desc) { char* path; int index; FT_Face face; int error; + ass_font_t* font; + + font = ass_font_cache_find(desc); + if (font) + return font; path = fontconfig_select(fc_priv, desc->family, desc->bold, desc->italic, &index); error = FT_New_Face(ftlibrary, path, index, &face); if (error) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningFont, path, index); - return 1; + return 0; } charmap_magic(face); + font = calloc(1, sizeof(ass_font_t)); font->path = strdup(path); font->index = index; font->face = face; @@ -77,7 +83,9 @@ int ass_font_init(FT_Library ftlibrary, void* fc_priv, ass_font_t* font, ass_fon font->v.x = font->v.y = 0; font->size = 0; - return 0; + ass_font_cache_add(font); + + return font; } void ass_font_set_transform(ass_font_t* font, FT_Matrix* m, FT_Vector* v) @@ -133,4 +141,5 @@ void ass_font_free(ass_font_t* font) if (font->face) FT_Done_Face(font->face); if (font->path) free(font->path); if (font->desc.family) free(font->desc.family); + free(font); } diff --git a/libass/ass_font.h b/libass/ass_font.h index 0e5998ca60..4fa31d0b0d 100644 --- a/libass/ass_font.h +++ b/libass/ass_font.h @@ -29,7 +29,7 @@ #include "ass_bitmap.h" #include "ass_cache.h" -int ass_font_init(FT_Library ftlibrary, void* fc_priv, ass_font_t* font, ass_font_desc_t* desc); +ass_font_t* ass_font_new(FT_Library ftlibrary, void* fc_priv, ass_font_desc_t* desc); void ass_font_set_transform(ass_font_t* font, FT_Matrix* m, FT_Vector* v); void ass_font_set_size(ass_font_t* font, int size); FT_Glyph ass_font_get_glyph(void* fontconfig_priv, ass_font_t* font, uint32_t ch); diff --git a/libass/ass_render.c b/libass/ass_render.c index dc43129f01..7eda16ca48 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -561,7 +561,7 @@ static void update_font(void) else if (val == 1) val = 110; //italic desc.italic = val; - render_context.font = ass_new_font(priv->ftlibrary, priv->fontconfig_priv, &desc); + render_context.font = ass_font_new(priv->ftlibrary, priv->fontconfig_priv, &desc); if (render_context.font) change_font_size(render_context.font_size);