PangoFT2 font maps don't honor aliases defined in custom FcConfigs
Please have a look at the following test program:
#include <stdio.h>
#include <assert.h>
#include <fontconfig/fontconfig.h>
#include <pango/pangoft2.h>
int main() {
FcConfig *conf = FcConfigCreate();
FcChar8 *default_conf_file = FcConfigGetFilename(NULL, NULL);
assert(default_conf_file);
printf("Reading default conf file: %s\n", default_conf_file);
assert(FcConfigParseAndLoad(conf, default_conf_file, FcTrue));
printf("Reading custom config that defines a \"Custom Family\" alias for the C059 font\n");
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"
" </alias>\n"
"</fontconfig>\n";
assert(FcConfigParseAndLoadFromMemory(conf, my_conf, FcTrue));
FcConfigBuildFonts(conf);
printf("Finding \"Custom Family\" font via Fontconfig...\n");
FcPattern *pat = FcPatternCreate();
FcPatternAddString(pat, FC_FAMILY, (FcChar8 *) "Custom Family");
FcConfigSubstitute(conf, pat, FcMatchPattern);
FcDefaultSubstitute(pat);
FcResult result;
FcPattern *found_pat = FcFontMatch(conf, pat, &result);
assert(result == FcResultMatch);
FcChar8 *fc_family;
FcResult fam_result = FcPatternGetString(found_pat, FC_FAMILY, 0, &fc_family);
assert(fam_result == FcResultMatch);
printf("Found: %s\n", fc_family);
printf("Finding \"Custom Family\" font via PangoFT2...\n");
PangoFontMap *map = pango_ft2_font_map_new();
pango_fc_font_map_set_config(PANGO_FC_FONT_MAP(map), conf);
PangoContext *ctx = pango_font_map_create_context(map);
PangoFontDescription *desc = pango_font_description_new();
pango_font_description_set_family(desc, "Custom Family");
PangoFont *found_font = pango_font_map_load_font(map, ctx, desc);
PangoFontDescription *found_desc = pango_font_describe(found_font);
char *desc_str = pango_font_description_to_string(found_desc);
printf("Found: %s\n", desc_str);
return 0;
}
Here is the output on my system:
~/tmp $ gcc $(pkg-config --cflags pangoft2) $(pkg-config --libs pangoft2) -o pango-bug pango-bug.c && ./pango-bug
Reading default conf file: /etc/fonts/fonts.conf
Reading custom config that defines a "Custom Family" alias for the C059 font
Finding "Custom Family" font via Fontconfig...
Found: C059
Finding "Custom Family" font via PangoFT2...
Found: Noto Sans 0
~/tmp $ pkg-config --modversion pangoft2
1.50.14
~/tmp $ pkg-config --modversion fontconfig
2.14.1
In this program, I am using a custom FcConfig object which loads a bit of Fontconfig XML defining a font alias "Custom Family" that is the same as C059 (a font found on my system by fc-list
).
- When I use the Fontconfig API directly to look up "Custom Family", I get C059.
- When I use a Pango FT2 font map, I get "Noto Sans", the default font on my system.
I'm pretty sure this happens because of the call to FcConfigSubstitute
in pangoft2-fontmap.c
:
$ rg "FcConfigSubstitute"
pango/pangocairo-fcfontmap.c
106: FcConfigSubstitute (pango_fc_font_map_get_config (fcfontmap), pattern, FcMatchPattern);
pango/pangoxft-fontmap.c
393: FcConfigSubstitute (NULL, pattern, FcMatchPattern);
pango/pangoft2-fontmap.c
353: FcConfigSubstitute (NULL, pattern, FcMatchPattern);
Shouldn't the third one, and possibly the second, be using the font map's FcConfig rather than NULL
, which means to use the global FcConfig?
CC @behdad as the author of http://mces.blogspot.com/2015/05/how-to-use-custom-application-fonts.html who also added pango_fc_font_map_set_config
.
Thanks!