Hi, On Thu, Apr 13, 2023 at 8:15 PM Jean Abou Samra <jean@xxxxxxxxxxxxx> wrote: > 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? Well, that is entirely meaningless. that'd rather cause a memory leak. If you expect to reuse this FcConfig in another place, you should call FcConfigSetCurrent() with that result. > 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? FcConfigBuildFonts() doesn't affect applications fonts which can be added by FcConfigAppFontAddDir(). > 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? No. if there are any issues with it, that should be a bug in fontconfig. > 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? Well, there are some wrong codes attached. 1. FcConfigFilename() assumes FcConfig is set by FcConfigSetCurrent(). if no FcConfig instance is initialized, they do. As you can see with FC_DEBUG, fontconfig was initialized before showing "Default conf file..". You may want to use FcConfigGetFilename() instead. a trivial thing though. 2. What you should set to FcConfigSubstitute() is FcMatchPattern. FcMatchFont is basically done in FcFontRenderPrepare() which is also called in FcFontMatch() at the end. 3. FcConfigParseAndLoad() doesn't add font directories into FcConfig. you need to call FcConfigBuildFonts() after reading config. > > Thanks! > > Jean Hope that helps, -- Akira TAGOH