Subject: Re: bug#52493: 29.0.50; Setting Inconsolata up in init.el makes default face rendered wrong

From: Gregory Heytings <[email-masked]>
Date: Wed, 28 Dec 2022 15:20:59 +0000

>> I did not design that function, that's how it works.  But given how 
>> intricate the face machinery is, I'm not sure it's possible to do much 
>> better.
>
> It does feel a little odd, though. Could you explain why :family does 
> get evaluated first, but :font does not?
>

I can't explain that, no.  If you look at bug#1127, you'll see that moving 
the evaluation of :family and :foundry before other attributes was (in 
2008) perceived as a workaround.  Apparently that worked well enough, and 
it's still there in its original form.

IMO it would make sense to move the evaluation of the :font attribute 
before other attributes, for the same reason.

Eli, what do you think of the attached patch?

>
> And yet, it's better recommended to use :font?
>

Again, that's why I'd recommend, but it's not the officially recommended 
way of doing things (if such a thing exists).
From a74dea03d4bd42677e1cc03feaf625c33ca6bfe4 Mon Sep 17 00:00:00 2001
From: Gregory Heytings <[email-masked]>
Date: Wed, 28 Dec 2022 15:16:50 +0000
Subject: [PATCH] Evaluate :font attribute earlier in set-face-attribute

* lisp/faces.el (set-face-attribute): Evaluate the :font attribute
before other attributes when it is specified.
---
 lisp/faces.el | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/lisp/faces.el b/lisp/faces.el
index 29e26e4c651..7320d1f0e03 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -844,20 +844,22 @@ set-face-attribute
   (setq args (purecopy args))
   (let ((where (if (null frame) 0 frame))
 	(spec args)
-	family foundry orig-family orig-foundry)
+	family foundry orig-family orig-foundry font)
     ;; If we set the new-frame defaults, this face is modified outside Custom.
     (if (memq where '(0 t))
 	(put (or (get face 'face-alias) face) 'face-modified t))
-    ;; If family and/or foundry are specified, set it first.  Certain
+    ;; If family, foundry and/or font are specified, set it first.  Certain
     ;; face attributes, e.g. :weight semi-condensed, are not supported
     ;; in every font.  See bug#1127.
     (while spec
       (cond ((eq (car spec) :family)
 	     (setq family (cadr spec)))
 	    ((eq (car spec) :foundry)
-	     (setq foundry (cadr spec))))
+	     (setq foundry (cadr spec)))
+            ((eq (car spec) :font)
+             (setq font (cadr spec))))
       (setq spec (cddr spec)))
-    (when (or family foundry)
+    (when (or family foundry font)
       (when (and (stringp family)
 		 (string-match "\\([^-]*\\)-\\([^-]*\\)" family))
         (setq orig-foundry foundry
@@ -875,9 +877,12 @@ set-face-attribute
 					  where))
       (when (or (stringp foundry) (eq foundry 'unspecified))
 	(internal-set-lisp-face-attribute face :foundry (purecopy foundry)
+					  where))
+      (when (or (stringp font) (eq font 'unspecified))
+	(internal-set-lisp-face-attribute face :font (purecopy font)
 					  where)))
     (while args
-      (unless (memq (car args) '(:family :foundry))
+      (unless (memq (car args) '(:family :foundry :font))
 	(internal-set-lisp-face-attribute face (car args)
 					  (purecopy (cadr args))
 					  where))
-- 
2.35.1