Package: emacs;
Reported by: "Feng Shu" <tumashu <at> 163.com>
Date: Sat, 13 Nov 2021 23:30:03 UTC
Severity: wishlist
Found in version 29.0.50
View this message in rfc822 format
From: Eli Zaretskii <eliz <at> gnu.org> To: tumashu <at> 163.com, luangruo <at> yahoo.com Cc: larsi <at> gnus.org, 51821 <at> debbugs.gnu.org Subject: bug#51821: 29.0.50; Suggest add variable or frame parameter: line-height Date: Thu, 18 Nov 2021 20:26:20 +0200
> Date: Tue, 16 Nov 2021 18:45:16 +0200 > From: Eli Zaretskii <eliz <at> gnu.org> > Cc: tumashu <at> 163.com, 51821 <at> debbugs.gnu.org > > > From: Lars Ingebrigtsen <larsi <at> gnus.org> > > Cc: tumashu <at> 163.com, 51821 <at> debbugs.gnu.org > > Date: Tue, 16 Nov 2021 16:20:52 +0100 > > > > > That shouldn't happen, normally. Emacs selects fonts of the same size > > > for a face. > > > > No, not really. Here's a trivial example: > > > > > > Note how the lines with jidanni are taller than the rest. > > OK, let me see what can be done about that. Please try the patch below. I have a very limited number of cases with which I can test it, so I think users of CJK scripts should say what they think. Basically, set the new variable line-height-factor to something like 1.2 (more if you enlarge the non-ASCII font to make double-width characters take close to 2 columns), and see if you get the desired effect. If this is what people want, I will install it and document it. diff --git a/src/window.c b/src/window.c index e801ff8..a368b6d 100644 --- a/src/window.c +++ b/src/window.c @@ -5246,7 +5246,10 @@ grow_mini_window (struct window *w, int delta) { struct frame *f = XFRAME (w->frame); int old_height = window_body_height (w, true); - int min_height = FRAME_LINE_HEIGHT (f); + int min_height = + FLOATP (Vline_height_factor) + ? FRAME_LINE_HEIGHT (f) * XFLOAT_DATA (Vline_height_factor) + : FRAME_LINE_HEIGHT (f); eassert (MINI_WINDOW_P (w)); @@ -5279,7 +5282,11 @@ grow_mini_window (struct window *w, int delta) shrink_mini_window (struct window *w) { struct frame *f = XFRAME (w->frame); - int delta = window_body_height (w, true) - FRAME_LINE_HEIGHT (f); + int min_line_height = + FLOATP (Vline_height_factor) + ? FRAME_LINE_HEIGHT (f) * XFLOAT_DATA (Vline_height_factor) + : FRAME_LINE_HEIGHT (f); + int delta = window_body_height (w, true) - min_line_height; eassert (MINI_WINDOW_P (w)); diff --git a/src/xdisp.c b/src/xdisp.c index ef49297..d1f4043 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -22073,6 +22073,18 @@ append_space_for_newline (struct it *it, bool default_face_p) it->descent = it->override_descent; boff = it->override_boff; } + else + { + /* Enlarge the ascent to make the row higher by + line-height-factor if needed. */ + if (face == face->ascii_face && it->voffset == 0 + && FLOATP (Vline_height_factor)) + { + int enlarged_height = ((it->ascent + it->descent) + * XFLOAT_DATA (Vline_height_factor)); + it->ascent = enlarged_height - it->descent; + } + } if (EQ (height, Qt)) extra_line_spacing = 0; else @@ -30587,9 +30599,9 @@ gui_produce_glyphs (struct it *it) /* When no suitable font is found, display this character by the method specified in the first extra slot of Vglyphless_char_display. */ - Lisp_Object acronym = lookup_glyphless_char_display (-1, it); + Lisp_Object acronym = lookup_glyphless_char_display (-1, it); - eassert (it->what == IT_GLYPHLESS); + eassert (it->what == IT_GLYPHLESS); produce_glyphless_glyph (it, true, STRINGP (acronym) ? acronym : Qnil); goto done; @@ -30613,6 +30625,15 @@ gui_produce_glyphs (struct it *it) { it->ascent = FONT_BASE (font) + boff; it->descent = FONT_DESCENT (font) - boff; + /* If this glyph uses the ASCII face, enlarge the ascent + to make the row higher by line-height-factor. */ + if (face == face->ascii_face && it->voffset == 0 + && FLOATP (Vline_height_factor)) + { + int enlarged_height = ((it->ascent + it->descent) + * XFLOAT_DATA (Vline_height_factor)); + it->ascent = enlarged_height - it->descent; + } } if (get_char_glyph_code (it->char_to_display, font, &char2b)) @@ -30763,6 +30784,13 @@ gui_produce_glyphs (struct it *it) { it->ascent = FONT_BASE (font) + boff; it->descent = FONT_DESCENT (font) - boff; + if (face == face->ascii_face && it->voffset == 0 + && FLOATP (Vline_height_factor)) + { + int enlarged_height = ((it->ascent + it->descent) + * XFLOAT_DATA (Vline_height_factor)); + it->ascent = enlarged_height - it->descent; + } } } @@ -30886,6 +30914,13 @@ gui_produce_glyphs (struct it *it) { it->ascent = FONT_BASE (font) + boff; it->descent = FONT_DESCENT (font) - boff; + if (face == face->ascii_face && it->voffset == 0 + && FLOATP (Vline_height_factor)) + { + int enlarged_height = ((it->ascent + it->descent) + * XFLOAT_DATA (Vline_height_factor)); + it->ascent = enlarged_height - it->descent; + } } it->phys_ascent = it->ascent; it->phys_descent = it->descent; @@ -31243,6 +31278,24 @@ gui_produce_glyphs (struct it *it) if (it->glyph_row && (metrics.lbearing < 0 || metrics.rbearing > metrics.width)) it->glyph_row->contains_overlapping_glyphs_p = true; + if (it->voffset == 0 && FLOATP (Vline_height_factor)) + { + Lisp_Object font_object = LGSTRING_FONT (gstring); + struct font *gstring_font = XFONT_OBJECT (font_object); + + /* This is for when the grapheme cluster displays some + ligature using ASCII font: if the height is smaller + than line-height-factor says, enlarge the ascent. */ + if (face == face->ascii_face + && face->ascii_face->font == gstring_font) + { + int enlarged_height = + ((FONT_BASE (gstring_font) + FONT_DESCENT (gstring_font)) + * XFLOAT_DATA (Vline_height_factor)); + if (metrics.ascent + metrics.descent < enlarged_height) + metrics.ascent = enlarged_height - metrics.descent; + } + } it->ascent = it->phys_ascent = metrics.ascent; it->descent = it->phys_descent = metrics.descent; } @@ -35581,6 +35634,16 @@ syms_of_xdisp (void) mini-window frame's default font's height. */); Vmax_mini_window_height = make_float (0.25); + DEFVAR_LISP ("line-height-factor", Vline_height_factor, + doc: /* Factor for enlarging the height of lines that use the default font. +The value should be a float number greater than 1. It determines how +much will Emacs enlarge the height of a screen line that shows only +characters displayed with the default face's font for ASCII characters. +This is to avoid differences in height between lines that use the +ASCII font and those which use non-ASCII (for example, Chinese) +font, which is typically higher than the ASCII one. */); + Vline_height_factor = Qnil; + DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows, doc: /* How to resize mini-windows (the minibuffer and the echo area). A value of nil means don't automatically resize mini-windows.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.