Subject: Re: bug#70993: set-fontset-font doesn't use specified font for some scripts

From: Rodrigo Morales <[email-masked]>
Date: Fri, 17 May 2024 09:57:47 -0500

Eli Zaretskii <[email-masked]> writes:

> I think you need to evaluate those set-fontset-font expressions
> _before_ displaying any characters from the corresponding scripts
> (i.e., at the very beginning of the Emacs session), to get reliable
> results.

I tried setting the font for those scripts in an empty
~/.config/emacs/init.el but the hexadecimal code inside a box was not
shown.

I cleaned the file =~/.config/emacs/init.el= in my system and inserted
the following sexp:

#+HEADER: :tangle ~/.config/emacs/init.el
#+BEGIN_SRC elisp
(set-fontset-font t 'brahmi (font-spec :family "Cozette"))
(set-fontset-font t 'egyptian (font-spec :family "Cozette"))
(set-fontset-font t 'ethiopic (font-spec :family "Cozette"))
(set-fontset-font t 'tagbanwa (font-spec :family "Cozette"))
(set-fontset-font t 'han (font-spec :family "Cozette"))
#+END_SRC

I then launched =emacs= without the =-Q= flag so that
=~/.config/emacs/init.el= is read. Afterwards, I opened the file
=/tmp/a.txt= which contained the same content as in my first message in
this bug report.

#+HEADER: :tangle /tmp/a.txt
#+BEGIN_SRC text
The following lines were retrieved from the HELLO buffer which is
opened by calling view-hello-file in GNU Emacs 29.3.
Brahmi (𑀩𑁆𑀭𑀸𑀳𑁆𑀫𑀻)	𑀦𑀫𑀲𑁆𑀢𑁂
Egyptian Hieroglyphs (𓂋𓏤𓈖𓆎𓅓‌𓏏𓊖)	𓅓𓊵𓏏𓊪, 𓇍𓇋𓂻𓍘𓇋
Amharic (አማርኛ)	ሠላም
Tagbanwa (ᝦᝪᝯ)	ᝫᝩᝬᝥ ᝣᝮᝧᝯ
Chinese (中文,普通话,汉语)	你好
#+END_SRC

The lines containing the scripts Brahmi and Egyptian Hieroglyphs showed
the hexadecimal code inside a box, while the lines containing the
scripts Amharic, Tagbanwa and Chinese didn't show the hexadecimal code
inside a box. Here's the font reported by what-cursor-position when
called with a prefix argument in each line:

Brahmi: no font available
Egyptian Hieroglyphs: no font available
Amharic: ftcrhb:-GOOG-Noto Sans Ethiopic-regular-normal-normal-*-12-*-*-*-*-0-iso10646-1 (#x2B)
Tagbanwa: ftcrhb:-GOOG-Noto Sans Tagbanwa-regular-normal-normal-*-12-*-*-*-*-0-iso10646-1 (#x12)
Chinese: ftcrhb:-GOOG-Noto Sans CJK KR-regular-normal-normal-*-12-*-*-*-*-0-iso10646-1 (#x2703)

> That's because some scripts require characters to be composed on
> display, and Emacs caches these compositions together with the font
> used to display those characters.  Changing the fontset after some
> character compositions were already cached will not change the font
> recorded in the cached compositions.
>
> IOW, set-fontset-font cannot be reliably used in the middle of an
> Emacs session.

This is a significant limitation for users that feel the need to
regularly change the font for a given script in the middle of an Emacs
session (e.g. users of the package
[[https://github.com/tumashu/cnfonts][cnfonts]], the package primarily
uses set-fontset-font for setting the font for the scripts 'kana, 'han,
'cjk-misc, 'bopomofo and 'hangul). As for me, I usually change the font
for the script 'han because I'm studying Asian languages and the glyphs
for a unique code point can be significantly different when using
different fonts, see more information in table "Same code point,
different language tags" in
https://en.wikipedia.org/wiki/Variant_Chinese_characters

I lack knowledge on how Emacs internals work to set the font for
specific scripts and how glyphs for each character are chosen so I don't
know how difficult this would be to implement but I believe that given
that Emacs is called an extensible and customizable text editor in
https://www.gnu.org/software/emacs/, set-fontset-font should have a
reliable and consistent behavior when it is run in the middle of an
Emacs session. Thus, giving users the freedom to change the font for any
script at any time reliably and making Emacs more customizable. Please
let me know your thoughts.