# HG changeset patch # User eugeni # Date 1165170251 0 # Node ID 62bd8e0d3a0f553bf09a56b2279817259a0b465f # Parent 44b94d5d70e57ee89dedd9e5a05b4b5a05c6e895 Open embedded fonts directly from memory. FontConfig 2.4.2 (released yesterday) supports scanning fonts with FcFreeTypeQueryFace without writing them to disk. With earlier FontConfig versions, the old mechanism is used. diff -r 44b94d5d70e5 -r 62bd8e0d3a0f help/help_mp-en.h --- a/help/help_mp-en.h Sun Dec 03 18:22:07 2006 +0000 +++ b/help/help_mp-en.h Sun Dec 03 18:24:11 2006 +0000 @@ -2023,6 +2023,7 @@ #define MSGTR_LIBASS_FcDirSave "[ass] FcDirSave failed.\n" #define MSGTR_LIBASS_FcConfigAppFontAddDirFailed "[ass] FcConfigAppFontAddDir failed\n" #define MSGTR_LIBASS_FontconfigDisabledDefaultFontWillBeUsed "[ass] Fontconfig disabled, only default font will be used.\n" +#define MSGTR_LIBASS_FunctionCallFailed "[ass] %s failed\n" // ass_render.c #define MSGTR_LIBASS_NeitherPlayResXNorPlayResYDefined "[ass] Neither PlayResX nor PlayResY defined. Assuming 384x288.\n" @@ -2044,3 +2045,4 @@ // ass_font.c #define MSGTR_LIBASS_GlyphNotFoundReselectingFont "[ass] Glyph 0x%X not found, reselecting font for (%s, %d, %d)\n" #define MSGTR_LIBASS_GlyphNotFound "[ass] Glyph 0x%X not found in font for (%s, %d, %d)\n" +#define MSGTR_LIBASS_ErrorOpeningMemoryFont "[ass] Error opening memory font: %s\n" diff -r 44b94d5d70e5 -r 62bd8e0d3a0f libass/ass_font.c --- a/libass/ass_font.c Sun Dec 03 18:22:07 2006 +0000 +++ b/libass/ass_font.c Sun Dec 03 18:24:11 2006 +0000 @@ -52,13 +52,23 @@ } } -ass_font_t* ass_font_new(FT_Library ftlibrary, void* fc_priv, ass_font_desc_t* desc) +static int find_font(ass_library_t* library, char* name) +{ + int i; + for (i = 0; i < library->num_fontdata; ++i) + if (strcasecmp(name, library->fontdata[i].name) == 0) + return i; + return -1; +} + +ass_font_t* ass_font_new(ass_library_t* library, FT_Library ftlibrary, void* fc_priv, ass_font_desc_t* desc) { char* path; int index; FT_Face face; int error; ass_font_t* font; + int mem_idx; font = ass_font_cache_find(desc); if (font) @@ -66,11 +76,21 @@ path = fontconfig_select(fc_priv, desc->family, desc->bold, desc->italic, &index); + mem_idx = find_font(library, path); + if (mem_idx >= 0) { + error = FT_New_Memory_Face(ftlibrary, library->fontdata[mem_idx].data, + library->fontdata[mem_idx].size, 0, &face); + if (error) { + mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningMemoryFont, path); + return 0; + } + } else { error = FT_New_Face(ftlibrary, path, index, &face); if (error) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningFont, path, index); return 0; } + } charmap_magic(face); diff -r 44b94d5d70e5 -r 62bd8e0d3a0f libass/ass_font.h --- a/libass/ass_font.h Sun Dec 03 18:22:07 2006 +0000 +++ b/libass/ass_font.h Sun Dec 03 18:24:11 2006 +0000 @@ -45,7 +45,7 @@ #endif } ass_font_t; -ass_font_t* ass_font_new(FT_Library ftlibrary, void* fc_priv, ass_font_desc_t* desc); +ass_font_t* ass_font_new(ass_library_t* library, 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 -r 44b94d5d70e5 -r 62bd8e0d3a0f libass/ass_fontconfig.c --- a/libass/ass_fontconfig.c Sun Dec 03 18:22:07 2006 +0000 +++ b/libass/ass_fontconfig.c Sun Dec 03 18:24:11 2006 +0000 @@ -34,6 +34,7 @@ #ifdef HAVE_FONTCONFIG #include +#include #endif struct fc_instance_s { @@ -228,7 +229,7 @@ * \param data binary font data * \param data_size data size */ -static void process_fontdata(fc_instance_t* priv, ass_library_t* library, int idx) +static void process_fontdata(fc_instance_t* priv, ass_library_t* library, FT_Library ftlibrary, int idx) { char buf[1000]; FILE* fp = 0; @@ -239,7 +240,12 @@ const char* data = library->fontdata[idx].data; int data_size = library->fontdata[idx].size; const char* fonts_dir = library->fonts_dir; + FT_Face face; + FcPattern* pattern; + FcFontSet* fset; + FcBool res; +#if (FC_VERSION < 20402) if (!fonts_dir) return; rc = stat(fonts_dir, &st); @@ -267,6 +273,38 @@ fwrite(data, data_size, 1, fp); fclose(fp); + +#else // (FC_VERSION >= 20402) + + rc = FT_New_Memory_Face(ftlibrary, data, data_size, 0, &face); + if (rc) { + mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningMemoryFont, name); + return; + } + + pattern = FcFreeTypeQueryFace(face, name, 0, FcConfigGetBlanks(priv->config)); + if (!pattern) { + mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed, "FcFreeTypeQueryFace"); + FT_Done_Face(face); + return; + } + + fset = FcConfigGetFonts(priv->config, FcSetSystem); // somehow it failes when asked for FcSetApplication + if (!fset) { + mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed, "FcConfigGetFonts"); + FT_Done_Face(face); + return; + } + + res = FcFontSetAdd(fset, pattern); + if (!res) { + mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed, "FcFontSetAdd"); + FT_Done_Face(face); + return; + } + + FT_Done_Face(face); +#endif } /** @@ -276,7 +314,7 @@ * \param path default font path * \return pointer to fontconfig private data */ -fc_instance_t* fontconfig_init(ass_library_t* library, const char* family, const char* path) +fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, const char* family, const char* path) { int rc; struct stat st; @@ -294,7 +332,7 @@ } for (i = 0; i < library->num_fontdata; ++i) - process_fontdata(priv, library, i); + process_fontdata(priv, library, ftlibrary, i); if (FcDirCacheValid((const FcChar8 *)dir) == FcFalse) { @@ -355,7 +393,7 @@ return priv->path_default; } -fc_instance_t* fontconfig_init(ass_library_t* library, const char* family, const char* path) +fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, const char* family, const char* path) { fc_instance_t* priv; diff -r 44b94d5d70e5 -r 62bd8e0d3a0f libass/ass_fontconfig.h --- a/libass/ass_fontconfig.h Sun Dec 03 18:22:07 2006 +0000 +++ b/libass/ass_fontconfig.h Sun Dec 03 18:24:11 2006 +0000 @@ -27,7 +27,7 @@ typedef struct fc_instance_s fc_instance_t; -fc_instance_t* fontconfig_init(ass_library_t* library, const char* family, const char* path); +fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, const char* family, const char* path); char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index); void fontconfig_done(fc_instance_t* priv); diff -r 44b94d5d70e5 -r 62bd8e0d3a0f libass/ass_render.c --- a/libass/ass_render.c Sun Dec 03 18:22:07 2006 +0000 +++ b/libass/ass_render.c Sun Dec 03 18:24:11 2006 +0000 @@ -561,7 +561,7 @@ else if (val == 1) val = 110; //italic desc.italic = val; - render_context.font = ass_font_new(priv->ftlibrary, priv->fontconfig_priv, &desc); + render_context.font = ass_font_new(priv->library, priv->ftlibrary, priv->fontconfig_priv, &desc); if (render_context.font) change_font_size(render_context.font_size); @@ -1928,7 +1928,7 @@ if (priv->fontconfig_priv) fontconfig_done(priv->fontconfig_priv); - priv->fontconfig_priv = fontconfig_init(priv->library, default_family, default_font); + priv->fontconfig_priv = fontconfig_init(priv->library, priv->ftlibrary, default_family, default_font); return !!priv->fontconfig_priv; }