changeset 23980:27bac14b4ce4

More simple and correct font reselection. Since ass_font_t contains a list of font faces, there is no need to select the face with maximum charset coverage each time. It is enough to select any face with the required glyph.
author eugeni
date Fri, 03 Aug 2007 13:43:11 +0000
parents 33928da6ba62
children 705628816d98
files libass/ass_font.c libass/ass_font.h libass/ass_fontconfig.c libass/ass_fontconfig.h
diffstat 4 files changed, 21 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/libass/ass_font.c	Fri Aug 03 10:57:49 2007 +0000
+++ b/libass/ass_font.c	Fri Aug 03 13:43:11 2007 +0000
@@ -104,7 +104,7 @@
 	if (fontp)
 		return fontp;
 	
-	path = fontconfig_select(fc_priv, desc->family, desc->bold, desc->italic, &index);
+	path = fontconfig_select(fc_priv, desc->family, desc->bold, desc->italic, &index, 0);
 	
 	mem_idx = find_font(library, path);
 	if (mem_idx >= 0) {
@@ -135,10 +135,6 @@
 	font.v.x = font.v.y = 0;
 	font.size = 0.;
 
-#ifdef HAVE_FONTCONFIG
-	font.charset = FcCharSetCreate();
-#endif
-
 	return ass_font_cache_add(&font);
 }
 
@@ -208,8 +204,8 @@
 	if (font->n_faces == ASS_FONT_MAX_FACES)
 		return;
 	
-	path = fontconfig_select_with_charset(fontconfig_priv, font->desc.family, font->desc.bold,
-					      font->desc.italic, &index, font->charset);
+	path = fontconfig_select(fontconfig_priv, font->desc.family, font->desc.bold,
+					      font->desc.italic, &index, ch);
 
 	error = FT_New_Face(font->ftlibrary, path, index, &face);
 	if (error) {
@@ -282,7 +278,6 @@
 	}
 
 #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);
@@ -359,8 +354,5 @@
 	for (i = 0; i < font->n_faces; ++i)
 		if (font->faces[i]) FT_Done_Face(font->faces[i]);
 	if (font->desc.family) free(font->desc.family);
-#ifdef HAVE_FONTCONFIG
-	if (font->charset) FcCharSetDestroy(font->charset);
-#endif
 	free(font);
 }
--- a/libass/ass_font.h	Fri Aug 03 10:57:49 2007 +0000
+++ b/libass/ass_font.h	Fri Aug 03 13:43:11 2007 +0000
@@ -21,10 +21,6 @@
 #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;
@@ -41,9 +37,6 @@
 	double scale_x, scale_y; // current transform
 	FT_Vector v; // current shift
 	double size;
-#ifdef HAVE_FONTCONFIG
-	FcCharSet* charset;
-#endif
 } ass_font_t;
 
 ass_font_t* ass_font_new(ass_library_t* library, FT_Library ftlibrary, void* fc_priv, ass_font_desc_t* desc);
--- a/libass/ass_fontconfig.c	Fri Aug 03 10:57:49 2007 +0000
+++ b/libass/ass_fontconfig.c	Fri Aug 03 13:43:11 2007 +0000
@@ -57,11 +57,11 @@
  * \param bold font weight value
  * \param italic font slant value
  * \param index out: font index inside a file
- * \param charset: contains the characters that should be present in the font, can be NULL
+ * \param code: the character that should be present in the font, can be 0
  * \return font file path
 */ 
 static char* _select_font(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index,
-			  FcCharSet* charset)
+			  uint32_t code)
 {
 	FcBool rc;
 	FcResult result;
@@ -71,7 +71,7 @@
 	FcBool val_b;
 	FcCharSet* val_cs;
 	FcFontSet* fset = 0;
-	int curf, bestf, bestdiff = 0;
+	int curf;
 	char* retval = 0;
 	
 	*index = 0;
@@ -93,9 +93,6 @@
 
 	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];
 		
@@ -104,29 +101,19 @@
 			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;
+		if (!code)
 			break;
-		}
+		result = FcPatternGetCharSet(rpat, FC_CHARSET, 0, &val_cs);
+		if (result != FcResultMatch)
+			continue;
+		if (FcCharSetHasChar(val_cs, code))
+			break;
 	}
 
-	if (bestf < 0)
+	if (curf >= fset->nfont)
 		goto error;
 
-	rpat = fset->fonts[bestf];
+	rpat = fset->fonts[curf];
 	
 	result = FcPatternGetInteger(rpat, FC_INDEX, 0, &val_i);
 	if (result != FcResultMatch)
@@ -159,17 +146,17 @@
  * \param bold font weight value
  * \param italic font slant value
  * \param index out: font index inside a file
- * \param charset: contains the characters that should be present in the font, can be NULL
+ * \param code: the character that should be present in the font, can be 0
  * \return font file path
 */ 
-char* fontconfig_select_with_charset(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index,
-			FcCharSet* charset)
+char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index,
+			uint32_t code)
 {
 	char* res = 0;
 	if (family && *family)
-		res = _select_font(priv, family, bold, italic, index, charset);
+		res = _select_font(priv, family, bold, italic, index, code);
 	if (!res && priv->family_default) {
-		res = _select_font(priv, priv->family_default, bold, italic, index, charset);
+		res = _select_font(priv, priv->family_default, bold, italic, index, code);
 		if (res)
 			mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_UsingDefaultFontFamily, 
 					family, bold, italic, res, *index);
@@ -181,7 +168,7 @@
 		       family, bold, italic, res, *index);
 	}
 	if (!res) {
-		res = _select_font(priv, "Arial", bold, italic, index, charset);
+		res = _select_font(priv, "Arial", bold, italic, index, code);
 		if (res)
 			mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_UsingArialFontFamily, 
 					family, bold, italic, res, *index);
@@ -192,11 +179,6 @@
 	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);
-}
-
 #if (FC_VERSION < 20402)
 static char* validate_fname(char* name)
 {
--- a/libass/ass_fontconfig.h	Fri Aug 03 10:57:49 2007 +0000
+++ b/libass/ass_fontconfig.h	Fri Aug 03 13:43:11 2007 +0000
@@ -28,12 +28,8 @@
 typedef struct fc_instance_s fc_instance_t;
 
 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);
+char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index, uint32_t code);
 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