<p>Hi,</p>
<p>I'm trying to improve LilyPond's font selection (see <a href="https://gitlab.com/lilypond/lilypond/-/merge_requests/1938#note_1350759526">here</a>), and feeling a bit lost. LilyPond uses Fontconfig + Pango to find fonts. It has custom Fontconfig config files and adds app font directories.</p>
<p>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.</p>
<ol>
<li>
<p>At the beginning of its processing, LilyPond calls <code>FcInitLoadConfig();</code> and discards the result. I think this might be an artifact of history. Does this do anything relevant if the result is discarded?</p>
</li>
<li>
<p>At the end, after having constructed its desired configuration called <code>font_config_global</code>, LilyPond calls <code>FcConfigBuildFonts(font_config_global);</code>. I see in the documentation of <code>FcConfigBuildFonts</code> 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 <code>FcConfigAppFontAddDir</code>) is. Is <code>FcConfigBuildFonts</code> implicitly called when you do <code>FcFontMatch</code> or similar? Does Pango call it internally the first time a font is requested? Does this call interact with caching somehow?</p>
</li>
<li>
<p>As you can see in the LilyPond merge request, removing a call <code>FcConfigSetCurrent(font_config_global);</code> 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?</p>
</li>
<li>
<p>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.</p>
</li>
</ol>
<p>I have used this command to compile and test it:</p>
<pre><code>gcc $(pkg-config --cflags fontconfig) $(pkg-config --libs fontconfig) -o fcpb fcpb.c && ./fcpb
</code></pre>
<p><code>pkg-config --modversion fontconfig</code> outputs 2.14.1.</p>
<p>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.</p>
<p>The result of the program as-is is:</p>
<pre><code>Default conf file: /etc/fonts/fonts.conf
Match result is: 1
Get result is: 1
Font file: (null)
</code></pre>
<p>4.1. Why is there no match? I would have expected it to find the C059 font (which is found by <code>fc-list</code> on my system).</p>
<p>4.2. If I uncomment the call <code>FcConfigSetCurrent(conf);</code>, the result is different:</p>
<pre><code>Default conf file: /etc/fonts/fonts.conf
Match result is: 0
Get result is: 0
Font file: /usr/share/fonts/gnu-free/FreeSans.ttf
</code></pre>
<p>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?</p>
<p>Thanks!</p>
<p>Jean</p>