From ab7090e055b7c2043f9fdb07b760ae8b304fe02c Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Sun, 20 Nov 2022 13:50:47 +0000 Subject: [PATCH] Also try 'normal' weight when searching a font with 'medium' weight. Between commits bf0d3f76dc (2014) and 6b1ed2f2c9 (2022), realize_gui_face called font_load_for_lface with an empty or partly emptied font spec, i.e. it ignored a part of its attrs argument. The rationale given in bug#17973, which led to bf0d3f76dc, is not clear. In the meantime, commit 65fd3ca84f added support for the 'medium' font weight, which was previously synonymous to 'normal'. Together, the two commits 6b1ed2f2c9 and 65fd3ca84f lead to suboptimal font choices. When the font chosen for the default face has its weight set to 'medium' and actually supports that weight, font_load_for_lface will be called with a weight attribute set to 'medium' in spec for other faces. However, fonts with an explicit 'medium' weight are much less common than fonts with an explicit 'normal' weight, which means that fonts that only support a 'normal' weight are rejected, although they are close to the desired font. Therefore, font_find_for_lface should also try the 'normal' weight when the weight in spec is 'medium', after trying the 'medium' weight. * src/font.c (font_find_for_lface): When the weight in SPEC is 'medium', also try the 'normal' weight. --- src/font.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/font.c b/src/font.c index 6e720bc285..4222d60231 100644 --- a/src/font.c +++ b/src/font.c @@ -2959,9 +2959,9 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int { Lisp_Object work; Lisp_Object entities, val; - Lisp_Object foundry[3], *family, registry[3], adstyle[3]; + Lisp_Object foundry[3], *family, registry[3], adstyle[3], weight[3]; int pixel_size; - int i, j, k, l; + int i, j, k, l, m; USE_SAFE_ALLOCA; /* Registry specification alternatives: from the most specific to @@ -3081,6 +3081,17 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int } } + /* If weight is "medium" in SPEC, also try "normal". Fonts with an + explicit "medium" weight are much less common than fonts with an + explicit "normal" weight, and for a long time "medium" and + "normal" (a.k.a. "regular" a.k.a. "book") were synonymous in + Emacs. See e.g. bug#59347 and bug#57555. */ + weight[0] = AREF (spec, FONT_WEIGHT_INDEX); + if (EQ (weight[0], Qmedium)) + weight[1] = Qnormal, weight[2] = zero_vector; + else + weight[1] = zero_vector; + /* Now look up suitable fonts, from the most specific spec to the least specific spec. Accept the first one that matches. */ for (i = 0; SYMBOLP (family[i]); i++) @@ -3095,18 +3106,22 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int for (l = 0; SYMBOLP (adstyle[l]); l++) { ASET (work, FONT_ADSTYLE_INDEX, adstyle[l]); - /* Produce the list of candidates for the spec in WORK. */ - entities = font_list_entities (f, work); - if (! NILP (entities)) + for (m = 0; SYMBOLP (weight[m]); m++) { - /* If there are several candidates, select the - best match for PIXEL_SIZE and attributes in ATTRS. */ - val = font_select_entity (f, entities, - attrs, pixel_size, c); - if (! NILP (val)) + ASET (work, FONT_WEIGHT_INDEX, weight[m]); + /* Produce the list of candidates for the spec in WORK. */ + entities = font_list_entities (f, work); + if (! NILP (entities)) { - SAFE_FREE (); - return val; + /* If there are several candidates, select the + best match for PIXEL_SIZE and attributes in ATTRS. */ + val = font_select_entity (f, entities, + attrs, pixel_size, c); + if (! NILP (val)) + { + SAFE_FREE (); + return val; + } } } } -- 2.35.1