summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreugeni <eugeni@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-11-28 22:50:02 +0000
committereugeni <eugeni@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-11-28 22:50:02 +0000
commit9fdb13fd53214359318f63942d00001d18ce3124 (patch)
tree3f76f1346ccde116ba0e4f1829231e1bbeed7758
parenta4d33dbb470b02ddcdcfa73746146c47dda9addb (diff)
downloadmpv-9fdb13fd53214359318f63942d00001d18ce3124.tar.bz2
mpv-9fdb13fd53214359318f63942d00001d18ce3124.tar.xz
If a glyph is not found in the current font, switch to another one.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@21367 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r--help/help_mp-en.h3
-rw-r--r--libass/ass_font.c55
-rw-r--r--libass/ass_font.h7
-rw-r--r--libass/ass_fontconfig.c65
-rw-r--r--libass/ass_fontconfig.h8
5 files changed, 124 insertions, 14 deletions
diff --git a/help/help_mp-en.h b/help/help_mp-en.h
index 4c1eccd219..90c1522532 100644
--- a/help/help_mp-en.h
+++ b/help/help_mp-en.h
@@ -2041,3 +2041,6 @@ static char help_text[]=
#define MSGTR_LIBASS_EventHeightHasChanged "[ass] Warning! Event height has changed! \n"
#define MSGTR_LIBASS_TooManySimultaneousEvents "[ass] Too many simultaneous events!\n"
+// 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"
diff --git a/libass/ass_font.c b/libass/ass_font.c
index 3120db04f2..2a44c9fc2c 100644
--- a/libass/ass_font.c
+++ b/libass/ass_font.c
@@ -86,6 +86,10 @@ ass_font_t* ass_font_new(FT_Library ftlibrary, void* fc_priv, ass_font_desc_t* d
font->v.x = font->v.y = 0;
font->size = 0;
+#ifdef HAVE_FONTCONFIG
+ font->charset = FcCharSetCreate();
+#endif
+
ass_font_cache_add(font);
return font;
@@ -118,6 +122,40 @@ void ass_font_set_size(ass_font_t* font, int size)
}
}
+#ifdef HAVE_FONTCONFIG
+static void ass_font_reselect(void* fontconfig_priv, ass_font_t* font)
+{
+ char* path;
+ int index;
+ FT_Face face;
+ int error;
+
+ path = fontconfig_select_with_charset(fontconfig_priv, font->desc.family, font->desc.bold,
+ font->desc.italic, &index, font->charset);
+ if (strcasecmp(path, font->path) == 0 && index == font->index) {
+ free(path);
+ return;
+ }
+
+ error = FT_New_Face(font->ftlibrary, path, index, &face);
+ if (error) {
+ mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningFont, path, index);
+ return;
+ }
+ charmap_magic(face);
+
+ if (font->face) FT_Done_Face(font->face);
+ free(font->path);
+
+ font->face = face;
+ font->path = strdup(path);
+ font->index = index;
+
+ FT_Set_Transform(font->face, &font->m, &font->v);
+ FT_Set_Pixel_Sizes(font->face, 0, font->size);
+}
+#endif
+
FT_Glyph ass_font_get_glyph(void* fontconfig_priv, ass_font_t* font, uint32_t ch)
{
int error;
@@ -128,6 +166,20 @@ FT_Glyph ass_font_get_glyph(void* fontconfig_priv, ass_font_t* font, uint32_t ch
return 0;
index = FT_Get_Char_Index(font->face, ch);
+#ifdef HAVE_FONTCONFIG
+ FcCharSetAddChar(font->charset, ch);
+ if (index == 0) {
+ mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_GlyphNotFoundReselectingFont,
+ ch, font->desc.family, font->desc.bold, font->desc.italic);
+ ass_font_reselect(fontconfig_priv, font);
+ index = FT_Get_Char_Index(font->face, ch);
+ if (index == 0) {
+ mp_msg(MSGT_ASS, MSGL_ERR, MSGTR_LIBASS_GlyphNotFound,
+ ch, font->desc.family, font->desc.bold, font->desc.italic);
+ }
+ }
+#endif
+
error = FT_Load_Glyph(font->face, index, FT_LOAD_NO_BITMAP );
if (error) {
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorLoadingGlyph);
@@ -157,5 +209,8 @@ 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);
+#ifdef HAVE_FONTCONFIG
+ if (font->charset) FcCharSetDestroy(font->charset);
+#endif
free(font);
}
diff --git a/libass/ass_font.h b/libass/ass_font.h
index f1ae7a6e16..aac42e9a24 100644
--- a/libass/ass_font.h
+++ b/libass/ass_font.h
@@ -21,6 +21,10 @@
#ifndef __ASS_FONT_H__
#define __ASS_FONT_H__
+#ifdef HAVE_FONTCONFIG
+#include <fontconfig/fontconfig.h>
+#endif
+
typedef struct ass_font_desc_s {
char* family;
unsigned bold;
@@ -36,6 +40,9 @@ typedef struct ass_font_s {
FT_Matrix m; // current transformation
FT_Vector v; // current shift
int size;
+#ifdef HAVE_FONTCONFIG
+ FcCharSet* charset;
+#endif
} ass_font_t;
ass_font_t* ass_font_new(FT_Library ftlibrary, void* fc_priv, ass_font_desc_t* desc);
diff --git a/libass/ass_fontconfig.c b/libass/ass_fontconfig.c
index b4ac44e863..8cb6db205e 100644
--- a/libass/ass_fontconfig.c
+++ b/libass/ass_fontconfig.c
@@ -53,7 +53,8 @@ struct fc_instance_s {
* \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)
+static char* _select_font(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index,
+ FcCharSet* charset)
{
FcBool rc;
FcResult result;
@@ -61,6 +62,9 @@ static char* _select_font(fc_instance_t* priv, const char* family, unsigned bold
int val_i;
FcChar8* val_s;
FcBool val_b;
+ FcCharSet* val_cs;
+ FcFontSet* fset;
+ int curf, bestf, bestdiff = 0;
*index = 0;
@@ -78,16 +82,43 @@ static char* _select_font(fc_instance_t* priv, const char* family, unsigned bold
rc = FcConfigSubstitute(priv->config, pat, FcMatchPattern);
if (!rc)
return 0;
-
- rpat = FcFontMatch(priv->config, pat, &result);
- if (!rpat)
- return 0;
-
- result = FcPatternGetBool(rpat, FC_OUTLINE, 0, &val_b);
- if (result != FcResultMatch)
- return 0;
- if (val_b != FcTrue)
+
+ fset = FcFontSort(priv->config, pat, FcTrue, NULL, &result);
+
+ bestf = -1;
+ if (charset)
+ bestdiff = FcCharSetCount(charset) + 1;
+ for (curf = 0; curf < fset->nfont; ++curf) {
+ rpat = fset->fonts[curf];
+
+ result = FcPatternGetBool(rpat, FC_OUTLINE, 0, &val_b);
+ if (result != FcResultMatch)
+ continue;
+ if (val_b != FcTrue)
+ continue;
+
+ if (charset) {
+ int diff;
+ result = FcPatternGetCharSet(rpat, FC_CHARSET, 0, &val_cs);
+ if (result != FcResultMatch)
+ continue;
+ diff = FcCharSetSubtractCount(charset, val_cs);
+ if (diff < bestdiff) {
+ bestdiff = diff;
+ bestf = curf;
+ }
+ if (diff == 0)
+ break;
+ } else {
+ bestf = curf;
+ break;
+ }
+ }
+
+ if (bestf < 0)
return 0;
+
+ rpat = fset->fonts[bestf];
result = FcPatternGetInteger(rpat, FC_INDEX, 0, &val_i);
if (result != FcResultMatch)
@@ -118,13 +149,14 @@ static char* _select_font(fc_instance_t* priv, const char* family, unsigned bold
* \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* fontconfig_select_with_charset(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index,
+ FcCharSet* charset)
{
char* res = 0;
if (family && *family)
- res = _select_font(priv, family, bold, italic, index);
+ res = _select_font(priv, family, bold, italic, index, charset);
if (!res && priv->family_default) {
- res = _select_font(priv, priv->family_default, bold, italic, index);
+ res = _select_font(priv, priv->family_default, bold, italic, index, charset);
if (res)
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_UsingDefaultFontFamily,
family, bold, italic, res, *index);
@@ -136,7 +168,7 @@ char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold,
family, bold, italic, res, *index);
}
if (!res) {
- res = _select_font(priv, "Arial", bold, italic, index);
+ res = _select_font(priv, "Arial", bold, italic, index, charset);
if (res)
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_UsingArialFontFamily,
family, bold, italic, res, *index);
@@ -147,6 +179,11 @@ char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold,
return res;
}
+char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index)
+{
+ return fontconfig_select_with_charset(priv, family, bold, italic, index, 0);
+}
+
/**
* \brief Init fontconfig.
* \param dir additional directoryu for fonts
diff --git a/libass/ass_fontconfig.h b/libass/ass_fontconfig.h
index e2e71a9fd9..9aa1746908 100644
--- a/libass/ass_fontconfig.h
+++ b/libass/ass_fontconfig.h
@@ -21,11 +21,19 @@
#ifndef __ASS_FONTCONFIG_H__
#define __ASS_FONTCONFIG_H__
+#ifdef HAVE_FONTCONFIG
+#include <fontconfig/fontconfig.h>
+#endif
+
typedef struct fc_instance_s fc_instance_t;
fc_instance_t* fontconfig_init(const char* dir, 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);
+#ifdef HAVE_FONTCONFIG
+char* fontconfig_select_with_charset(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index, FcCharSet* charset);
+#endif
+
#endif