Support cons cell for 'line-spacing'
* etc/NEWS: Announce the change. * src/dispextern.h (struct glyph_row): Add 'extra_line_spacing_above' member. (struct it): Add 'extra_line_spacing_above' member. * src/frame.h (struct frame): Add 'extra_line_spacing_above' member. Update comment for 'extra_line_spacing.' * src/buffer.c (syms_of_buffer): Update the docstring of 'line-spacing' to describe the cons cell usage. * src/buffer.h (struct buffer): Update comment for 'extra_line_spacing'. * src/frame.c (gui_set_line_spacing): Handle cons cell value for 'line-spacing'. Calculate and set 'extra_line_spacing_above' for both integer and float pairs. * src/xdisp.c (init_iterator): Initialize 'extra_line_spacing_above' from buffer or frame 'line-spacing', handling cons cells for both integer and float values. (gui_produce_glyphs): Use 'extra_line_spacing_above' to distribute spacing between ascent and descent. Update 'max_extra_line_spacing' calculation. (resize_mini_window): Take line spacing into account when resizing the mini window. Pass height of a single line to 'grow_mini_window' and 'shrink_mini_window'. * src/window.c (grow_mini_window, shrink_mini_window): Add unit argument which defines height of a single line. * src/window.h (grow_mini_window, shrink_mini_window): Adjust function prototypes accordingly with unit argument. * lisp/subr.el (total-line-spacing): New function to calculate total spacing from a number or cons cell. (posn-col-row): Use total-line-spacing. * lisp/simple.el (default-line-height): Use 'total-line-spacing'. * lisp/textmodes/picture.el (picture-mouse-set-point): Use 'total-line-spacing'. * lisp/window.el (window-default-line-height): Use 'total-line-spacing'. (window--resize-mini-window): Take 'line-spacing' into account. * test/lisp/subr-tests.el (total-line-spacing): New test. * test/src/buffer-tests.el (test-line-spacing): New test. * doc/emacs/display.texi (Display Custom): Document that 'line-spacing' can be a cons cell. (Line Height): Document the new cons cell format for 'line-spacing' to allow vertical centering. Co-authored-by: Przemysław Alexander Kamiński <alexander@kaminski.se> Co-authored-by: Daniel Mendler <mail@daniel-mendler.de>
This commit is contained in:
committed by
Eli Zaretskii
parent
2145519734
commit
e8f26d554b
@@ -2351,6 +2351,16 @@ of lines which are a multiple of certain numbers. Customize
|
||||
@code{display-line-numbers-minor-tick} respectively to set those
|
||||
numbers.
|
||||
|
||||
@vindex line-spacing
|
||||
The variable @code{line-spacing} controls the vertical spacing between
|
||||
lines. It can be set to an integer (specifying pixels) or a float
|
||||
(specifying spacing relative to the default frame font height). You can
|
||||
also set this variable to a cons cell of integers or floats, such as
|
||||
@code{(@var{top} . @var{bottom})}. When set to a cons cell, the spacing
|
||||
is distributed above and below the line, allowing for text to be
|
||||
vertically centered within the line height. See also @ref{Line Height,,,
|
||||
elisp, The Emacs Lisp Reference Manual}.
|
||||
|
||||
@vindex visible-bell
|
||||
If the variable @code{visible-bell} is non-@code{nil}, Emacs attempts
|
||||
to make the whole screen blink when it would normally make an audible bell
|
||||
|
||||
@@ -2582,10 +2582,13 @@ the spacing relative to the frame's default line height.
|
||||
|
||||
@vindex line-spacing
|
||||
You can specify the line spacing for all lines in a buffer via the
|
||||
buffer-local @code{line-spacing} variable. An integer specifies
|
||||
the number of pixels put below lines. A floating-point number
|
||||
specifies the spacing relative to the default frame line height. This
|
||||
overrides line spacings specified for the frame.
|
||||
buffer-local @code{line-spacing} variable. An integer specifies the
|
||||
number of pixels put below lines. A floating-point number specifies the
|
||||
spacing relative to the default frame line height. A cons cell of
|
||||
integers or floating-point numbers specifies the spacing put above and
|
||||
below the line, allowing for vertically centering text. This overrides
|
||||
line spacings specified for the frame.
|
||||
|
||||
|
||||
@kindex line-spacing @r{(text property)}
|
||||
Finally, a newline can have a @code{line-spacing} text or overlay
|
||||
|
||||
6
etc/NEWS
6
etc/NEWS
@@ -82,6 +82,12 @@ other directory on your system. You can also invoke the
|
||||
|
||||
* Changes in Emacs 31.1
|
||||
|
||||
** 'line-spacing' now supports specifying spacing above the line.
|
||||
Previously, only spacing below the line could be specified. The variable
|
||||
can now be set to a cons cell to specify spacing both above and below
|
||||
the line, which allows for vertically centering text.
|
||||
|
||||
+++
|
||||
** 'prettify-symbols-mode' attempts to ignore undisplayable characters.
|
||||
Previously, such characters would be rendered as, e.g., white boxes.
|
||||
|
||||
|
||||
@@ -7875,10 +7875,10 @@ This function uses the definition of the default face for the currently
|
||||
selected frame."
|
||||
(let ((dfh (default-font-height))
|
||||
(lsp (if (display-graphic-p)
|
||||
(or line-spacing
|
||||
(default-value 'line-spacing)
|
||||
(frame-parameter nil 'line-spacing)
|
||||
0)
|
||||
(total-line-spacing (or line-spacing
|
||||
(default-value 'line-spacing)
|
||||
(frame-parameter nil 'line-spacing)
|
||||
0))
|
||||
0)))
|
||||
(if (floatp lsp)
|
||||
(setq lsp (truncate (* (frame-char-height) lsp))))
|
||||
|
||||
13
lisp/subr.el
13
lisp/subr.el
@@ -2027,8 +2027,9 @@ and `event-end' functions."
|
||||
(let* ((spacing (when (display-graphic-p frame)
|
||||
(or (with-current-buffer
|
||||
(window-buffer (frame-selected-window frame))
|
||||
line-spacing)
|
||||
(frame-parameter frame 'line-spacing)))))
|
||||
(total-line-spacing))
|
||||
(total-line-spacing
|
||||
(frame-parameter frame 'line-spacing))))))
|
||||
(cond ((floatp spacing)
|
||||
(setq spacing (truncate (* spacing
|
||||
(frame-char-height frame)))))
|
||||
@@ -7936,4 +7937,12 @@ and return the value found in PLACE instead."
|
||||
,(funcall setter val)
|
||||
,val)))))
|
||||
|
||||
(defun total-line-spacing (&optional line-spacing-param)
|
||||
"Return numeric value of line-spacing, summing it if it's a cons.
|
||||
When LINE-SPACING-PARAM is provided, calculate from it instead."
|
||||
(let ((v (or line-spacing-param line-spacing)))
|
||||
(pcase v
|
||||
((pred numberp) v)
|
||||
(`(,above . ,below) (+ above below)))))
|
||||
|
||||
;;; subr.el ends here
|
||||
|
||||
@@ -235,8 +235,8 @@ Use \"\\[command-apropos] picture-movement\" to see commands which control motio
|
||||
(char-ht (frame-char-height frame))
|
||||
(spacing (when (display-graphic-p frame)
|
||||
(or (with-current-buffer (window-buffer window)
|
||||
line-spacing)
|
||||
(frame-parameter frame 'line-spacing)))))
|
||||
(total-line-spacing))
|
||||
(total-line-spacing (frame-parameter frame 'line-spacing))))))
|
||||
(cond ((floatp spacing)
|
||||
(setq spacing (truncate (* spacing char-ht))))
|
||||
((null spacing)
|
||||
|
||||
@@ -2850,9 +2850,15 @@ as small) as possible, but don't signal an error."
|
||||
(let* ((frame (window-frame window))
|
||||
(root (frame-root-window frame))
|
||||
(height (window-pixel-height window))
|
||||
(min-height (+ (frame-char-height frame)
|
||||
(- (window-pixel-height window)
|
||||
(window-body-height window t))))
|
||||
;; Take line-spacing into account if the line-spacing is
|
||||
;; configured as a cons cell with above > 0 to prevent
|
||||
;; mini-window jiggling.
|
||||
(ls (or (buffer-local-value 'line-spacing (window-buffer window))
|
||||
(frame-parameter frame 'line-spacing)))
|
||||
(min-height (+ (if (and (consp ls) (> (car ls) 0))
|
||||
(window-default-line-height window)
|
||||
(frame-char-height frame))
|
||||
(- height (window-body-height window t))))
|
||||
(max-delta (- (window-pixel-height root)
|
||||
(window-min-size root nil nil t))))
|
||||
;; Don't make mini window too small.
|
||||
@@ -9906,8 +9912,8 @@ face on WINDOW's frame."
|
||||
(buffer (window-buffer window))
|
||||
(space-height
|
||||
(or (and (display-graphic-p frame)
|
||||
(or (buffer-local-value 'line-spacing buffer)
|
||||
(frame-parameter frame 'line-spacing)))
|
||||
(total-line-spacing (or (buffer-local-value 'line-spacing buffer)
|
||||
(frame-parameter frame 'line-spacing))))
|
||||
0)))
|
||||
(+ font-height
|
||||
(if (floatp space-height)
|
||||
|
||||
@@ -5875,12 +5875,15 @@ cursor's appearance is instead controlled by the variable
|
||||
`cursor-in-non-selected-windows'. */);
|
||||
|
||||
DEFVAR_PER_BUFFER ("line-spacing",
|
||||
&BVAR (current_buffer, extra_line_spacing), Qnumberp,
|
||||
&BVAR (current_buffer, extra_line_spacing), Qnil,
|
||||
doc: /* Additional space to put between lines when displaying a buffer.
|
||||
The space is measured in pixels, and put below lines on graphic displays,
|
||||
see `display-graphic-p'.
|
||||
If value is a floating point number, it specifies the spacing relative
|
||||
to the default frame line height. A value of nil means add no extra space. */);
|
||||
to the default frame line height.
|
||||
If value is a cons cell containing a pair of floats or integers,
|
||||
it is interpreted as space above and below the line, respectively.
|
||||
A value of nil means add no extra space. */);
|
||||
|
||||
DEFVAR_PER_BUFFER ("cursor-in-non-selected-windows",
|
||||
&BVAR (current_buffer, cursor_in_non_selected_windows), Qnil,
|
||||
|
||||
@@ -575,7 +575,10 @@ struct buffer
|
||||
Lisp_Object cursor_type_;
|
||||
|
||||
/* An integer > 0 means put that number of pixels below text lines
|
||||
in the display of this buffer. */
|
||||
in the display of this buffer.
|
||||
A float ~ 1.0 means add extra number of pixels below text lines
|
||||
relative to the line height.
|
||||
A cons means put car spacing above and cdr spacing below the line. */
|
||||
Lisp_Object extra_line_spacing_;
|
||||
|
||||
#ifdef HAVE_TREE_SITTER
|
||||
|
||||
@@ -960,6 +960,9 @@ struct glyph_row
|
||||
in last row when checking if row is fully visible. */
|
||||
int extra_line_spacing;
|
||||
|
||||
/* Part of extra_line_spacing that should go above the line. */
|
||||
int extra_line_spacing_above;
|
||||
|
||||
/* First position in this row. This is the text position, including
|
||||
overlay position information etc, where the display of this row
|
||||
started, and can thus be less than the position of the first
|
||||
@@ -2772,6 +2775,10 @@ struct it
|
||||
window systems only.) */
|
||||
int extra_line_spacing;
|
||||
|
||||
/* Default amount of additional space in pixels above lines (for
|
||||
window systems only). */
|
||||
int extra_line_spacing_above;
|
||||
|
||||
/* Max extra line spacing added in this row. */
|
||||
int max_extra_line_spacing;
|
||||
|
||||
|
||||
50
src/frame.c
50
src/frame.c
@@ -5454,18 +5454,60 @@ void
|
||||
gui_set_line_spacing (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
|
||||
{
|
||||
if (NILP (new_value))
|
||||
f->extra_line_spacing = 0;
|
||||
{
|
||||
f->extra_line_spacing = 0;
|
||||
f->extra_line_spacing_above = 0;
|
||||
}
|
||||
else if (RANGED_FIXNUMP (0, new_value, INT_MAX))
|
||||
f->extra_line_spacing = XFIXNAT (new_value);
|
||||
{
|
||||
f->extra_line_spacing = XFIXNAT (new_value);
|
||||
f->extra_line_spacing_above = 0;
|
||||
}
|
||||
else if (FLOATP (new_value))
|
||||
{
|
||||
int new_spacing = XFLOAT_DATA (new_value) * FRAME_LINE_HEIGHT (f) + 0.5;
|
||||
int new_spacing = XFLOAT_DATA (new_value) * FRAME_LINE_HEIGHT (f);
|
||||
|
||||
if (new_spacing >= 0)
|
||||
if (new_spacing >= 0) {
|
||||
f->extra_line_spacing = new_spacing;
|
||||
f->extra_line_spacing_above = 0;
|
||||
}
|
||||
else
|
||||
signal_error ("Invalid line-spacing", new_value);
|
||||
}
|
||||
else if (CONSP (new_value))
|
||||
{
|
||||
Lisp_Object above = XCAR (new_value);
|
||||
Lisp_Object below = XCDR (new_value);
|
||||
|
||||
/* Integer pair case. */
|
||||
if (RANGED_FIXNUMP (0, above, INT_MAX)
|
||||
&& RANGED_FIXNUMP (0, below, INT_MAX))
|
||||
{
|
||||
f->extra_line_spacing = XFIXNAT (above) + XFIXNAT (below);
|
||||
f->extra_line_spacing_above = XFIXNAT (above);
|
||||
}
|
||||
|
||||
/* Float pair case. */
|
||||
else if (FLOATP (XCAR (new_value))
|
||||
&& FLOATP (XCDR (new_value)))
|
||||
{
|
||||
int new_spacing = (XFLOAT_DATA (above) + XFLOAT_DATA (below)) * FRAME_LINE_HEIGHT (f);
|
||||
int spacing_above = XFLOAT_DATA (above) * FRAME_LINE_HEIGHT (f);
|
||||
if(new_spacing >= 0 && spacing_above >= 0)
|
||||
{
|
||||
f->extra_line_spacing = new_spacing;
|
||||
f->extra_line_spacing_above = spacing_above;
|
||||
}
|
||||
else
|
||||
signal_error ("Invalid line-spacing", new_value);
|
||||
}
|
||||
|
||||
/* Unmatched pair case. */
|
||||
else
|
||||
{
|
||||
signal_error ("Invalid line-spacing", new_value);
|
||||
}
|
||||
}
|
||||
else
|
||||
signal_error ("Invalid line-spacing", new_value);
|
||||
if (FRAME_VISIBLE_P (f))
|
||||
|
||||
@@ -718,9 +718,16 @@ struct frame
|
||||
frame parameter. 0 means don't do gamma correction. */
|
||||
double gamma;
|
||||
|
||||
/* Additional space to put between text lines on this frame. */
|
||||
/* Additional space to put below text lines on this frame.
|
||||
Also takes part in line height calculation. */
|
||||
int extra_line_spacing;
|
||||
|
||||
/* Amount of space (included in extra_line_spacing) that goes ABOVE
|
||||
line line.
|
||||
IMPORTANT: Don't use this for line height calculations.
|
||||
(5 . 20) means that extra_line_spacing is 25 with 5 above. */
|
||||
int extra_line_spacing_above;
|
||||
|
||||
/* All display backends seem to need these two pixel values. */
|
||||
unsigned long background_pixel;
|
||||
unsigned long foreground_pixel;
|
||||
|
||||
15
src/window.c
15
src/window.c
@@ -5894,11 +5894,11 @@ resize_mini_window_apply (struct window *w, int delta)
|
||||
* line of text.
|
||||
*/
|
||||
void
|
||||
grow_mini_window (struct window *w, int delta)
|
||||
grow_mini_window (struct window *w, int delta, int unit)
|
||||
{
|
||||
struct frame *f = XFRAME (w->frame);
|
||||
int old_height = window_body_height (w, WINDOW_BODY_IN_PIXELS);
|
||||
int min_height = FRAME_LINE_HEIGHT (f);
|
||||
int min_height = unit;
|
||||
|
||||
eassert (MINI_WINDOW_P (w));
|
||||
|
||||
@@ -5926,7 +5926,7 @@ grow_mini_window (struct window *w, int delta)
|
||||
resize_mini_window_apply (w, -XFIXNUM (grow));
|
||||
}
|
||||
FRAME_WINDOWS_FROZEN (f)
|
||||
= window_body_height (w, WINDOW_BODY_IN_PIXELS) > FRAME_LINE_HEIGHT (f);
|
||||
= window_body_height (w, WINDOW_BODY_IN_PIXELS) > unit;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5936,11 +5936,10 @@ grow_mini_window (struct window *w, int delta)
|
||||
* line of text.
|
||||
*/
|
||||
void
|
||||
shrink_mini_window (struct window *w)
|
||||
shrink_mini_window (struct window *w, int unit)
|
||||
{
|
||||
struct frame *f = XFRAME (w->frame);
|
||||
int delta = (window_body_height (w, WINDOW_BODY_IN_PIXELS)
|
||||
- FRAME_LINE_HEIGHT (f));
|
||||
int delta = (window_body_height (w, WINDOW_BODY_IN_PIXELS) - unit);
|
||||
|
||||
eassert (MINI_WINDOW_P (w));
|
||||
|
||||
@@ -5959,10 +5958,10 @@ shrink_mini_window (struct window *w)
|
||||
else if (delta < 0)
|
||||
/* delta can be less than zero after adding horizontal scroll
|
||||
bar. */
|
||||
grow_mini_window (w, -delta);
|
||||
grow_mini_window (w, -delta, unit);
|
||||
|
||||
FRAME_WINDOWS_FROZEN (f)
|
||||
= window_body_height (w, WINDOW_BODY_IN_PIXELS) > FRAME_LINE_HEIGHT (f);
|
||||
= window_body_height (w, WINDOW_BODY_IN_PIXELS) > unit;
|
||||
}
|
||||
|
||||
DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal,
|
||||
|
||||
@@ -1126,8 +1126,8 @@ extern Lisp_Object window_from_coordinates (struct frame *, int, int,
|
||||
extern void resize_frame_windows (struct frame *, int, bool);
|
||||
extern void restore_window_configuration (Lisp_Object);
|
||||
extern void delete_all_child_windows (Lisp_Object);
|
||||
extern void grow_mini_window (struct window *, int);
|
||||
extern void shrink_mini_window (struct window *);
|
||||
extern void grow_mini_window (struct window *, int, int);
|
||||
extern void shrink_mini_window (struct window *, int);
|
||||
extern int window_relative_x_coord (struct window *, enum window_part, int);
|
||||
|
||||
void run_window_change_functions (void);
|
||||
|
||||
73
src/xdisp.c
73
src/xdisp.c
@@ -3316,13 +3316,50 @@ init_iterator (struct it *it, struct window *w,
|
||||
if (base_face_id == DEFAULT_FACE_ID
|
||||
&& FRAME_WINDOW_P (it->f))
|
||||
{
|
||||
Lisp_Object line_space_above;
|
||||
Lisp_Object line_space_below;
|
||||
|
||||
if (FIXNATP (BVAR (current_buffer, extra_line_spacing)))
|
||||
it->extra_line_spacing = XFIXNAT (BVAR (current_buffer, extra_line_spacing));
|
||||
{
|
||||
it->extra_line_spacing = XFIXNAT (BVAR (current_buffer, extra_line_spacing));
|
||||
it->extra_line_spacing_above = 0;
|
||||
}
|
||||
else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
|
||||
it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
|
||||
* FRAME_LINE_HEIGHT (it->f));
|
||||
{
|
||||
it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
|
||||
* FRAME_LINE_HEIGHT (it->f));
|
||||
it->extra_line_spacing_above = 0;
|
||||
}
|
||||
else if (CONSP (BVAR (current_buffer, extra_line_spacing)))
|
||||
{
|
||||
line_space_above = XCAR (BVAR (current_buffer, extra_line_spacing));
|
||||
line_space_below = XCDR (BVAR (current_buffer, extra_line_spacing));
|
||||
/* Integer pair case. */
|
||||
if (FIXNATP (line_space_above) && FIXNATP (line_space_below))
|
||||
{
|
||||
int line_space_total = XFIXNAT (line_space_below) + XFIXNAT (line_space_above);
|
||||
it->extra_line_spacing = line_space_total;
|
||||
it->extra_line_spacing_above = XFIXNAT (line_space_above);
|
||||
}
|
||||
/* Float pair case. */
|
||||
else if (FLOATP (line_space_above) && FLOATP (line_space_below))
|
||||
{
|
||||
double line_space_total = XFLOAT_DATA (line_space_above) + XFLOAT_DATA (line_space_below);
|
||||
it->extra_line_spacing = (line_space_total * FRAME_LINE_HEIGHT (it->f));
|
||||
it->extra_line_spacing_above = (XFLOAT_DATA (line_space_above) * FRAME_LINE_HEIGHT (it->f));
|
||||
}
|
||||
/* Invalid cons. */
|
||||
else
|
||||
{
|
||||
it->extra_line_spacing = 0;
|
||||
it->extra_line_spacing_above = 0;
|
||||
}
|
||||
}
|
||||
else if (it->f->extra_line_spacing > 0)
|
||||
it->extra_line_spacing = it->f->extra_line_spacing;
|
||||
{
|
||||
it->extra_line_spacing = it->f->extra_line_spacing;
|
||||
it->extra_line_spacing_above = it->f->extra_line_spacing_above;
|
||||
}
|
||||
}
|
||||
|
||||
/* If realized faces have been removed, e.g. because of face
|
||||
@@ -13157,7 +13194,7 @@ resize_mini_window (struct window *w, bool exact_p)
|
||||
else
|
||||
{
|
||||
struct it it;
|
||||
int unit = FRAME_LINE_HEIGHT (f);
|
||||
int unit;
|
||||
int height, max_height;
|
||||
struct text_pos start;
|
||||
struct buffer *old_current_buffer = NULL;
|
||||
@@ -13171,6 +13208,10 @@ resize_mini_window (struct window *w, bool exact_p)
|
||||
|
||||
init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
|
||||
|
||||
/* Unit includes line spacing if line spacing is added above */
|
||||
unit = FRAME_LINE_HEIGHT (f) +
|
||||
(it.extra_line_spacing_above ? it.extra_line_spacing : 0);
|
||||
|
||||
/* Compute the max. number of lines specified by the user. */
|
||||
if (FLOATP (Vmax_mini_window_height))
|
||||
max_height = XFLOAT_DATA (Vmax_mini_window_height) * windows_height;
|
||||
@@ -13203,7 +13244,10 @@ resize_mini_window (struct window *w, bool exact_p)
|
||||
}
|
||||
else
|
||||
height = it.current_y + it.max_ascent + it.max_descent;
|
||||
height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
|
||||
|
||||
/* Remove final line spacing in the mini-window */
|
||||
if (!it.extra_line_spacing_above)
|
||||
height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
|
||||
|
||||
/* Compute a suitable window start. */
|
||||
if (height > max_height)
|
||||
@@ -13241,13 +13285,13 @@ resize_mini_window (struct window *w, bool exact_p)
|
||||
/* Let it grow only, until we display an empty message, in which
|
||||
case the window shrinks again. */
|
||||
if (height > old_height)
|
||||
grow_mini_window (w, height - old_height);
|
||||
grow_mini_window (w, height - old_height, unit);
|
||||
else if (height < old_height && (exact_p || BEGV == ZV))
|
||||
shrink_mini_window (w);
|
||||
shrink_mini_window (w, unit);
|
||||
}
|
||||
else if (height != old_height)
|
||||
/* Always resize to exact size needed. */
|
||||
grow_mini_window (w, height - old_height);
|
||||
grow_mini_window (w, height - old_height, unit);
|
||||
|
||||
if (old_current_buffer)
|
||||
set_buffer_internal (old_current_buffer);
|
||||
@@ -24068,6 +24112,7 @@ append_space_for_newline (struct it *it, bool default_face_p)
|
||||
{
|
||||
Lisp_Object height, total_height;
|
||||
int extra_line_spacing = it->extra_line_spacing;
|
||||
int extra_line_spacing_above = it->extra_line_spacing_above;
|
||||
int boff = font->baseline_offset;
|
||||
|
||||
if (font->vertical_centering)
|
||||
@@ -24109,7 +24154,7 @@ append_space_for_newline (struct it *it, bool default_face_p)
|
||||
|
||||
if (!NILP (total_height))
|
||||
spacing = calc_line_height_property (it, total_height, font,
|
||||
boff, false);
|
||||
boff, false);
|
||||
else
|
||||
{
|
||||
spacing = get_it_property (it, Qline_spacing);
|
||||
@@ -24121,11 +24166,13 @@ append_space_for_newline (struct it *it, bool default_face_p)
|
||||
extra_line_spacing = XFIXNUM (spacing);
|
||||
if (!NILP (total_height))
|
||||
extra_line_spacing -= (it->phys_ascent + it->phys_descent);
|
||||
|
||||
}
|
||||
}
|
||||
if (extra_line_spacing > 0)
|
||||
{
|
||||
it->descent += extra_line_spacing;
|
||||
it->descent += (extra_line_spacing - extra_line_spacing_above);
|
||||
it->ascent += extra_line_spacing_above;
|
||||
if (extra_line_spacing > it->max_extra_line_spacing)
|
||||
it->max_extra_line_spacing = extra_line_spacing;
|
||||
}
|
||||
@@ -33138,6 +33185,7 @@ void
|
||||
gui_produce_glyphs (struct it *it)
|
||||
{
|
||||
int extra_line_spacing = it->extra_line_spacing;
|
||||
int extra_line_spacing_above = it->extra_line_spacing_above;
|
||||
|
||||
it->glyph_not_available_p = false;
|
||||
|
||||
@@ -33891,7 +33939,8 @@ gui_produce_glyphs (struct it *it)
|
||||
|
||||
if (extra_line_spacing > 0)
|
||||
{
|
||||
it->descent += extra_line_spacing;
|
||||
it->descent += extra_line_spacing - extra_line_spacing_above;
|
||||
it->ascent += extra_line_spacing_above;
|
||||
if (extra_line_spacing > it->max_extra_line_spacing)
|
||||
it->max_extra_line_spacing = extra_line_spacing;
|
||||
}
|
||||
|
||||
@@ -1694,5 +1694,20 @@ final or penultimate step during initialization."))
|
||||
(should (equal (funcall (subr--identity #'any) #'minusp ls) '(-1 -2 -3)))
|
||||
(should (equal (funcall (subr--identity #'any) #'stringp ls) nil))))
|
||||
|
||||
(ert-deftest total-line-spacing ()
|
||||
(progn
|
||||
(let ((line-spacing 10))
|
||||
(should (equal (total-line-spacing) line-spacing) ))
|
||||
(let ((line-spacing 0.8))
|
||||
(should (equal (total-line-spacing) 0.8)))
|
||||
(let ((line-spacing '(10 . 5)))
|
||||
(should (equal (total-line-spacing) 15)))
|
||||
(let ((line-spacing '(0.3 . 0.4)))
|
||||
(should (equal (total-line-spacing) 0.7)))
|
||||
(should (equal (total-line-spacing 10) 10))
|
||||
(should (equal (total-line-spacing 0.3) 0.3))
|
||||
(should (equal (total-line-spacing '(1 . 3)) 4))
|
||||
(should (equal (total-line-spacing '(0.1 . 0.1 )) 0.2))))
|
||||
|
||||
(provide 'subr-tests)
|
||||
;;; subr-tests.el ends here
|
||||
|
||||
@@ -8650,4 +8650,22 @@ Finally, kill the buffer and its temporary file."
|
||||
(should (= (point-min) 1))
|
||||
(should (= (point-max) 5001))))
|
||||
|
||||
(ert-deftest test-line-spacing ()
|
||||
"Test `line-spacing' impact on text size"
|
||||
(skip-unless (display-graphic-p))
|
||||
(let*
|
||||
((size-with-text (lambda (ls)
|
||||
(with-temp-buffer
|
||||
(setq-local line-spacing ls)
|
||||
(insert "X\nX")
|
||||
(cdr (buffer-text-pixel-size))))))
|
||||
(cl-loop for x from 0 to 50
|
||||
for y from 0 to 50
|
||||
do
|
||||
(ert-info ((format "((linespacing '(%d . %d)) == (linespacing %d)" x y (+ x y))
|
||||
:prefix "Linespace check: ")
|
||||
(should (=
|
||||
(funcall size-with-text (+ x y))
|
||||
(funcall size-with-text (cons x y))))))))
|
||||
|
||||
;;; buffer-tests.el ends here
|
||||
|
||||
Reference in New Issue
Block a user