From e15ae9a60043d8d9c1b110607c5059f13ca86421 Mon Sep 17 00:00:00 2001 From: eugeni Date: Fri, 7 Jul 2006 18:26:51 +0000 Subject: Initial libass release (without mencoder support). git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@18942 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libass/ass_fontconfig.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 libass/ass_fontconfig.c (limited to 'libass/ass_fontconfig.c') diff --git a/libass/ass_fontconfig.c b/libass/ass_fontconfig.c new file mode 100644 index 0000000000..e75bcbc058 --- /dev/null +++ b/libass/ass_fontconfig.c @@ -0,0 +1,192 @@ +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "mp_msg.h" +#include "ass_fontconfig.h" + +#ifdef HAVE_FONTCONFIG +#include +#endif + +struct fc_instance_s { +#ifdef HAVE_FONTCONFIG + FcConfig* config; +#endif + char* family_default; + char* path_default; + int index_default; +}; + +extern int no_more_font_messages; + +#ifdef HAVE_FONTCONFIG +/** + * \brief Low-level font selection. + * \param priv private data + * \param family font family + * \param bold font weight value + * \param italic font slant value + * \param index out: font index inside a file + * \return font file path +*/ +static char* _select_font(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index) +{ + FcBool rc; + FcResult result; + FcPattern *pat, *rpat; + int val_i; + FcChar8* val_s; + char buf[2000]; + + *index = 0; + + snprintf(buf, 2000, "%s:outline=True:slant=%u:weight=%u", family, italic, bold); + + pat = FcNameParse((const FcChar8*)buf); + if (!pat) + return 0; + + FcDefaultSubstitute(pat); + + rc = FcConfigSubstitute(priv->config, pat, FcMatchPattern); + if (!rc) + return 0; + + rpat = FcFontMatch(priv->config, pat, &result); + if (!rpat) + return 0; + + result = FcPatternGetInteger(rpat, FC_INDEX, 0, &val_i); + if (result != FcResultMatch) + return 0; + *index = val_i; + + result = FcPatternGetString(rpat, FC_FAMILY, 0, &val_s); + if (result != FcResultMatch) + return 0; + + if (strcasecmp((const char*)val_s, family) != 0) + mp_msg(MSGT_GLOBAL, MSGL_WARN, "fontconfig: selected font family is not the requested one: '%s' != '%s'\n", + (const char*)val_s, family); + + result = FcPatternGetString(rpat, FC_FILE, 0, &val_s); + if (result != FcResultMatch) + return 0; + + return strdup((const char*)val_s); +} + +/** + * \brief Find a font. Use default family or path if necessary. + * \param priv_ private data + * \param family font family + * \param bold font weight value + * \param italic font slant value + * \param index out: font index inside a file + * \return font file path +*/ +char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index) +{ + char* res = 0; + if (family && *family) + res = _select_font(priv, family, bold, italic, index); + if (!res && priv->family_default) { + res = _select_font(priv, priv->family_default, bold, italic, index); + if (res && !no_more_font_messages) + mp_msg(MSGT_GLOBAL, MSGL_WARN, "fontconfig_select: using default font family: (%s, %d, %d) -> %s, %d\n", + family, bold, italic, res, *index); + } + if (!res && priv->path_default) { + res = priv->path_default; + *index = priv->index_default; + if (!no_more_font_messages) + mp_msg(MSGT_GLOBAL, MSGL_WARN, "fontconfig_select: using default font: (%s, %d, %d) -> %s, %d\n", + family, bold, italic, res, *index); + } + if (!res) { + res = _select_font(priv, "Arial", bold, italic, index); + if (res && !no_more_font_messages) + mp_msg(MSGT_GLOBAL, MSGL_WARN, "fontconfig_select: using 'Arial' font family: (%s, %d, %d) -> %s, %d\n", + family, bold, italic, res, *index); + } + if (res) + mp_msg(MSGT_GLOBAL, MSGL_V, "fontconfig_select: (%s, %d, %d) -> %s, %d\n", + family, bold, italic, res, *index); + return res; +} + +/** + * \brief Init fontconfig. + * \param dir additional directoryu for fonts + * \param family default font family + * \param path default font path + * \return pointer to fontconfig private data +*/ +fc_instance_t* fontconfig_init(const char* dir, const char* family, const char* path) +{ + int rc; + struct stat st; + fc_instance_t* priv = calloc(1, sizeof(fc_instance_t)); + + rc = FcInit(); + assert(rc); + + priv->config = FcConfigGetCurrent(); + if (!priv->config) { + mp_msg(MSGT_GLOBAL, MSGL_FATAL, "FcInitLoadConfigAndFonts failed\n"); + return 0; + } + + rc = FcConfigAppFontAddDir(priv->config, (const FcChar8*)dir); + if (!rc) { + mp_msg(MSGT_GLOBAL, MSGL_WARN, "FcConfigAppFontAddDir failed\n"); + } + + priv->family_default = family ? strdup(family) : 0; + priv->index_default = 0; + + rc = stat(path, &st); + if (!rc && S_ISREG(st.st_mode)) + priv->path_default = path ? strdup(path) : 0; + else + priv->path_default = 0; + + return priv; +} + +#else + +char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index) +{ + *index = priv->index_default; + return priv->path_default; +} + +fc_instance_t* fontconfig_init(const char* dir, const char* family, const char* path) +{ + mp_msg(MSGT_GLOBAL, MSGL_WARN, "Fontconfig disabled, only default font will be used\n"); + + fc_instance_t* priv = calloc(1, sizeof(fc_instance_t)); + + priv->path_default = strdup(path); + priv->index_default = 0; + return priv; +} + +#endif + +void fontconfig_done(fc_instance_t* priv) +{ + // don't call FcFini() here, library can still be used by some code + if (priv && priv->path_default) free(priv->path_default); + if (priv && priv->family_default) free(priv->family_default); + if (priv) free(priv); +} + + -- cgit v1.2.3