Subject: bug#29631: 25.3; Unable to use custom fontset as frame default font

From: Eli Zaretskii <[email-masked]>
Date: Sun, 10 Dec 2017 19:28:04 +0200

> From: Thomas Morgan <[email-masked]>
> Date: Sat, 09 Dec 2017 16:32:39 -0500
> 
> I started Emacs with `emacs -Q', entered the following expression
> in *scratch*, and evaluated it with C-M-x:
> 
>   (progn
>     ;; Create a new fontset called fontset-liberation.
>     (create-fontset-from-fontset-spec
>      "-*-Liberation Mono-normal-normal-normal-*-*-*-*-*-m-0-fontset-liberation")
> 
>     ;; Set its primary font to Liberation Mono.
>     (set-fontset-font "fontset-liberation" 'unicode-bmp "Liberation Mono")
> 
>     ;; Add a fallback to Freemono for characters that Liberation Mono lacks.
>     (set-fontset-font "fontset-liberation" 'unicode-bmp "Freemono:size=40"
>                       nil 'append)
> 
>     ;; Set the frame's default font to the new fontset.
> 
>     (set-face-font 'default "fontset-liberation")
> 
>     ;; Return font objects for "a", an ASCII character that Liberation Mono has,
>     ;; and "ȷ" (LATIN SMALL LETTER DOTLESS J), a character in Freemono but
>     ;; not in Liberation Mono.
>     (list (font-at 0 nil "a") (font-at 0 nil "ȷ")))
> 
> The result was this:
> 
>   (#<font-object "-1ASC-Liberation Mono-normal-normal-normal-*-15-*-*-*-m-0-iso10646-1">
>    #<font-object "-1ASC-Liberation Serif-normal-normal-normal-*-15-*-*-*-*-0-iso10646-1">)
> 
> The font for ASCII character "a" was Liberation Mono as expected, but
> I expected the second font to be Freemono and it was Liberation Serif.
> 
> I checked which fontset is being used as default:
> 
>   (face-attribute 'default :fontset)
> 
> It's fontset-auto1, not fontset-liberation:
> 
>   "-1ASC-Liberation Mono-normal-normal-normal-*-15-*-*-*-m-0-fontset-auto1"
> 
> I typed `M-x describe-fontset RET fontset-auto1 RET'.
> 
>   Fontset: -1ASC-Liberation Mono-normal-normal-normal-*-15-*-*-*-m-0-fontset-auto1
>   CHAR RANGE (CODE RANGE)
>       FONT NAME (REQUESTED and [OPENED])
>   C-@ ..  (#x43 .. #x9F)
>       -*-*-*-*-*-*-*-*-*-*-*-*-iso10646-1
>     .. ɏ (#xA0 .. #x24F)
>       -*-*-*-*-*-*-*-*-*-*-*-*-iso10646-1
>           [-1ASC-Liberation Mono-normal-normal-normal-*-15-*-*-*-m-0-iso10646-1]
>           [-1ASC-Liberation Serif-normal-normal-normal-*-15-*-*-*-*-0-iso10646-1]
>   ɐ .. [#x3FFF7F] (#x250 .. #x3FFF7F)
>       -*-*-*-*-*-*-*-*-*-*-*-*-iso10646-1
>   [\200] .. [\377] (#x3FFF80 .. #x3FFFFF)
>       -*-*-*-*-*-*-*-*-*-*-*-*-iso10646-1
> 
>     ---<fallback to the default fontset>---
>   [...]
> 
> (Non-UTF8 characters are replaced with representations in brackets.)
> 
> So fontset-auto1 includes Liberation Serif but not Freemono.
> fontset-auto1 seems to be generated from fontset-liberation's primary
> font without regard for its fallback fonts.
> 
> To test whether changing the fallback font in fontset-auto1 has
> an effect, I restarted Emacs with `emacs -Q' and evaluated the
> following expression, which modifies fontset-auto1 instead of
> fontset-liberation.
> 
>   (progn
>     ;; Create a new fontset called fontset-liberation.
>     (create-fontset-from-fontset-spec
>      "-*-Liberation Mono-normal-normal-normal-*-*-*-*-*-m-0-fontset-liberation")
> 
>     ;; Set the frame's default font to the new fontset.
>     (set-face-font 'default "fontset-liberation")
> 
>     ;; Set the frame's primary font to Liberation Mono.
>     (set-fontset-font "fontset-auto1" 'unicode-bmp "Liberation Mono")
> 
>     ;; Add a fallback to Freemono for characters that Liberation Mono lacks.
>     (set-fontset-font "fontset-auto1" 'unicode-bmp "Freemono:size=40"
>                       nil 'append)
> 
>     ;; Return font objects for "a", an ASCII character that Liberation Mono has,
>     ;; and "ȷ" (LATIN SMALL LETTER DOTLESS J), a character in Freemono but
>     ;; not in Liberation Mono.
>     (list (font-at 0 nil "a") (font-at 0 nil "ȷ")))
> 
> This changed the font for the non-ASCII character to Freemono
> and returned what I expected:
> 
>   (#<font-object "-1ASC-Liberation Mono-normal-normal-normal-*-15-*-*-*-m-0-iso10646-1">
>    #<font-object "-GNU -FreeMono-normal-normal-normal-*-40-*-*-*-m-0-iso10646-1">)
> 
> (Incidentally, evaluating the above progn without restarting Emacs
> causes a core dump, but I have a smaller test case for that and I'll
> make another report about it.)
> 
> It looks as if fontset-auto1 is generated by fontset_from_font
> in fontset.c, but I don't understand why the specified fontset
> (fontset-liberation) is not used and I haven't been able to find
> anything in the manual that clarifies this behavior.  I'd like
> to know how to use a custom fontset for a frame's default face
> (and for other faces), but if that's not supported, this may be
> a documentation bug.

CC'ing Handa-san in the hope that he could provide some insights.