Fabian Greffrath
2012-Apr-27 12:25 UTC
[Fontconfig] Questionable usage of FcPatternAddInteger()
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; }
Akira TAGOH
2012-Apr-27 18:26 UTC
[Fontconfig] Questionable usage of FcPatternAddInteger()
On Fri, Apr 27, 2012 at 9:25 PM, Fabian Greffrath <fabian at greffrath.com> wrote:> 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)FcFontSort() doesn''t necessarily returns only FcPatterns matched the given pattern. it returns FcPatterns sorted by the score according to the result of matching the pattern. I guess what you are expecting to see may be more close to FcFontList() perhaps.> 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).Well, if you want to use FcFontSort() anyway, you shouldn''t trim at least as long as you want to filter the result out by the fontformat say because, the result is really depending on what fonts are installed on the system and the pattern though, if any fonts that has same coverage is added to the list prior to a font what you want to see, it won''t be added if you give a FcTrue to the trim. HTH -- Akira TAGOH
Fabian Greffrath
2012-Apr-27 19:29 UTC
[Fontconfig] Questionable usage of FcPatternAddInteger()
> FcFontSort() doesn''t necessarily returns only FcPatterns matched the > given pattern. it returns FcPatterns sorted by the score according to > the result of matching the pattern. I guess what you are expecting to > see may be more close to FcFontList() perhaps.Thanks for your reply, but this doesn''t really answer my question. Do you think that using FcPatternAddInteger() in the code I attached to my previous mail is a good idea or do you think it does confuse fontconfig more than it guides it towards preferring monospaced fonts? I more or less want to resemble the behaviour of "fc-match -s" with this code, thus the usage of FcFontSort(). - Fabian
Raimund Steger
2012-Apr-28 12:16 UTC
[Fontconfig] Questionable usage of FcPatternAddInteger()
Fabian Greffrath wrote:>> FcFontSort() doesn''t necessarily returns only FcPatterns matched the >> given pattern. it returns FcPatterns sorted by the score according to >> the result of matching the pattern. I guess what you are expecting to >> see may be more close to FcFontList() perhaps. > > Thanks for your reply, but this doesn''t really answer my question.Well, part of your question was why FcFontSort didn''t restrict the list, wasn''t it? Other than that: I tried the attached example with the argument ''FreeMono'', and as you suggested, it produces pretty identical results to ''fc-match --sort FreeMono:spacing=mono'', with FreeMono on top of the list because it''s the closest match. So I can find nothing wrong with the way you build the pattern. (If you leave out the call to FcPatternAddInteger, you might get a different order because a missing element produces a slightly different score in the match.) Whether fontconfig is able to substitute Liberation Mono for FreeMono on a system where the latter isn''t available is another story. (Meaning, treating it as a closer match than other fonts.) This benefits from appropriate rules in fontconfig''s configuration files, which typically operate on ''family'', not on ''spacing'' (the priority of ''family'' in the match is higher than that of ''spacing'' anyway). These work through the generic family name ''monospace''. I. e. adding ''Liberation Mono'' for the monospace family in 60-latin.conf improves its eligibility as a substitute for FreeMono. Although on a system where it isn''t clear what kind of monospace font is available it would be an option to use the generic family name directly. Raimund
Akira TAGOH
2012-Apr-28 13:07 UTC
[Fontconfig] Questionable usage of FcPatternAddInteger()
2012/04/28 4:29 "Fabian Greffrath" <fabian at greffrath.com>:> Thanks for your reply, but this doesn''t really answer my question. > > Do you think that using FcPatternAddInteger() in the code I attached to my > previous mail is a good idea or do you think it does confuse fontconfig > more than it guides it towards preferring monospaced fonts? I more or less > want to resemble the behaviour of "fc-match -s" with this code, thus the > usage of FcFontSort().The usage of FcPatternAddInteger() is good though I''m wondering why you didn''t set monospace to FC_FAMILY instead. that would gives you more easier way to do similar thing, but anyway. Since FC_SPACING also affects to the score estimation, looking good to you when getting rid of that line was just happened to work. As I mentioned in the previous mail, mistake to what you want to do may be you did give FcTrue to trim in FcFontSort (). you can try to compare the result of fc-match -s and -a. that may helps to understand what I told you in the previous mail.> > - Fabian > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/fontconfig/attachments/20120428/58992328/attachment.htm>
Raimund Steger
2012-Apr-28 16:06 UTC
[Fontconfig] Questionable usage of FcPatternAddInteger()
Akira TAGOH wrote:>[...] > Since FC_SPACING also affects to the score estimation, looking good to > you when getting rid of that line was just happened to work. As I > mentioned in the previous mail, mistake to what you want to do may be > you did give FcTrue to trim in FcFontSort (). you can try to compare theI believe Akira is right, I just checked in the source of cups-filters-1.0.16 that is mentioned in the original bug report and it seems that like in your example, trim is enabled in texttopdf.c:67, which is not a very good idea because -- depending on the fontconfig configuration -- the first font that satisfies the application''s requirement might appear further down the list. (I''m also not too positive about passing 0 as pointer to ''result''. Is that allowed for FcFontSort()?) Raimund
Akira TAGOH
2012-Apr-29 12:36 UTC
[Fontconfig] Questionable usage of FcPatternAddInteger()
2012/04/29 1:06 "Raimund Steger" <rs at mytum.de>:> (I''m also not too positive about passing 0 as pointer to ''result''. Isthat allowed for FcFontSort()?) No, it isn''t. you are right.> Raimund >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/fontconfig/attachments/20120429/ad34e546/attachment.htm>
Fabian Greffrath
2012-Apr-30 08:11 UTC
[Fontconfig] Questionable usage of FcPatternAddInteger()
Hi Raimund and Akira, Am 28.04.2012 18:06, schrieb Raimund Steger:> I believe Akira is right, I just checked in the source of > cups-filters-1.0.16 that is mentioned in the original bug report and > it seems that like in your example, trim is enabled in texttopdf.c:67, > which is not a very good idea because -- depending on the fontconfig > configuration -- the first font that satisfies the application''s > requirement might appear further down the list.thanks for your insightful replies. I believe I have understood the issue a bit better now. So as you both point out, the culprit is not necessarily FcPatternAddInteger() but the trimming of FcFontSort()''s results, which may cause dropping of some reasonable candidates.> (I''m also not too positive about passing 0 as pointer to ''result''. Is > that allowed for FcFontSort()?)Is it fine to pass NULL instead of 0 or does it have to be an actual pointer? - Fabian
Raimund Steger
2012-Apr-30 10:50 UTC
[Fontconfig] Questionable usage of FcPatternAddInteger()
Hi, On Mon, April 30, 2012 10:11, Fabian Greffrath wrote:> [...] > So as you both point out, the culprit is not necessarily > FcPatternAddInteger() but the trimming of FcFontSort()''s results, > which may cause dropping of some reasonable candidates.I think so.>> (I''m also not too positive about passing 0 as pointer to ''result''. Is >> that allowed for FcFontSort()?) > > Is it fine to pass NULL instead of 0 or does it have to be an actual > pointer?It will be assigned to, so it would have to be a non-null pointer, like: FcResult result; [...] candidates = FcFontSort (0, pattern, FcTrue, 0, &result); Raimund -- Worringer Str 31 Duesseldorf 40211 Germany +49-179-2981632 icq 16845346
Fabian Greffrath
2012-Apr-30 12:14 UTC
[Fontconfig] Questionable usage of FcPatternAddInteger()
Am 30.04.2012 12:50, schrieb Raimund Steger:> It will be assigned to, so it would have to be a non-null pointer, like: > > FcResult result; > [...] > candidates = FcFontSort (0, pattern, FcTrue, 0,&result);Alright, but I still don''t get it. This variable is unused, even in the fc-match code. What''s its purpose actually? - Fabian
Raimund Steger
2012-Apr-30 12:34 UTC
[Fontconfig] Questionable usage of FcPatternAddInteger()
On Mon, April 30, 2012 14:14, Fabian Greffrath wrote:> Am 30.04.2012 12:50, schrieb Raimund Steger: >> It will be assigned to, so it would have to be a non-null pointer, like: >> >> FcResult result; >> [...] >> candidates = FcFontSort (0, pattern, FcTrue, 0,&result); > > Alright, but I still don''t get it. This variable is unused, even in > the fc-match code. What''s its purpose actually?Its value will be set to indicate whether there was a match (FcResultMatch), no match (FcResultNoMatch), or error (FcResultTypeMismatch, maybe others as well). The first two of these options coincide with (candidates&&candidates->nfonts>0). See src/fcmatch.c. Raimund -- Worringer Str 31 Duesseldorf 40211 Germany +49-179-2981632 icq 16845346
Fabian Greffrath
2012-Apr-30 12:46 UTC
[Fontconfig] Questionable usage of FcPatternAddInteger()
Am 30.04.2012 14:34, schrieb Raimund Steger:> Its value will be set to indicate whether there was a match > (FcResultMatch), no match (FcResultNoMatch), or error > (FcResultTypeMismatch, maybe others as well). The first two of these > options coincide with (candidates&&candidates->nfonts>0). See > src/fcmatch.c.Alright, thanks! This is checked elsewhere in the code in question. Thank you very much for your help! - Fabian