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

Urs Liska ul at openlilylib.org
Wed Apr 29 04:27:37 PDT 2015


Dear list users,

this is my first post to this list, and also I'm completely new to using 
fontconfig from a programming language. But I have tried to get my head 
around the function references, and in the project I'm working at there 
are other people who are experienced with font issues and who couldn't 
help me either. So I dare to ask here directly.
I apologize in advance for the (not unlikely) case that I'm simply not 
seeing the obvious.

I am working on a patch for GNU LilyPond (http://lilypond.org) that will 
make the use of (music and text) fonts significantly easier and more 
powerful. However, to achieve what I want I need to reliably determine 
if a font (that is given by its font name) is visible to fontconfig on 
the user's system. And all of my approaches so far have limitations that 
are inacceptable (and seem unnecessary). I'll concentrate on one 
approach that seems the most promising in my eyes.

LilyPond provides a function (ly:font-config-get-font-file <name>) in 
its C++ part which returns the full path and file name to the font, and 
the path to a substitution font if the requested font is not found.
However, the substitution font is different on the users' systems, so my 
initial approach (checking if the returned font is the one *I* was 
getting as substitution) wasn't successful. However, I can see a way to 
handle that  by modifying the function's implementation.

The existing function is defined as follows:
http://git.savannah.gnu.org/cgit/lilypond.git/tree/lily/font-config-scheme.cc, 
line 101ff.

|LY_DEFINE (ly_font_config_get_font_file, "ly:font-config-get-font-file", 1, 0, 0,
            (SCM name),
            "Get the file for font @var{name}.")
{
   LY_ASSERT_TYPE (scm_is_string, name, 1);

   FcPattern *pat = FcPatternCreate ();
   FcValue val;

   val.type = FcTypeString;
   val.u.s = (const FcChar8 *)ly_scm2string (name).c_str (); // FC_SLANT_ITALIC;
   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_FILE, 0, &str) == FcResultMatch)
     scm_result = scm_from_utf8_string ((char const *)str);

   FcPatternDestroy (pat);

   return scm_result;
}

|


I hope the LilyPond/Guile specific stuff doesn't step in the way of 
looking at the code.
Despite looking at the documentation of the different Fc... functions 
and some example code, e.g. on StackOverflow I don't really see how to 
properly modify that function. My goal would be to set it so *no* 
replacement font is returned when the requested font isn't found. 
Basically str should only hold the path and the `if` expression should 
only evaluate to true when the font is found.
The function as a whole would then either return the string or 'false' 
(which is no problem with the Guile/Scheme wrappers).

Can you advise me how to achieve that? AFAICS it should be a simple 
matter of setting the configuration properly. Or is the return of a 
default font built-in at a deeper level? (I mean running fc-match in the 
terminal also returns a default for non-present fonts.)
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.

Thanks in advance
Urs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/fontconfig/attachments/20150429/2e48b300/attachment.html>


More information about the Fontconfig mailing list