From 9f3ce9236f9818263437cb6a4f26b20c5506a218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 3 Mar 2023 17:21:11 +0100 Subject: [PATCH] =?UTF-8?q?config:=20apply=20fontconfig=20rules=20if=20use?= =?UTF-8?q?r=20didn=E2=80=99t=20set=20an=20explicit=20font=20size?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the user didn’t explicitly set the font size (e.g. font=monospace, instead of font=monospace:size=12), our initial attempt to read the FC_SIZE and FC_PIXEL_SIZE attributes will fail, and we used to fallback to setting the size to 8pt. Change this slightly, so that when we fail to read the FC_*_SIZE attributes, apply the fontconfig rules, but *without expanding* them (i.e. without calling FcDefaultSubstitute()). Then try reading FC_*_SIZE again. If that too fails, _then_ set size to 8pt. This allows us to pick up rules that set a default {pixel}size: 14 Closes #1287 --- CHANGELOG.md | 4 ++++ config.c | 40 ++++++++++++++++++++++++++++++++++------ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40072182..08d7d69f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -81,10 +81,14 @@ * DPI is now forced to 96 when found to be unreasonably high. * Set default log level to warning ([#1215][1215]). * Default `grapheme-width-method` from `wcswidth` to `double-width`. +* When determining initial font size, do FontConfig config + substitution if the user-provided font pattern has no {pixel}size + option ([#1287][1287]). [1166]: https://codeberg.org/dnkl/foot/issues/1166 [1179]: https://codeberg.org/dnkl/foot/issues/1179 [1215]: https://codeberg.org/dnkl/foot/pulls/1215 +[1287]: https://codeberg.org/dnkl/foot/issues/1287 ### Deprecated diff --git a/config.c b/config.c index d77b50b8..2ede1aa5 100644 --- a/config.c +++ b/config.c @@ -3390,20 +3390,48 @@ config_font_parse(const char *pattern, struct config_font *font) if (pat == NULL) return false; + /* + * First look for user specified {pixel}size option + * e.g. “font-name:size=12” + */ + double pt_size = -1.0; - FcPatternGetDouble(pat, FC_SIZE, 0, &pt_size); - FcPatternRemove(pat, FC_SIZE, 0); + FcResult have_pt_size = FcPatternGetDouble(pat, FC_SIZE, 0, &pt_size); int px_size = -1; - FcPatternGetInteger(pat, FC_PIXEL_SIZE, 0, &px_size); - FcPatternRemove(pat, FC_PIXEL_SIZE, 0); + FcResult have_px_size = FcPatternGetInteger(pat, FC_PIXEL_SIZE, 0, &px_size); - if (pt_size == -1. && px_size == -1) - pt_size = 8.0; + if (have_pt_size != FcResultMatch && have_px_size != FcResultMatch) { + /* + * Apply fontconfig config. Can’t do that until we’ve first + * checked for a user provided size, since we may end up with + * both “size” and “pixelsize” being set, and we don’t know + * which one takes priority. + */ + FcPattern *pat_copy = FcPatternDuplicate(pat); + if (pat_copy == NULL || + !FcConfigSubstitute(NULL, pat_copy, FcMatchPattern)) + { + LOG_WARN("%s: failed to do config substitution", pattern); + } else { + have_pt_size = FcPatternGetDouble(pat_copy, FC_SIZE, 0, &pt_size); + have_px_size = FcPatternGetInteger(pat_copy, FC_PIXEL_SIZE, 0, &px_size); + } + + FcPatternDestroy(pat_copy); + + if (have_pt_size != FcResultMatch && have_px_size != FcResultMatch) + pt_size = 8.0; + } + + FcPatternRemove(pat, FC_SIZE, 0); + FcPatternRemove(pat, FC_PIXEL_SIZE, 0); char *stripped_pattern = (char *)FcNameUnparse(pat); FcPatternDestroy(pat); + LOG_DBG("%s: pt-size=%.2f, px-size=%d", stripped_pattern, pt_size, px_size); + *font = (struct config_font){ .pattern = stripped_pattern, .pt_size = pt_size,