/** * \brief Init fontconfig. * \param library libass library object * \param ftlibrary freetype library object * \param family default font family * \param path default font path * \param fc whether fontconfig should be used * \param config path to a fontconfig configuration file, or NULL * \param update whether the fontconfig cache should be built/updated * \return pointer to fontconfig private data */ FCInstance *fontconfig_init(ASS_Library *library, FT_Library ftlibrary, const char *family, const char *path, int fc, const char *config, int update) { int rc; FCInstance *priv = calloc(1, sizeof(FCInstance)); const char *dir = library->fonts_dir; int i; if (!fc) { ass_msg(library, MSGL_WARN, "Fontconfig disabled, only default font will be used."); goto exit; } priv->config = FcConfigCreate(); rc = FcConfigParseAndLoad(priv->config, (unsigned char *) config, FcTrue); if (!rc) { ass_msg(library, MSGL_WARN, "No usable fontconfig configuration " "file found, using fallback."); FcConfigDestroy(priv->config); priv->config = FcInitLoadConfig(); rc++; } if (rc && update) { FcConfigBuildFonts(priv->config); } if (!rc || !priv->config) { ass_msg(library, MSGL_FATAL, "No valid fontconfig configuration found!"); FcConfigDestroy(priv->config); goto exit; } for (i = 0; i < library->num_fontdata; ++i) process_fontdata(priv, library, ftlibrary, i); if (dir) { ass_msg(library, MSGL_V, "Updating font cache"); rc = FcConfigAppFontAddDir(priv->config, (const FcChar8 *) dir); if (!rc) { ass_msg(library, MSGL_WARN, "%s failed", "FcConfigAppFontAddDir"); } } priv->family_default = family ? strdup(family) : NULL; exit: priv->path_default = path ? strdup(path) : NULL; priv->index_default = 0; return priv; }
/** * \brief Create font provider for embedded fonts. This parses the fonts known * to the current ASS_Library and adds them to the selector. * \param lib library * \param selector font selector * \param ftlib FreeType library - used for querying fonts * \return font provider */ static ASS_FontProvider * ass_embedded_fonts_add_provider(ASS_Library *lib, ASS_FontSelector *selector, FT_Library ftlib) { int i; ASS_FontProvider *priv = ass_font_provider_new(selector, &ft_funcs, NULL); if (priv == NULL) return NULL; if (lib->fonts_dir && lib->fonts_dir[0]) { load_fonts_from_dir(lib, lib->fonts_dir); } for (i = 0; i < lib->num_fontdata; ++i) process_fontdata(priv, lib, ftlib, i); return priv; }
/** * \brief Init fontconfig. * \param library libass library object * \param ftlibrary freetype library object * \param family default font family * \param path default font path * \return pointer to fontconfig private data */ fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, const char* family, const char* path) { int rc; fc_instance_t* priv = calloc(1, sizeof(fc_instance_t)); const char* dir = library->fonts_dir; int i; rc = FcInit(); assert(rc); priv->config = FcConfigGetCurrent(); if (!priv->config) { mp_msg(MSGT_ASS, MSGL_FATAL, MSGTR_LIBASS_FcInitLoadConfigAndFontsFailed); return 0; } for (i = 0; i < library->num_fontdata; ++i) process_fontdata(priv, library, ftlibrary, i); if (FcDirCacheValid((const FcChar8 *)dir) == FcFalse) { mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_UpdatingFontCache); if (FcGetVersion() >= 20390 && FcGetVersion() < 20400) mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_BetaVersionsOfFontconfigAreNotSupported); // FontConfig >= 2.4.0 updates cache automatically in FcConfigAppFontAddDir() if (FcGetVersion() < 20390) { FcFontSet* fcs; FcStrSet* fss; fcs = FcFontSetCreate(); fss = FcStrSetCreate(); rc = FcStrSetAdd(fss, (const FcChar8*)dir); if (!rc) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcStrSetAddFailed); goto ErrorFontCache; } rc = FcDirScan(fcs, fss, NULL, FcConfigGetBlanks(priv->config), (const FcChar8 *)dir, FcFalse); if (!rc) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcDirScanFailed); goto ErrorFontCache; } rc = FcDirSave(fcs, fss, (const FcChar8 *)dir); if (!rc) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcDirSave); goto ErrorFontCache; } ErrorFontCache: ; } } rc = FcConfigAppFontAddDir(priv->config, (const FcChar8*)dir); if (!rc) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcConfigAppFontAddDirFailed); } priv->family_default = family ? strdup(family) : 0; priv->path_default = path ? strdup(path) : 0; priv->index_default = 0; return priv; }