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: Yuan Fu
Subject: bug#49797: 28.0.50; Setting face to custom fontset doesn't work
Date: Tue, 5 Oct 2021 08:36:26 -0700

I finally got myself a Linux machine and am able to use gdb and poke around in 
xfaces.c. I think the reason why setting custom fontset doesn’t work is at 
here, in Finternal_set_lisp_face_attribute at xfaces.c:3425:

                  if (STRINGP (value))
                    {
                      Lisp_Object name = value;
                      int fontset = fs_query_fontset (name, 0);

                      if (fontset >= 0)
                        name = fontset_ascii (fontset);
                      value = font_spec_from_name (name);
                      if (!FONTP (value))
                        signal_error ("Invalid font name", name);
                    }
                  else
                    signal_error ("Invalid font or font-spec", value);

Basically, if I try to set a custom fontset to the :font attribute, Emacs takes 
the ASCII font from my custom fontset, and set the :font attribute to that 
ASCII font. Then if the face is the default face, in set_font_frame_param, 
Emacs translates the font attribute to the frame’s “font" parameter. Finally in 
gui_set_font, Emacs looks at the “font” frame parameter and sets frame’s font.

If I try to set :fontset attribute for ‘default, 
Finternal_set_lisp_face_attribute works just fine, setting the fontset 
attribute in the face, but set_font_frame_param completely ignores the fontset 
attribute, still setting the “font” frame parameter with the :font attribute, 
and gui_set_font uses the “font” frame parameter . That’s why setting :fontset 
takes no effect either.

For faces other than default, setting :fontset works fine, because 
realize_gui_face handles :fontset attribute correctly. But it doesn’t handle 
the case where the :font attribute contains a fontset. It works right now 
because Finternal_set_lisp_face always converts the fontset passed to :font 
attribute to an font (as described above).

Here is my attempt to fix it:

In Finternal_set_lisp_face_attribute, if the :font attribute actually carries a 
fontset, set the :fontset attribute, in addition to the old logic which 
extracts a font from it and set the font to the :font attribute.

The, in set_font_frame_param, instead of looking at :font slot alone, we look 
at both :font and :fontset slot. If any of them is specified, use that for the 
“font” frame parameter. Prefer :fontset when both are specified.

In Finternal_get_lisp_face_attribute, if the user asks for a :font, prefer to 
return :fontset if both :fontset and :font are specified. (See comment for more 
detail.)

This scheme can hide the :fontset attribute from users, and allow them to set 
the fontset for a face with the :font attribute. The existing code that handles 
:fontset is untouched.

I am able to get the correct behavior described in the manual with this patch. 
WDYT? (I also attached a test file that I used.)

Yuan

Attachment: fontset.patch
Description: Binary data

Attachment: fontset-test.el
Description: Binary data


reply via email to

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