bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#49797: 28.0.50; Setting face to custom fontset doesn't work


From: Eli Zaretskii
Subject: bug#49797: 28.0.50; Setting face to custom fontset doesn't work
Date: Wed, 06 Oct 2021 19:10:59 +0300

> From: Yuan Fu <casouri@gmail.com>
> Date: Tue, 5 Oct 2021 13:51:23 -0700
> Cc: handa@gnu.org,
>  49797@debbugs.gnu.org
> 
> > I asked why not use :family and :foundry in the face definition.  Did
> > you try that?
> 
> :family, :foundry, :font, they all realize into _one_ font.

:font does.  :family doesn't, AFAIK, and :foundry definitely doesn't.

But that was just a suggestion, and it doesn't help you if you want to
use very specific fonts for specific scripts.

> Problem 1: The following doesn’t work as intended:
> 
> (set-face-attribute 'variable-pitch nil :font "fontset-serif”)
> 
> where “fontset-serif” contains two fonts: Charter for Latin and Source Han 
> Serif for CJK. 
> 
> The current effect is, Latin characters in ‘variable-pitch works (displayed 
> in Charter), CJK characters don’t (not displayed in Source Han Serif). With 
> my fix, CJK characters work (displayed in Source Han Serif).
> 
> Problem 2: ‘default face cannot use fontset. Even if problem 1 is fixed, 
> setting the fontset for the default face still doesn’t display CJK characters 
> correctly. With the fix, setting a fontset for ‘default works as intended.
> 
> The problems are not limited to CJK characters, any other non-ASCII character 
> that requires a font different from the Latin characters has the same problem.

The thing is, what you describe as "problems" is how this stuff was
designed to work, at least AFAIU the code.  Specifically, the face we
define and see in Lisp specifies the font only for the ASCII
characters.  When Emacs needs to display a non-ASCII character with
some face (including the 'default' face), it calls face_for_char.
That function will use the same face if its font supports the
character, but if not, it will create a new "derivative" face.  That
derivative face shares all the face attributes with the original one,
but has a different font.  These derivative faces are never exposed to
Lisp, and don't have names, so a few people even know they exist, but
they are very visible on the C level: they have a distinct face ID.

You want to force Emacs to use the face's font for non-ASCII
characters, but that's not how this stuff was designed, AFAIU.  If I'm
not missing something, it means what you perceive as bugs are at best
design bugs, not implementation bugs, and they cannot be fixed with a
few lines of tweaking.  That might work in your relatively simple use
case, but I don't see how we can trust that not to break important
features, because working against the design always runs that risk.

For example, this part of your patch:

> @@ -4040,7 +4055,17 @@ DEFUN ("internal-get-lisp-face-attribute", 
> Finternal_get_lisp_face_attribute,
>    else if (EQ (keyword, QCextend))
>      value = LFACE_EXTEND (lface);
>    else if (EQ (keyword, QCfont))
> -    value = LFACE_FONT (lface);
> +    {
> +      /* We prefer to return fontset, if it is specified, because font
> +      are derived from fontset when the user sets the
> +      fontset. I.e., if the fontset is specified, that's probably
> +      the one that the user set, and it is intuitive to get back
> +      what you put in.  */
> +      if (!UNSPECIFIEDP (LFACE_FONTSET (lface)))
> +     value = LFACE_FONTSET (lface);
> +      else
> +     value = LFACE_FONT (lface);
> +    }

This is completely ad-hoc, and could be wrong in some cases: the
caller wanted the font, but you provide it with a fontset, which is a
completely different Lisp object.  And there are other similarly
ad-hoc changes of the semantics of the face attributes.

Maybe we can extend the design to support "face-specific" fontsets,
but I'm quite sure that will need changes in font.c and fontset.c as
well, because the current design is implicitly assumed there.

> My fix is based on the assumption that we want to use :font attribute for 
> both font and fontsets, which is what the manual says, and is what Handa-san 
> said what RMS wanted.

That's one way of interpreting what the manual says, but it is not the
only one.  If you look at what the code does, you will arrive at
another interpretation: Emacs allows you to specify a fontset as the
value for the :font attribute, but what it does in that case is take
from the fontset the font for ASCII characters, and then use it as if
you specified that font, not a fontset.  IOW, the fontset in that case
is just used as a method of specifying the ASCII font.

But even if your interpretation were the only correct one, the way
faces and font selection works in Emacs was not designed to support
your interpretation (again, if my reading of the code is correct).

I hope Handa-san will chime in soon and set us straight.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]