[Fontconfig] Questionable usage of FcPatternAddInteger()
Fabian Greffrath
fabian at greffrath.com
Fri Apr 27 05:25:15 PDT 2012
Dear fontconfig-devs,
I have a question about the proper use of FcPatternAddInteger() and
friends to add specific information to a fontconfig pattern. Please
have a look at the attached code, which is based on an excerpt from
cups-filter's texttopdf filter.
It is supposed to read a fontconfig pattern from the command line,
find the most appropriate candidates to match that pattern (just like
"fc-match -s") and print them to stdout prefixed with "C:" for
"candidate". The first candidate that is both monospaced and in a font
format that allows for embedding in a PDF file (i.e. either TTF or
CFF) is printed to stdout prefixed with "S" for "selection".
Now, the line in question is line 17, which calls
FcPatternAddInteger() to "guide" fontconfig and add the information
that we are looking for monospaced fonts to "pattern". However, this
line does not seem to do what is expected. First, there are still a
lot of fonts returned by FcFontSort() that are non-monospaced (remove
the "break;" commands to see them all) and second, the list of fonts
returned by FcFontSort() is slightly puzzled depending on the
FcPatternAddInteger() call being commented out or not.
This has lead to a bug reported in Debian [1] that occured when
Liberation-Mono was the only installed monospaced Truetype font and
the queried pattern was "FreeMono". I believe that removing the
FcPatternAddInteger() call fixes this issue (it did on my system, but
the OP hasn't answered yet).
But then I am not sure what else this command is supposed to do. It
does not restrict the list of candidates returned by FcFontSort() to
monospaced fonts, even if this requirement should get added to the
pattern by means of FcPatternAddInteger(). Furthermore, it shuffles
the list of candidates returned by FcFontSort() in a way that the most
obvious installed monospaced Truetype fint is not part of that list.
so what is the purpose of FcPatternAddInteger() again?
Best Regards,
Fabian Greffrath
[1] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=670055
--
#include <stdio.h>
#include <fontconfig/fontconfig.h>
int main (int argc, char *argv[])
{
char *font = argv[1];
FcPattern *pattern;
FcFontSet *candidates;
FcChar8 *fontname = NULL;
int i;
if (!font)
return 1;
FcInit ();
pattern = FcNameParse ((const FcChar8 *)font);
FcPatternAddInteger (pattern, FC_SPACING, FC_MONO);
FcConfigSubstitute (0, pattern, FcMatchPattern);
FcDefaultSubstitute (pattern);
candidates = FcFontSort (0, pattern, FcTrue, 0, 0);
FcPatternDestroy (pattern);
for (i = 0; i < candidates->nfont; i++) {
FcChar8 *fontformat=NULL;
int spacing=0;
FcPatternGetString (candidates->fonts[i], FC_FONTFORMAT, 0,
&fontformat);
FcPatternGetInteger (candidates->fonts[i], FC_SPACING, 0, &spacing);
printf ("C: %s\n", FcPatternFormat (candidates->fonts[i], (const
FcChar8 *)"%{file|cescape}"));
if ( (fontformat)&&(spacing == FC_MONO) ) {
if (strcmp((const char *)fontformat, "TrueType") == 0) {
fontname = FcPatternFormat (candidates->fonts[i], (const FcChar8
*)"%{file|cescape}/%{index}");
break;
} else if (strcmp((const char *)fontformat, "CFF") == 0) {
fontname = FcPatternFormat (candidates->fonts[i], (const FcChar8
*)"%{file|cescape}");
break;
}
}
}
FcFontSetDestroy (candidates);
if (fontname)
printf("S: %s\n", fontname);
return 0;
}
More information about the Fontconfig
mailing list