Questionable usage of FcPatternAddInteger()

View: New views
12 Messages — Rating Filter:   Alert me  

Questionable usage of FcPatternAddInteger()

by Fabian Greffrath-9 :: Rate this Message:

| View Threaded | Show Only this Message

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;
}

_______________________________________________
Fontconfig mailing list
Fontconfig@...
http://lists.freedesktop.org/mailman/listinfo/fontconfig

Re: Questionable usage of FcPatternAddInteger()

by Akira TAGOH-5 :: Rate this Message:

| View Threaded | Show Only this Message

On Fri, Apr 27, 2012 at 9:25 PM, Fabian Greffrath <fabian@...> 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
_______________________________________________
Fontconfig mailing list
Fontconfig@...
http://lists.freedesktop.org/mailman/listinfo/fontconfig

Re: Questionable usage of FcPatternAddInteger()

by Fabian Greffrath-9 :: Rate this Message:

| View Threaded | Show Only this Message

> 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


_______________________________________________
Fontconfig mailing list
Fontconfig@...
http://lists.freedesktop.org/mailman/listinfo/fontconfig

Re: Questionable usage of FcPatternAddInteger()

by Raimund Steger :: Rate this Message:

| View Threaded | Show Only this Message

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
_______________________________________________
Fontconfig mailing list
Fontconfig@...
http://lists.freedesktop.org/mailman/listinfo/fontconfig

Re: Questionable usage of FcPatternAddInteger()

by Akira TAGOH-5 :: Rate this Message:

| View Threaded | Show Only this Message


2012/04/28 4:29 "Fabian Greffrath" <fabian@...>:
> 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
>
>


_______________________________________________
Fontconfig mailing list
Fontconfig@...
http://lists.freedesktop.org/mailman/listinfo/fontconfig

Re: Questionable usage of FcPatternAddInteger()

by Raimund Steger :: Rate this Message:

| View Threaded | Show Only this Message

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 the

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.

(I'm also not too positive about passing 0 as pointer to 'result'. Is
that allowed for FcFontSort()?)

Raimund

_______________________________________________
Fontconfig mailing list
Fontconfig@...
http://lists.freedesktop.org/mailman/listinfo/fontconfig

Re: Questionable usage of FcPatternAddInteger()

by Akira TAGOH-5 :: Rate this Message:

| View Threaded | Show Only this Message


2012/04/29 1:06 "Raimund Steger" <rs@...>:
> (I'm also not too positive about passing 0 as pointer to 'result'. Is that allowed for FcFontSort()?)

No, it isn't. you are right.

> Raimund
>


_______________________________________________
Fontconfig mailing list
Fontconfig@...
http://lists.freedesktop.org/mailman/listinfo/fontconfig

Re: Questionable usage of FcPatternAddInteger()

by Fabian Greffrath-9 :: Rate this Message:

| View Threaded | Show Only this Message

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

_______________________________________________
Fontconfig mailing list
Fontconfig@...
http://lists.freedesktop.org/mailman/listinfo/fontconfig

Re: Questionable usage of FcPatternAddInteger()

by Raimund Steger :: Rate this Message:

| View Threaded | Show Only this Message

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

_______________________________________________
Fontconfig mailing list
Fontconfig@...
http://lists.freedesktop.org/mailman/listinfo/fontconfig

Re: Questionable usage of FcPatternAddInteger()

by Fabian Greffrath-9 :: Rate this Message:

| View Threaded | Show Only this Message

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

_______________________________________________
Fontconfig mailing list
Fontconfig@...
http://lists.freedesktop.org/mailman/listinfo/fontconfig

Re: Questionable usage of FcPatternAddInteger()

by Raimund Steger :: Rate this Message:

| View Threaded | Show Only this Message


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

_______________________________________________
Fontconfig mailing list
Fontconfig@...
http://lists.freedesktop.org/mailman/listinfo/fontconfig

Re: Questionable usage of FcPatternAddInteger()

by Fabian Greffrath-9 :: Rate this Message:

| View Threaded | Show Only this Message

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

_______________________________________________
Fontconfig mailing list
Fontconfig@...
http://lists.freedesktop.org/mailman/listinfo/fontconfig