Trouble with custom configs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I'm trying to improve LilyPond's font selection (see here), and feeling a bit lost. LilyPond uses Fontconfig + Pango to find fonts. It has custom Fontconfig config files and adds app font directories.

I think we are probably misusing the Fontconfig API in a number of ways, but I'm not sure what the correct way is. I have a lot of questions, sorry.

  1. At the beginning of its processing, LilyPond calls FcInitLoadConfig(); and discards the result. I think this might be an artifact of history. Does this do anything relevant if the result is discarded?

  2. At the end, after having constructed its desired configuration called font_config_global, LilyPond calls FcConfigBuildFonts(font_config_global);. I see in the documentation of FcConfigBuildFonts that changes to the configuration have undefined effect, and in fact there are functions in LilyPond to add custom fonts, which do exactly this. So far they work, but given the documentation, this isn't guaranteed. So I'm trying to understand what the last moment we can do these modifications (essentially FcConfigAppFontAddDir) is. Is FcConfigBuildFonts implicitly called when you do FcFontMatch or similar? Does Pango call it internally the first time a font is requested? Does this call interact with caching somehow?

  3. As you can see in the LilyPond merge request, removing a call FcConfigSetCurrent(font_config_global); and passing the config explicitly everywhere made aliases from our custom config files not recognized anymore. I triple checked and I don't think we're still using NULL somewhere as config, the custom config should always be properly used. Does this ring a bell?

  4. Attached is a test C program where I tried to reduce LilyPond's case to a minimal example. Unfortunately, it doesn't exhibit the behavior we're seeing in LilyPond, but I still don't understand it.

I have used this command to compile and test it:

gcc $(pkg-config --cflags fontconfig) $(pkg-config --libs fontconfig) -o fcpb fcpb.c && ./fcpb

pkg-config --modversion fontconfig outputs 2.14.1.

The program creates a config, parses the default config file plus a custom XML string defining an alias into this config, then makes a request for the alias.

The result of the program as-is is:

Default conf file: /etc/fonts/fonts.conf
Match result is: 1
Get result is: 1
Font file: (null)

4.1. Why is there no match? I would have expected it to find the C059 font (which is found by fc-list on my system).

4.2. If I uncomment the call FcConfigSetCurrent(conf);, the result is different:

Default conf file: /etc/fonts/fonts.conf
Match result is: 0
Get result is: 0
Font file: /usr/share/fonts/gnu-free/FreeSans.ttf

Still not the expected result, but a fallback is chosen. Why does this make a difference, given that I'm not using the global config?

Thanks!

Jean

#include <stdlib.h>
#include <assert.h>
#include <stdio.h>

#include <fontconfig/fontconfig.h>

int main() {
  FcConfig *conf = FcConfigCreate();
  FcChar8 *default_conf_file = FcConfigFilename(NULL);
  assert(default_conf_file);
  printf("Default conf file: %s\n", default_conf_file);
  assert(FcConfigParseAndLoad(conf, default_conf_file, FcTrue));
  FcChar8 *my_conf = (FcChar8 *)
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    "<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">\n"
    "<fontconfig>\n"
    "  <alias binding=\"strong\">\n"
    "    <family>Custom Family</family>\n"
    "      <prefer>\n"
    "        <family>C059</family>\n"
    "      </prefer>\n"
    "    <default>\n"
    "      <family>serif</family>\n"
    "    </default>\n"
    "  </alias>\n"
    "</fontconfig>\n";
  assert(FcConfigParseAndLoadFromMemory(conf, my_conf, FcTrue));

  //FcConfigSetCurrent(conf);

  FcPattern *pat = FcPatternCreate();
  FcPatternAddString(pat, FC_FAMILY, (FcChar8 *) "Custom Family");
  FcConfigSubstitute(conf, pat, FcMatchFont);
  FcDefaultSubstitute(pat);
  FcResult result;
  FcPattern *found_pat = FcFontMatch(conf, pat, &result);
  printf("Match result is: %d\n", result);
  FcChar8 *filename;
  FcResult get_result = FcPatternGetString(found_pat, FC_FILE, 0, &filename);
  printf("Get result is: %d\n", get_result);
  printf("Font file: %s\n", (char *) filename);
  return 0;
}

Attachment: signature.asc
Description: This is a digitally signed message part


[Index of Archives]     [Fedora Fonts]     [Fedora Users]     [Fedora Cloud]     [Kernel]     [Fedora Packaging]     [Fedora Desktop]     [PAM]     [Gimp Graphics Editor]     [Yosemite News]

  Powered by Linux