[Fontconfig] Determining the presence of a font / font fallback

Urs Liska ul at openlilylib.org
Wed Apr 29 06:03:44 PDT 2015

Hi Raimund

Am 29.04.2015 um 14:38 schrieb Raimund Steger:
> On Wed, April 29, 2015 13:27, Urs Liska wrote:
>> [...]
>> In that case I'd try another approach that *seemed* promising but also
>> had some issues: returning the family name and comparing that to the
>> originally given family name.
> If I may ask, what issues were they? Because even if fontconfig supported
> a comparison mode where family name had to be strictly equal (and nothing
> else was checked), that's what it would more or less amount to.
> Otherwise, see prior discussion ... also about lilypond:
> http://thread.gmane.org/gmane.comp.fonts.fontconfig/4251

Oops! It was Werner who directed me to the fontconfig list, obviously 
not recalling having started this thread ;-)

One of the two issues referenced in that thread (the missing ligatures 
on Windows) have (coincidentally) just been fixed several weeks ago, but 
the other thread with the patch at 
http://code.google.com/p/lilypond/issues/detail?id=2761 seems to be 
quite related. But that patch tries to intercept later, at the Pango 
stage. What I would like to have is something earlier, in the fontconfig 

Now to the issue:
I made a modified copy of the function quoted in my initial post:

LY_DEFINE (ly_font_config_font_exists, "ly:font-config-font-exists", 1, 
0, 0,
            (SCM name),
            "Determine if font @var{name} exists.")
   LY_ASSERT_TYPE (scm_is_string, name, 1);

   string in_name = ly_scm2string (name).c_str ();

   FcPattern *pat = FcPatternCreate ();
   FcValue val;

   val.type = FcTypeString;
   val.u.s = (const FcChar8 *)ly_scm2string (name).c_str (); // 
   FcPatternAdd (pat, FC_FAMILY, val, FcFalse);

   FcResult result;
   SCM scm_result = SCM_BOOL_F;

   FcConfigSubstitute (NULL, pat, FcMatchFont);
   FcDefaultSubstitute (pat);

   pat = FcFontMatch (NULL, pat, &result);
   FcChar8 *str = 0;
   if ((FcPatternGetString (pat, FC_FAMILY, 0, &str) == FcResultMatch) &&
       (in_name.compare((char const *)str) == 0))
       scm_result = SCM_BOOL_T;

   FcPatternDestroy (pat);
   return scm_result;

This is very similar except that (mainly) the second argument to 
FcPatternGetString is FC_FAMILY instead of FC_FILE. That way I can 
compare the incoming string (which is assumed the family name of the 
font) with the resulting family name.

So this function returns true if the family name in the matched font 
file is the same as the family name used for starting the match.
This works most of the time (apart from the fact that it's now case 
sensitive, but we'd look into that separately). But there are reports of 
*some* fonts where the returned family is different from the actual one.
reports that the file name returned for fonts Umpush and Kedage are 
wrong. I verified this in my own installation: The family name returned 
by the above function for Umpush is "Tlwg Typo", although FontViewer and 
FontForge both confirm that the family name is "Umpush".
However, fc-match Umpush gives the right result: 'Umpush.ttf: "Umpush" 

So I don't know if that is an issue with fontconfig, some peculiarity of 
the font(s) or an issue with the match configuration in the above function.

If I could get a reliable information about this question (together with 
a solution to do a case-insensitive comparison of the input with the 
result) I could settle with this new function.
Or otherwise I'd like to know about a way to have fontconfig return some 
"failure condition" instead of a replacement if a font isn't matched.


> -Raimund

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/fontconfig/attachments/20150429/8d7acba5/attachment.html>

More information about the Fontconfig mailing list