From bbf53d99b57bd3d7fc0427d378df2efc6fa10e00 Mon Sep 17 00:00:00 2001 From: Aaron Jensen Date: Sat, 10 Mar 2018 13:14:28 +0200 Subject: [PATCH] Allow underline position variables be buffer-local * src/nsterm.m (ns_draw_text_decoration): * src/w32term.c (x_draw_glyph_string): * src/xterm.c (x_draw_glyph_string): Allow underline-minimum-offset, underline-at-descent-line, and x-use-underline-position-properties be buffer local variables. (Bug#30553) * src/xdisp.c (syms_of_xdisp) : Add DEFSYM. --- src/nsterm.m | 26 ++++++++++++++++++++++---- src/w32term.c | 36 ++++++++++++++++++++++++++++++------ src/xdisp.c | 1 + src/xterm.c | 37 ++++++++++++++++++++++++++++++------- 4 files changed, 83 insertions(+), 17 deletions(-) diff --git a/src/nsterm.m b/src/nsterm.m index 1919c6defaf..75e0b837c67 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3487,23 +3487,38 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face, { struct font *font = font_for_underline_metrics (s); unsigned long descent = s->y + s->height - s->ybase; + unsigned long minimum_offset; + BOOL underline_at_descent_line, use_underline_position_properties; + Lisp_Object val = buffer_local_value (Qunderline_minimum_offset, + s->w->contents); + if (INTEGERP (val)) + minimum_offset = XFASTINT (val); + else + minimum_offset = 1; + val = buffer_local_value (Qx_underline_at_descent_line, + s->w->contents); + underline_at_descent_line = !(NILP (val) || EQ (val, Qunbound)); + val = buffer_local_value (Qx_use_underline_position_properties, + s->w->contents); + use_underline_position_properties = + !(NILP (val) || EQ (val, Qunbound)); /* Use underline thickness of font, defaulting to 1. */ thickness = (font && font->underline_thickness > 0) ? font->underline_thickness : 1; /* Determine the offset of underlining from the baseline. */ - if (x_underline_at_descent_line) + if (underline_at_descent_line) position = descent - thickness; - else if (x_use_underline_position_properties + else if (use_underline_position_properties && font && font->underline_position >= 0) position = font->underline_position; else if (font) position = lround (font->descent / 2); else - position = underline_minimum_offset; + position = minimum_offset; - position = max (position, underline_minimum_offset); + position = max (position, minimum_offset); /* Ensure underlining is not cropped. */ if (descent <= position) @@ -9465,11 +9480,14 @@ This variable is ignored on macOS < 10.7 and GNUstep. Default is t. */); x_use_underline_position_properties, doc: /* SKIP: real doc in xterm.c. */); x_use_underline_position_properties = 0; + DEFSYM (Qx_use_underline_position_properties, + "x-use-underline-position-properties"); DEFVAR_BOOL ("x-underline-at-descent-line", x_underline_at_descent_line, doc: /* SKIP: real doc in xterm.c. */); x_underline_at_descent_line = 0; + DEFSYM (Qx_underline_at_descent_line, "x-underline-at-descent-line"); /* Tell Emacs about this window system. */ Fprovide (Qns, Qnil); diff --git a/src/w32term.c b/src/w32term.c index 97afb678c1d..24950dd25ec 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -2475,31 +2475,52 @@ x_draw_glyph_string (struct glyph_string *s) else { struct font *font = font_for_underline_metrics (s); + unsigned long minimum_offset; + BOOL underline_at_descent_line; + BOOL use_underline_position_properties; + Lisp_Object val + = buffer_local_value (Qunderline_minimum_offset, + s->w->contents); + if (INTEGERP (val)) + minimum_offset = XFASTINT (val); + else + minimum_offset = 1; + val = buffer_local_value (Qx_underline_at_descent_line, + s->w->contents); + underline_at_descent_line + = !(NILP (val) || EQ (val, Qunbound)); + val + = buffer_local_value (Qx_use_underline_position_properties, + s->w->contents); + use_underline_position_properties + = !(NILP (val) || EQ (val, Qunbound)); /* Get the underline thickness. Default is 1 pixel. */ if (font && font->underline_thickness > 0) thickness = font->underline_thickness; else thickness = 1; - if (x_underline_at_descent_line || !font) + if (underline_at_descent_line + || !font) position = (s->height - thickness) - (s->ybase - s->y); else { - /* Get the underline position. This is the recommended - vertical offset in pixels from the baseline to the top of - the underline. This is a signed value according to the + /* Get the underline position. This is the + recommended vertical offset in pixels from + the baseline to the top of the underline. + This is a signed value according to the specs, and its default is ROUND ((maximum_descent) / 2), with ROUND (x) = floor (x + 0.5) */ - if (x_use_underline_position_properties + if (use_underline_position_properties && font->underline_position >= 0) position = font->underline_position; else position = (font->descent + 1) / 2; } - position = max (position, underline_minimum_offset); + position = max (position, minimum_offset); } /* Check the sanity of thickness and position. We should avoid drawing underline out of the current line area. */ @@ -7385,11 +7406,14 @@ the cursor have no effect. */); x_use_underline_position_properties, doc: /* SKIP: real doc in xterm.c. */); x_use_underline_position_properties = 0; + DEFSYM (Qx_use_underline_position_properties, + "x-use-underline-position-properties"); DEFVAR_BOOL ("x-underline-at-descent-line", x_underline_at_descent_line, doc: /* SKIP: real doc in xterm.c. */); x_underline_at_descent_line = 0; + DEFSYM (Qx_underline_at_descent_line, "x-underline-at-descent-line"); DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars, doc: /* SKIP: real doc in xterm.c. */); diff --git a/src/xdisp.c b/src/xdisp.c index c2b3f5d954c..44eb1ebf059 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -33040,6 +33040,7 @@ particularly when using variable `x-use-underline-position-properties' with fonts that specify an UNDERLINE_POSITION relatively close to the baseline. The default value is 1. */); underline_minimum_offset = 1; + DEFSYM (Qunderline_minimum_offset, "underline-minimum-offset"); DEFVAR_BOOL ("display-hourglass", display_hourglass_p, doc: /* Non-nil means show an hourglass pointer, when Emacs is busy. diff --git a/src/xterm.c b/src/xterm.c index 0d25c7f1a26..db5ea4ac55e 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -3707,33 +3707,53 @@ x_draw_glyph_string (struct glyph_string *s) else { struct font *font = font_for_underline_metrics (s); + unsigned long minimum_offset; + bool underline_at_descent_line; + bool use_underline_position_properties; + Lisp_Object val + = buffer_local_value (Qunderline_minimum_offset, + s->w->contents); + if (INTEGERP (val)) + minimum_offset = XFASTINT (val); + else + minimum_offset = 1; + val = buffer_local_value (Qx_underline_at_descent_line, + s->w->contents); + underline_at_descent_line + = !(NILP (val) || EQ (val, Qunbound)); + val + = buffer_local_value (Qx_use_underline_position_properties, + s->w->contents); + use_underline_position_properties + = !(NILP (val) || EQ (val, Qunbound)); /* Get the underline thickness. Default is 1 pixel. */ if (font && font->underline_thickness > 0) thickness = font->underline_thickness; else thickness = 1; - if (x_underline_at_descent_line) + if (underline_at_descent_line) position = (s->height - thickness) - (s->ybase - s->y); else { - /* Get the underline position. This is the recommended - vertical offset in pixels from the baseline to the top of - the underline. This is a signed value according to the + /* Get the underline position. This is the + recommended vertical offset in pixels from + the baseline to the top of the underline. + This is a signed value according to the specs, and its default is ROUND ((maximum descent) / 2), with ROUND(x) = floor (x + 0.5) */ - if (x_use_underline_position_properties + if (use_underline_position_properties && font && font->underline_position >= 0) position = font->underline_position; else if (font) position = (font->descent + 1) / 2; else - position = underline_minimum_offset; + position = minimum_offset; } - position = max (position, underline_minimum_offset); + position = max (position, minimum_offset); } /* Check the sanity of thickness and position. We should avoid drawing underline out of the current line area. */ @@ -13246,6 +13266,8 @@ UNDERLINE_POSITION font properties, set this to nil. You can also use `underline-minimum-offset' to override the font's UNDERLINE_POSITION for small font display sizes. */); x_use_underline_position_properties = true; + DEFSYM (Qx_use_underline_position_properties, + "x-use-underline-position-properties"); DEFVAR_BOOL ("x-underline-at-descent-line", x_underline_at_descent_line, @@ -13256,6 +13278,7 @@ A value of nil means to draw the underline according to the value of the variable `x-use-underline-position-properties', which is usually at the baseline level. The default value is nil. */); x_underline_at_descent_line = false; + DEFSYM (Qx_underline_at_descent_line, "x-underline-at-descent-line"); DEFVAR_BOOL ("x-mouse-click-focus-ignore-position", x_mouse_click_focus_ignore_position, -- 2.39.2