From: Alex Gramiak <agrambot@gmail.com>
To: 35468@debbugs.gnu.org
Subject: bug#35468: [PATCH] Refactor draw_glyph_string on X and w32
Date: Sat, 27 Apr 2019 19:29:30 -0600 [thread overview]
Message-ID: <877ebeor2d.fsf@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 192 bytes --]
This merges x_draw_glyph_string and w32_draw_glyph_string together to
remove duplicated code.
I wanted to do it for NS as well, but it seems just a bit too different
to make it easily work.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Refactor-draw_glyph_string-on-X-and-w32.patch --]
[-- Type: text/x-patch, Size: 48961 bytes --]
From 1cd69c3bcfb79f8df61d1cacf75effb1947d869f Mon Sep 17 00:00:00 2001
From: Alexander Gramiak <agrambot@gmail.com>
Date: Sat, 27 Apr 2019 18:45:59 -0600
Subject: [PATCH] Refactor draw_glyph_string on X and w32
* src/dispextern.h (draw_glyph_string_interface): New interface for
system-dependent functions for draw_glyph_string.
(redisplay_interface): Add draw_glyph_string_interface.
* src/xdisp.c (gui_draw_glyph_string): New function implementing the
common behaviour of x_draw_glyph_string and w32_draw_glyph_string.
* src/w32term.c (w32_draw_glyph_string): Remove in favour of
gui_draw_glyph_string.
(w32_draw_underwave): Rename to w32_draw_underwave_1.
(w32_draw_underwave, w32_draw_underline, w32_draw_overline)
(w32_draw_strike_through, w32_reset_glyph_string_clipping): Define
extracted functions out of w32_draw_glyph_string.
* src/xterm.c (x_draw_glyph_string): Remove in favour of
gui_draw_glyph_string.
(x_draw_underwave): Rename to x_draw_underwave_1.
(x_draw_underwave, x_draw_underline, x_draw_overline)
(x_draw_strike_through, x_reset_glyph_string_clipping): Define
extracted functions out of x_draw_glyph_string.
---
src/dispextern.h | 98 +++++++++++
src/nsterm.m | 14 +-
src/w32term.c | 414 +++++++++++------------------------------------
src/xdisp.c | 292 +++++++++++++++++++++++++++++++++
src/xterm.c | 405 ++++++++++------------------------------------
5 files changed, 568 insertions(+), 655 deletions(-)
diff --git a/src/dispextern.h b/src/dispextern.h
index 827eed86f1..20124be817 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1389,6 +1389,98 @@ struct glyph_string
struct glyph_string *next, *prev;
};
+/* Structure holding system-dependent interface functions needed
+ for drawing glyph strings as used by `gui_draw_glyph_string'.
+
+ * If gui_draw_glyph_string is used as the RIF draw_glyph_string,
+ then all of the following must be defined with the possible
+ exception of draw_xwidget. */
+
+struct draw_glyph_string_interface
+{
+ /* Set S->gc of glyph string S for drawing that glyph string. */
+
+ void (*set_gc) (struct glyph_string *s);
+
+ /* Set clipping for output of glyph string S. */
+
+ void (*set_clipping) (struct glyph_string *s);
+
+ /* Set SRC's clipping for output of glyph string DST. This is
+ called when we are drawing DST's left_overhang or right_overhang
+ only in the area of SRC. */
+
+ void (*set_clipping_exactly) (struct glyph_string *src,
+ struct glyph_string *dst);
+
+ /* Reset clipping for output of glyph string S. */
+
+ void (*reset_clipping) (struct glyph_string *s);
+
+ /* Draw the background of glyph_string S. If S->background_filled_p
+ is non-zero don't draw it. FORCE_P non-zero means draw the
+ background even if it wouldn't be drawn normally. This is used
+ when a string preceding S draws into the background of S, or S
+ contains the first component of a composition. */
+
+ void (*draw_background) (struct glyph_string *s, bool force_p);
+
+ /* Draw the foreground of glyph string S. */
+
+ void (*draw_foreground) (struct glyph_string *s);
+
+ /* Draw a box around glyph string S. */
+
+ void (*draw_box) (struct glyph_string *s);
+
+ /* Draw image glyph string S.
+
+ s->y
+ s->x +-------------------------
+ | s->face->box
+ |
+ | +-------------------------
+ | | s->img->margin
+ | |
+ | | +-------------------
+ | | | the image
+
+ */
+
+ void (*draw_image) (struct glyph_string *s);
+
+ /* Draw stretch glyph string S. */
+
+ void (*draw_stretch) (struct glyph_string *s);
+
+ /* Draw xwidget stretch glyph string S. */
+
+ void (*draw_xwidget) (struct glyph_string *s);
+
+ /* Draw the foreground of composite glyph string S. */
+
+ void (*draw_composite_foreground) (struct glyph_string *s);
+
+ /* Draw the foreground of glyph string S for glyphless characters. */
+
+ void (*draw_glyphless_foreground) (struct glyph_string *s);
+
+ /* Draw underwave glyph string S. */
+
+ void (*draw_underwave) (struct glyph_string *s);
+
+ /* Draw underline glyph string S. */
+
+ void (*draw_underline) (struct glyph_string *s);
+
+ /* Draw overline glyph string S. */
+
+ void (*draw_overline) (struct glyph_string *s);
+
+ /* Draw strike-through glyph string S. */
+
+ void (*draw_strike_through) (struct glyph_string *s, int y, int height);
+};
#endif /* HAVE_WINDOW_SYSTEM */
\f
@@ -2890,6 +2982,10 @@ struct redisplay_interface
/* Draw a glyph string S. */
void (*draw_glyph_string) (struct glyph_string *s);
+ /* Interface for drawing glyph strings used by
+ gui_draw_glyph_string. */
+ struct draw_glyph_string_interface *gsif;
+
/* Define cursor CURSOR on frame F. */
void (*define_frame_cursor) (struct frame *f, Cursor cursor);
@@ -3288,6 +3384,8 @@ extern void gui_write_glyphs (struct window *, struct glyph_row *,
struct glyph *, enum glyph_row_area, int);
extern void gui_insert_glyphs (struct window *, struct glyph_row *,
struct glyph *, enum glyph_row_area, int);
+extern void gui_draw_glyph_string (struct glyph_string *);
+
extern void gui_clear_end_of_line (struct window *, struct glyph_row *,
enum glyph_row_area, int);
extern void gui_fix_overlapping_area (struct window *, struct glyph_row *,
diff --git a/src/nsterm.m b/src/nsterm.m
index 2a2b8cbaba..e7b3ab4ebf 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -5107,6 +5107,7 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
0, /* destroy_fringe_bitmap */
ns_compute_glyph_string_overhangs,
ns_draw_glyph_string,
+ NULL, /* draw_glyph_string_interface */
ns_define_frame_cursor,
ns_clear_frame_area,
0, /* clear_under_internal_border */
@@ -9507,19 +9508,6 @@ Nil means use fullscreen the old (< 10.7) way. The old way works better with
doc: /* SKIP: real doc in xterm.c. */);
Vx_toolkit_scroll_bars = Qt;
- DEFVAR_BOOL ("x-use-underline-position-properties",
- 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 8d5f57836c..947c67abb3 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -328,7 +328,7 @@ w32_get_scale_factor(struct w32_display_info *dpyinfo, int *scale_x, int *scale_
*/
static void
-w32_draw_underwave (struct glyph_string *s, COLORREF color)
+w32_draw_underwave_1 (struct glyph_string *s, COLORREF color)
{
struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
@@ -394,6 +394,71 @@ w32_draw_underwave (struct glyph_string *s, COLORREF color)
DeleteObject (hp);
}
+static void
+w32_draw_underwave (struct glyph_string *s)
+{
+ COLORREF color;
+
+ if (s->face->underline_defaulted_p)
+ color = s->gc->foreground;
+ else
+ color = s->face->underline_color;
+
+ w32_draw_underwave_1 (s, color);
+}
+
+static void
+w32_draw_underline (struct glyph_string *s)
+{
+ const int y = s->ybase + s->underline_position;
+
+ if (s->face->underline_defaulted_p)
+ {
+ w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
+ y, s->width, 1);
+ }
+ else
+ {
+ w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
+ y, s->width, 1);
+ }
+}
+
+static void
+w32_draw_overline (struct glyph_string *s)
+{
+ unsigned long dy = 0, h = 1;
+
+ if (s->face->overline_color_defaulted_p)
+ {
+ w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
+ s->y + dy, s->width, h);
+ }
+ else
+ {
+ w32_fill_area (s->f, s->hdc, s->face->overline_color, s->x,
+ s->y + dy, s->width, h);
+ }
+}
+
+static void
+w32_draw_strike_through (struct glyph_string *s, int y, int height)
+{
+ if (!FONT_TEXTMETRIC (s->font).tmStruckOut)
+ {
+ if (s->face->strike_through_color_defaulted_p)
+ {
+ w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
+ y, s->width, height);
+ }
+ else
+ {
+ w32_fill_area (s->f, s->hdc, s->face->strike_through_color, s->x,
+ y, s->width, height);
+ }
+ }
+}
+
/* Draw a hollow rectangle at the specified position. */
static void
w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y,
@@ -1132,6 +1197,13 @@ w32_set_glyph_string_clipping_exactly (struct glyph_string *src,
w32_set_clip_rectangle (dst->hdc, &r);
}
+static void
+w32_reset_glyph_string_clipping (struct glyph_string *s)
+{
+ w32_set_clip_rectangle (s->hdc, NULL);
+ s->num_clips = 0;
+}
+
/* RIF:
Compute left and right overhang of glyph string S. */
@@ -2384,308 +2456,6 @@ w32_draw_stretch_glyph_string (struct glyph_string *s)
}
-/* Draw glyph string S. */
-
-static void
-w32_draw_glyph_string (struct glyph_string *s)
-{
- bool relief_drawn_p = 0;
-
- /* If S draws into the background of its successor, draw the
- background of the successor first so that S can draw into it.
- This makes S->next use XDrawString instead of XDrawImageString. */
- if (s->next && s->right_overhang && !s->for_overlaps)
- {
- int width;
- struct glyph_string *next;
- for (width = 0, next = s->next;
- next && width < s->right_overhang;
- width += next->width, next = next->next)
- if (next->first_glyph->type != IMAGE_GLYPH)
- {
- w32_set_glyph_string_gc (next);
- w32_set_glyph_string_clipping (next);
- if (next->first_glyph->type == STRETCH_GLYPH)
- w32_draw_stretch_glyph_string (next);
- else
- w32_draw_glyph_string_background (next, true);
- next->num_clips = 0;
- }
- }
-
- /* Set up S->gc, set clipping and draw S. */
- w32_set_glyph_string_gc (s);
-
- /* Draw relief (if any) in advance for char/composition so that the
- glyph string can be drawn over it. */
- if (!s->for_overlaps
- && s->face->box != FACE_NO_BOX
- && (s->first_glyph->type == CHAR_GLYPH
- || s->first_glyph->type == COMPOSITE_GLYPH))
-
- {
- w32_set_glyph_string_clipping (s);
- w32_draw_glyph_string_background (s, true);
- w32_draw_glyph_string_box (s);
- w32_set_glyph_string_clipping (s);
- relief_drawn_p = 1;
- }
- else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
- && !s->clip_tail
- && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
- || (s->next && s->next->hl != s->hl && s->right_overhang)))
- /* We must clip just this glyph. left_overhang part has already
- drawn when s->prev was drawn, and right_overhang part will be
- drawn later when s->next is drawn. */
- w32_set_glyph_string_clipping_exactly (s, s);
- else
- w32_set_glyph_string_clipping (s);
-
- switch (s->first_glyph->type)
- {
- case IMAGE_GLYPH:
- w32_draw_image_glyph_string (s);
- break;
-
- case STRETCH_GLYPH:
- w32_draw_stretch_glyph_string (s);
- break;
-
- case CHAR_GLYPH:
- if (s->for_overlaps)
- s->background_filled_p = true;
- else
- w32_draw_glyph_string_background (s, false);
- w32_draw_glyph_string_foreground (s);
- break;
-
- case COMPOSITE_GLYPH:
- if (s->for_overlaps || (s->cmp_from > 0
- && ! s->first_glyph->u.cmp.automatic))
- s->background_filled_p = true;
- else
- w32_draw_glyph_string_background (s, true);
- w32_draw_composite_glyph_string_foreground (s);
- break;
-
- case GLYPHLESS_GLYPH:
- if (s->for_overlaps)
- s->background_filled_p = true;
- else
- w32_draw_glyph_string_background (s, false);
- w32_draw_glyphless_glyph_string_foreground (s);
- break;
-
- default:
- emacs_abort ();
- }
-
- if (!s->for_overlaps)
- {
- /* Draw underline. */
- if (s->face->underline_p)
- {
- if (s->face->underline_type == FACE_UNDER_WAVE)
- {
- COLORREF color;
-
- if (s->face->underline_defaulted_p)
- color = s->gc->foreground;
- else
- color = s->face->underline_color;
-
- w32_draw_underwave (s, color);
- }
- else if (s->face->underline_type == FACE_UNDER_LINE)
- {
- unsigned long thickness, position;
- int y;
-
- if (s->prev && s->prev->face->underline_p
- && s->prev->face->underline_type == FACE_UNDER_LINE)
- {
- /* We use the same underline style as the previous one. */
- thickness = s->prev->underline_thickness;
- position = s->prev->underline_position;
- }
- 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 (FIXNUMP (val))
- minimum_offset = XFIXNAT (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 (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
- specs, and its default is
-
- ROUND ((maximum_descent) / 2), with
- ROUND (x) = floor (x + 0.5) */
-
- if (use_underline_position_properties
- && font->underline_position >= 0)
- position = font->underline_position;
- else
- position = (font->descent + 1) / 2;
- }
- position = max (position, minimum_offset);
- }
- /* Check the sanity of thickness and position. We should
- avoid drawing underline out of the current line area. */
- if (s->y + s->height <= s->ybase + position)
- position = (s->height - 1) - (s->ybase - s->y);
- if (s->y + s->height < s->ybase + position + thickness)
- thickness = (s->y + s->height) - (s->ybase + position);
- s->underline_thickness = thickness;
- s->underline_position = position;
- y = s->ybase + position;
- if (s->face->underline_defaulted_p)
- {
- w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
- y, s->width, 1);
- }
- else
- {
- w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
- y, s->width, 1);
- }
- }
- }
- /* Draw overline. */
- if (s->face->overline_p)
- {
- unsigned long dy = 0, h = 1;
-
- if (s->face->overline_color_defaulted_p)
- {
- w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
- s->y + dy, s->width, h);
- }
- else
- {
- w32_fill_area (s->f, s->hdc, s->face->overline_color, s->x,
- s->y + dy, s->width, h);
- }
- }
-
- /* Draw strike-through. */
- if (s->face->strike_through_p
- && !FONT_TEXTMETRIC (s->font).tmStruckOut)
- {
- /* Y-coordinate and height of the glyph string's first
- glyph. We cannot use s->y and s->height because those
- could be larger if there are taller display elements
- (e.g., characters displayed with a larger font) in the
- same glyph row. */
- int glyph_y = s->ybase - s->first_glyph->ascent;
- int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
- /* Strike-through width and offset from the glyph string's
- top edge. */
- unsigned long h = 1;
- unsigned long dy = (glyph_height - h) / 2;
-
- if (s->face->strike_through_color_defaulted_p)
- {
- w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
- glyph_y + dy, s->width, h);
- }
- else
- {
- w32_fill_area (s->f, s->hdc, s->face->strike_through_color, s->x,
- glyph_y + dy, s->width, h);
- }
- }
-
- /* Draw relief if not yet drawn. */
- if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
- w32_draw_glyph_string_box (s);
-
- if (s->prev)
- {
- struct glyph_string *prev;
-
- for (prev = s->prev; prev; prev = prev->prev)
- if (prev->hl != s->hl
- && prev->x + prev->width + prev->right_overhang > s->x)
- {
- /* As prev was drawn while clipped to its own area, we
- must draw the right_overhang part using s->hl now. */
- enum draw_glyphs_face save = prev->hl;
-
- prev->hl = s->hl;
- w32_set_glyph_string_gc (prev);
- w32_set_glyph_string_clipping_exactly (s, prev);
- if (prev->first_glyph->type == CHAR_GLYPH)
- w32_draw_glyph_string_foreground (prev);
- else
- w32_draw_composite_glyph_string_foreground (prev);
- w32_set_clip_rectangle (prev->hdc, NULL);
- prev->hl = save;
- prev->num_clips = 0;
- }
- }
-
- if (s->next)
- {
- struct glyph_string *next;
-
- for (next = s->next; next; next = next->next)
- if (next->hl != s->hl
- && next->x - next->left_overhang < s->x + s->width)
- {
- /* As next will be drawn while clipped to its own area,
- we must draw the left_overhang part using s->hl now. */
- enum draw_glyphs_face save = next->hl;
-
- next->hl = s->hl;
- w32_set_glyph_string_gc (next);
- w32_set_glyph_string_clipping_exactly (s, next);
- if (next->first_glyph->type == CHAR_GLYPH)
- w32_draw_glyph_string_foreground (next);
- else
- w32_draw_composite_glyph_string_foreground (next);
- w32_set_clip_rectangle (next->hdc, NULL);
- next->hl = save;
- next->num_clips = 0;
- next->clip_head = s->next;
- }
- }
- }
-
- /* Reset clipping. */
- w32_set_clip_rectangle (s->hdc, NULL);
- s->num_clips = 0;
-}
-
-
/* Shift display to make room for inserted glyphs. */
static void
@@ -7077,6 +6847,26 @@ w32_make_rdb (char *xrm_option)
extern frame_parm_handler w32_frame_parm_handlers[];
+static struct draw_glyph_string_interface w32_draw_glyph_string_interface =
+{
+ w32_set_glyph_string_gc,
+ w32_set_glyph_string_clipping,
+ w32_set_glyph_string_clipping_exactly,
+ w32_reset_glyph_string_clipping,
+ w32_draw_glyph_string_background,
+ w32_draw_glyph_string_foreground,
+ w32_draw_glyph_string_box,
+ w32_draw_image_glyph_string,
+ w32_draw_stretch_glyph_string,
+ NULL, /* draw_xwidget_glyph_string */
+ w32_draw_composite_glyph_string_foreground,
+ w32_draw_glyphless_glyph_string_foreground,
+ w32_draw_underwave,
+ w32_draw_underline,
+ w32_draw_overline,
+ w32_draw_strike_through
+};
+
static struct redisplay_interface w32_redisplay_interface =
{
w32_frame_parm_handlers,
@@ -7096,7 +6886,8 @@ static struct redisplay_interface w32_redisplay_interface =
w32_define_fringe_bitmap,
w32_destroy_fringe_bitmap,
w32_compute_glyph_string_overhangs,
- w32_draw_glyph_string,
+ gui_draw_glyph_string,
+ &w32_draw_glyph_string_interface,
w32_define_frame_cursor,
w32_clear_frame_area,
w32_clear_under_internal_border,
@@ -7471,21 +7262,6 @@ the cursor have no effect. */);
w32_use_visible_system_caret = 0;
- /* We don't yet support this, but defining this here avoids whining
- from cus-start.el and other places, like "M-x set-variable". */
- DEFVAR_BOOL ("x-use-underline-position-properties",
- 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. */);
Vx_toolkit_scroll_bars = Qt;
diff --git a/src/xdisp.c b/src/xdisp.c
index a3dddfa8a5..2f5aaf6aff 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -29099,6 +29099,269 @@ gui_insert_glyphs (struct window *w, struct glyph_row *updated_row,
unblock_input ();
}
+/* EXPORT for RIF:
+ Draw glyph string S. */
+
+void
+gui_draw_glyph_string (struct glyph_string *s)
+{
+ bool relief_drawn_p = false;
+ struct draw_glyph_string_interface *gsif = FRAME_RIF (s->f)->gsif;
+
+ if (!gsif)
+ emacs_abort ();
+
+ /* If S draws into the background of its successors, draw the
+ background of the successors first so that S can draw into it. */
+ if (s->next && s->right_overhang && !s->for_overlaps)
+ {
+ int width;
+ struct glyph_string *next;
+
+ for (width = 0, next = s->next;
+ next && width < s->right_overhang;
+ width += next->width, next = next->next)
+ if (next->first_glyph->type != IMAGE_GLYPH)
+ {
+ gsif->set_gc (next);
+ gsif->set_clipping (next);
+ if (next->first_glyph->type == STRETCH_GLYPH)
+ gsif->draw_stretch (next);
+ else
+ gsif->draw_background (next, true);
+ next->num_clips = 0;
+ }
+ }
+
+ /* Set up S->gc, set clipping and draw S. */
+ gsif->set_gc (s);
+
+ /* Draw relief (if any) in advance for char/composition so that the
+ glyph string can be drawn over it. */
+ if (!s->for_overlaps
+ && s->face->box != FACE_NO_BOX
+ && (s->first_glyph->type == CHAR_GLYPH
+ || s->first_glyph->type == COMPOSITE_GLYPH))
+
+ {
+ gsif->set_clipping (s);
+ gsif->draw_background (s, true);
+ gsif->draw_box (s);
+ gsif->set_clipping (s);
+ relief_drawn_p = true;
+ }
+ else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
+ && !s->clip_tail
+ && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
+ || (s->next && s->next->hl != s->hl && s->right_overhang)))
+ /* We must clip just this glyph. left_overhang part has already
+ drawn when s->prev was drawn, and right_overhang part will be
+ drawn later when s->next is drawn. */
+ gsif->set_clipping_exactly (s, s);
+ else
+ gsif->set_clipping (s);
+
+ switch (s->first_glyph->type)
+ {
+ case IMAGE_GLYPH:
+ gsif->draw_image (s);
+ break;
+
+ case STRETCH_GLYPH:
+ gsif->draw_stretch (s);
+ break;
+
+ case CHAR_GLYPH:
+ if (s->for_overlaps)
+ s->background_filled_p = true;
+ else
+ gsif->draw_background (s, false);
+ gsif->draw_foreground (s);
+ break;
+
+ case COMPOSITE_GLYPH:
+ if (s->for_overlaps || (s->cmp_from > 0
+ && ! s->first_glyph->u.cmp.automatic))
+ s->background_filled_p = true;
+ else
+ gsif->draw_background (s, true);
+ gsif->draw_composite_foreground (s);
+ break;
+
+ case XWIDGET_GLYPH:
+ if (gsif->draw_xwidget)
+ gsif->draw_xwidget (s);
+ break;
+
+ case GLYPHLESS_GLYPH:
+ if (s->for_overlaps)
+ s->background_filled_p = true;
+ else
+ gsif->draw_background (s, true);
+ gsif->draw_glyphless_foreground (s);
+ break;
+
+ default:
+ emacs_abort ();
+ }
+
+ if (!s->for_overlaps)
+ {
+ /* Draw underline. */
+ if (s->face->underline_p)
+ {
+ if (s->face->underline_type == FACE_UNDER_WAVE)
+ gsif->draw_underwave (s);
+ else if (s->face->underline_type == FACE_UNDER_LINE)
+ {
+ unsigned long thickness, position;
+
+ if (s->prev && s->prev->face->underline_p
+ && s->prev->face->underline_type == FACE_UNDER_LINE)
+ {
+ /* We use the same underline style as the previous one. */
+ thickness = s->prev->underline_thickness;
+ position = s->prev->underline_position;
+ }
+ 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 (FIXNUMP (val))
+ minimum_offset = XFIXNAT (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 (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
+ specs, and its default is
+
+ ROUND ((maximum descent) / 2), with
+ ROUND(x) = floor (x + 0.5) */
+
+ if (use_underline_position_properties
+ && font && font->underline_position >= 0)
+ position = font->underline_position;
+ else if (font)
+ position = (font->descent + 1) / 2;
+ else
+ position = 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. */
+ if (s->y + s->height <= s->ybase + position)
+ position = (s->height - 1) - (s->ybase - s->y);
+ if (s->y + s->height < s->ybase + position + thickness)
+ thickness = (s->y + s->height) - (s->ybase + position);
+ s->underline_thickness = thickness;
+ s->underline_position = position;
+ gsif->draw_underline (s);
+ }
+ }
+ /* Draw overline. */
+ if (s->face->overline_p)
+ gsif->draw_overline (s);
+
+ /* Draw strike-through. */
+ if (s->face->strike_through_p)
+ {
+ /* Y-coordinate and height of the glyph string's first
+ glyph. We cannot use s->y and s->height because those
+ could be larger if there are taller display elements
+ (e.g., characters displayed with a larger font) in the
+ same glyph row. */
+ int glyph_y = s->ybase - s->first_glyph->ascent;
+ int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
+ /* Strike-through width and offset from the glyph string's
+ top edge. */
+ unsigned long dy = (glyph_height - 1) / 2;
+ gsif->draw_strike_through (s, glyph_y + dy, 1);
+ }
+
+ /* Draw relief if not yet drawn. */
+ if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
+ gsif->draw_box (s);
+
+ if (s->prev)
+ {
+ struct glyph_string *prev;
+
+ for (prev = s->prev; prev; prev = prev->prev)
+ if (prev->hl != s->hl
+ && prev->x + prev->width + prev->right_overhang > s->x)
+ {
+ /* As prev was drawn while clipped to its own area, we
+ must draw the right_overhang part using s->hl now. */
+ enum draw_glyphs_face save = prev->hl;
+
+ prev->hl = s->hl;
+ gsif->set_gc (prev);
+ gsif->set_clipping_exactly (s, prev);
+ if (prev->first_glyph->type == CHAR_GLYPH)
+ gsif->draw_foreground (prev);
+ else
+ gsif->draw_composite_foreground (prev);
+ gsif->reset_clipping (prev);
+ prev->hl = save;
+ }
+ }
+
+ if (s->next)
+ {
+ struct glyph_string *next;
+
+ for (next = s->next; next; next = next->next)
+ if (next->hl != s->hl
+ && next->x - next->left_overhang < s->x + s->width)
+ {
+ /* As next will be drawn while clipped to its own area,
+ we must draw the left_overhang part using s->hl now. */
+ enum draw_glyphs_face save = next->hl;
+
+ next->hl = s->hl;
+ gsif->set_gc (next);
+ gsif->set_clipping_exactly (s, next);
+ if (next->first_glyph->type == CHAR_GLYPH)
+ gsif->draw_foreground (next);
+ else
+ gsif->draw_composite_foreground (next);
+ gsif->reset_clipping (next);
+ next->hl = save;
+ next->clip_head = s->next;
+ }
+ }
+ }
+
+ /* Reset clipping. */
+ gsif->reset_clipping (s);
+}
/* EXPORT for RIF:
Erase the current text line from the nominal cursor position
@@ -33344,6 +33607,35 @@ baseline. The default value is 1. */);
underline_minimum_offset = 1;
DEFSYM (Qunderline_minimum_offset, "underline-minimum-offset");
+#ifdef HAVE_WINDOW_SYSTEM
+ DEFVAR_BOOL ("x-use-underline-position-properties",
+ x_use_underline_position_properties,
+ doc: /* Non-nil means make use of UNDERLINE_POSITION font properties.
+A value of nil means ignore them. If you encounter fonts with bogus
+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. */);
+# ifdef HAVE_X_WINDOWS
+ x_use_underline_position_properties = true;
+# else
+ /* Other terms don't support this (yet?). */
+ x_use_underline_position_properties = false;
+# endif
+ DEFSYM (Qx_use_underline_position_properties,
+ "x-use-underline-position-properties");
+
+ DEFVAR_BOOL ("x-underline-at-descent-line",
+ x_underline_at_descent_line,
+ doc: /* Non-nil means to draw the underline at the same place as the descent line.
+(If `line-spacing' is in effect, that moves the underline lower by
+that many pixels.)
+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");
+#endif
+
DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
This feature only works when on a window system that can change
diff --git a/src/xterm.c b/src/xterm.c
index b08f5f6a62..5fe4491f7e 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1626,6 +1626,12 @@ x_set_glyph_string_clipping_exactly (struct glyph_string *src, struct glyph_stri
x_set_clip_rectangles (dst->f, dst->gc, &r, 1);
}
+static void
+x_reset_glyph_string_clipping (struct glyph_string *s)
+{
+ x_reset_clip_rectangles (s->f, s->gc);
+ s->num_clips = 0;
+}
/* RIF:
Compute left and right overhang of glyph string S. */
@@ -3468,7 +3474,7 @@ x_get_scale_factor(Display *disp, int *scale_x, int *scale_y)
*/
static void
-x_draw_underwave (struct glyph_string *s)
+x_draw_underwave_1 (struct glyph_string *s)
{
/* Adjust for scale/HiDPI. */
int scale_x, scale_y;
@@ -3535,319 +3541,73 @@ x_draw_underwave (struct glyph_string *s)
#endif /* not USE_CAIRO */
}
-
-/* Draw glyph string S. */
-
static void
-x_draw_glyph_string (struct glyph_string *s)
+x_draw_underwave (struct glyph_string *s)
{
- bool relief_drawn_p = false;
-
- /* If S draws into the background of its successors, draw the
- background of the successors first so that S can draw into it.
- This makes S->next use XDrawString instead of XDrawImageString. */
- if (s->next && s->right_overhang && !s->for_overlaps)
+ if (s->face->underline_defaulted_p)
+ x_draw_underwave_1 (s);
+ else
{
- int width;
- struct glyph_string *next;
-
- for (width = 0, next = s->next;
- next && width < s->right_overhang;
- width += next->width, next = next->next)
- if (next->first_glyph->type != IMAGE_GLYPH)
- {
- x_set_glyph_string_gc (next);
- x_set_glyph_string_clipping (next);
- if (next->first_glyph->type == STRETCH_GLYPH)
- x_draw_stretch_glyph_string (next);
- else
- x_draw_glyph_string_background (next, true);
- next->num_clips = 0;
- }
+ XGCValues xgcv;
+ XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
+ XSetForeground (s->display, s->gc, s->face->underline_color);
+ x_draw_underwave_1 (s);
+ XSetForeground (s->display, s->gc, xgcv.foreground);
}
+}
- /* Set up S->gc, set clipping and draw S. */
- x_set_glyph_string_gc (s);
-
- /* Draw relief (if any) in advance for char/composition so that the
- glyph string can be drawn over it. */
- if (!s->for_overlaps
- && s->face->box != FACE_NO_BOX
- && (s->first_glyph->type == CHAR_GLYPH
- || s->first_glyph->type == COMPOSITE_GLYPH))
+static void
+x_draw_underline (struct glyph_string *s)
+{
+ const int y = s->ybase + s->underline_position;
+ const int thickness = s->underline_thickness;
- {
- x_set_glyph_string_clipping (s);
- x_draw_glyph_string_background (s, true);
- x_draw_glyph_string_box (s);
- x_set_glyph_string_clipping (s);
- relief_drawn_p = true;
- }
- else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
- && !s->clip_tail
- && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
- || (s->next && s->next->hl != s->hl && s->right_overhang)))
- /* We must clip just this glyph. left_overhang part has already
- drawn when s->prev was drawn, and right_overhang part will be
- drawn later when s->next is drawn. */
- x_set_glyph_string_clipping_exactly (s, s);
+ if (s->face->underline_defaulted_p)
+ x_fill_rectangle (s->f, s->gc,
+ s->x, y, s->width, thickness);
else
- x_set_glyph_string_clipping (s);
-
- switch (s->first_glyph->type)
{
- case IMAGE_GLYPH:
- x_draw_image_glyph_string (s);
- break;
-
- case XWIDGET_GLYPH:
- x_draw_xwidget_glyph_string (s);
- break;
-
- case STRETCH_GLYPH:
- x_draw_stretch_glyph_string (s);
- break;
-
- case CHAR_GLYPH:
- if (s->for_overlaps)
- s->background_filled_p = true;
- else
- x_draw_glyph_string_background (s, false);
- x_draw_glyph_string_foreground (s);
- break;
-
- case COMPOSITE_GLYPH:
- if (s->for_overlaps || (s->cmp_from > 0
- && ! s->first_glyph->u.cmp.automatic))
- s->background_filled_p = true;
- else
- x_draw_glyph_string_background (s, true);
- x_draw_composite_glyph_string_foreground (s);
- break;
+ XGCValues xgcv;
+ XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
+ XSetForeground (s->display, s->gc, s->face->underline_color);
+ x_fill_rectangle (s->f, s->gc,
+ s->x, y, s->width, thickness);
+ XSetForeground (s->display, s->gc, xgcv.foreground);
+ }
+}
- case GLYPHLESS_GLYPH:
- if (s->for_overlaps)
- s->background_filled_p = true;
- else
- x_draw_glyph_string_background (s, true);
- x_draw_glyphless_glyph_string_foreground (s);
- break;
+static void
+x_draw_overline (struct glyph_string *s)
+{
+ unsigned long dy = 0, h = 1;
- default:
- emacs_abort ();
+ if (s->face->overline_color_defaulted_p)
+ x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
+ s->width, h);
+ else
+ {
+ XGCValues xgcv;
+ XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
+ XSetForeground (s->display, s->gc, s->face->overline_color);
+ x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
+ s->width, h);
+ XSetForeground (s->display, s->gc, xgcv.foreground);
}
+}
- if (!s->for_overlaps)
+static void
+x_draw_strike_through (struct glyph_string *s, int y, int height)
+{
+ if (s->face->strike_through_color_defaulted_p)
+ x_fill_rectangle (s->f, s->gc, s->x, y, s->width, height);
+ else
{
- /* Draw underline. */
- if (s->face->underline_p)
- {
- if (s->face->underline_type == FACE_UNDER_WAVE)
- {
- if (s->face->underline_defaulted_p)
- x_draw_underwave (s);
- else
- {
- XGCValues xgcv;
- XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
- XSetForeground (s->display, s->gc, s->face->underline_color);
- x_draw_underwave (s);
- XSetForeground (s->display, s->gc, xgcv.foreground);
- }
- }
- else if (s->face->underline_type == FACE_UNDER_LINE)
- {
- unsigned long thickness, position;
- int y;
-
- if (s->prev && s->prev->face->underline_p
- && s->prev->face->underline_type == FACE_UNDER_LINE)
- {
- /* We use the same underline style as the previous one. */
- thickness = s->prev->underline_thickness;
- position = s->prev->underline_position;
- }
- 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 (FIXNUMP (val))
- minimum_offset = XFIXNAT (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 (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
- specs, and its default is
-
- ROUND ((maximum descent) / 2), with
- ROUND(x) = floor (x + 0.5) */
-
- if (use_underline_position_properties
- && font && font->underline_position >= 0)
- position = font->underline_position;
- else if (font)
- position = (font->descent + 1) / 2;
- else
- position = 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. */
- if (s->y + s->height <= s->ybase + position)
- position = (s->height - 1) - (s->ybase - s->y);
- if (s->y + s->height < s->ybase + position + thickness)
- thickness = (s->y + s->height) - (s->ybase + position);
- s->underline_thickness = thickness;
- s->underline_position = position;
- y = s->ybase + position;
- if (s->face->underline_defaulted_p)
- x_fill_rectangle (s->f, s->gc,
- s->x, y, s->width, thickness);
- else
- {
- XGCValues xgcv;
- XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
- XSetForeground (s->display, s->gc, s->face->underline_color);
- x_fill_rectangle (s->f, s->gc,
- s->x, y, s->width, thickness);
- XSetForeground (s->display, s->gc, xgcv.foreground);
- }
- }
- }
- /* Draw overline. */
- if (s->face->overline_p)
- {
- unsigned long dy = 0, h = 1;
-
- if (s->face->overline_color_defaulted_p)
- x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
- s->width, h);
- else
- {
- XGCValues xgcv;
- XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
- XSetForeground (s->display, s->gc, s->face->overline_color);
- x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
- s->width, h);
- XSetForeground (s->display, s->gc, xgcv.foreground);
- }
- }
-
- /* Draw strike-through. */
- if (s->face->strike_through_p)
- {
- /* Y-coordinate and height of the glyph string's first
- glyph. We cannot use s->y and s->height because those
- could be larger if there are taller display elements
- (e.g., characters displayed with a larger font) in the
- same glyph row. */
- int glyph_y = s->ybase - s->first_glyph->ascent;
- int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
- /* Strike-through width and offset from the glyph string's
- top edge. */
- unsigned long h = 1;
- unsigned long dy = (glyph_height - h) / 2;
-
- if (s->face->strike_through_color_defaulted_p)
- x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
- s->width, h);
- else
- {
- XGCValues xgcv;
- XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
- XSetForeground (s->display, s->gc, s->face->strike_through_color);
- x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
- s->width, h);
- XSetForeground (s->display, s->gc, xgcv.foreground);
- }
- }
-
- /* Draw relief if not yet drawn. */
- if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
- x_draw_glyph_string_box (s);
-
- if (s->prev)
- {
- struct glyph_string *prev;
-
- for (prev = s->prev; prev; prev = prev->prev)
- if (prev->hl != s->hl
- && prev->x + prev->width + prev->right_overhang > s->x)
- {
- /* As prev was drawn while clipped to its own area, we
- must draw the right_overhang part using s->hl now. */
- enum draw_glyphs_face save = prev->hl;
-
- prev->hl = s->hl;
- x_set_glyph_string_gc (prev);
- x_set_glyph_string_clipping_exactly (s, prev);
- if (prev->first_glyph->type == CHAR_GLYPH)
- x_draw_glyph_string_foreground (prev);
- else
- x_draw_composite_glyph_string_foreground (prev);
- x_reset_clip_rectangles (prev->f, prev->gc);
- prev->hl = save;
- prev->num_clips = 0;
- }
- }
-
- if (s->next)
- {
- struct glyph_string *next;
-
- for (next = s->next; next; next = next->next)
- if (next->hl != s->hl
- && next->x - next->left_overhang < s->x + s->width)
- {
- /* As next will be drawn while clipped to its own area,
- we must draw the left_overhang part using s->hl now. */
- enum draw_glyphs_face save = next->hl;
-
- next->hl = s->hl;
- x_set_glyph_string_gc (next);
- x_set_glyph_string_clipping_exactly (s, next);
- if (next->first_glyph->type == CHAR_GLYPH)
- x_draw_glyph_string_foreground (next);
- else
- x_draw_composite_glyph_string_foreground (next);
- x_reset_clip_rectangles (next->f, next->gc);
- next->hl = save;
- next->num_clips = 0;
- next->clip_head = s->next;
- }
- }
+ XGCValues xgcv;
+ XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
+ XSetForeground (s->display, s->gc, s->face->strike_through_color);
+ x_fill_rectangle (s->f, s->gc, s->x, y, s->width, height);
+ XSetForeground (s->display, s->gc, xgcv.foreground);
}
-
- /* Reset clipping. */
- x_reset_clip_rectangles (s->f, s->gc);
- s->num_clips = 0;
}
/* Shift display to make room for inserted glyphs. */
@@ -13060,6 +12820,26 @@ x_activate_timeout_atimer (void)
extern frame_parm_handler x_frame_parm_handlers[];
+static struct draw_glyph_string_interface x_draw_glyph_string_interface =
+ {
+ x_set_glyph_string_gc,
+ x_set_glyph_string_clipping,
+ x_set_glyph_string_clipping_exactly,
+ x_reset_glyph_string_clipping,
+ x_draw_glyph_string_background,
+ x_draw_glyph_string_foreground,
+ x_draw_glyph_string_box,
+ x_draw_image_glyph_string,
+ x_draw_stretch_glyph_string,
+ x_draw_xwidget_glyph_string,
+ x_draw_composite_glyph_string_foreground,
+ x_draw_glyphless_glyph_string_foreground,
+ x_draw_underwave,
+ x_draw_underline,
+ x_draw_overline,
+ x_draw_strike_through
+ };
+
static struct redisplay_interface x_redisplay_interface =
{
x_frame_parm_handlers,
@@ -13084,7 +12864,8 @@ static struct redisplay_interface x_redisplay_interface =
0, /* destroy_fringe_bitmap */
#endif
x_compute_glyph_string_overhangs,
- x_draw_glyph_string,
+ gui_draw_glyph_string,
+ &x_draw_glyph_string_interface,
x_define_frame_cursor,
x_clear_frame_area,
x_clear_under_internal_border,
@@ -13327,28 +13108,6 @@ syms_of_xterm (void)
DEFSYM (Qx_gtk_map_stock, "x-gtk-map-stock");
#endif
- DEFVAR_BOOL ("x-use-underline-position-properties",
- x_use_underline_position_properties,
- doc: /* Non-nil means make use of UNDERLINE_POSITION font properties.
-A value of nil means ignore them. If you encounter fonts with bogus
-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,
- doc: /* Non-nil means to draw the underline at the same place as the descent line.
-(If `line-spacing' is in effect, that moves the underline lower by
-that many pixels.)
-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,
doc: /* Non-nil means that a mouse click to focus a frame does not move point.
--
2.21.0
next reply other threads:[~2019-04-28 1:29 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-28 1:29 Alex Gramiak [this message]
2019-04-28 17:11 ` bug#35468: [PATCH] Refactor draw_glyph_string on X and w32 Eli Zaretskii
2019-04-28 19:46 ` Alex Gramiak
2019-04-29 17:43 ` Alex Gramiak
2019-04-30 4:59 ` Eli Zaretskii
2019-04-30 18:00 ` Alex Gramiak
2019-05-01 0:14 ` mituharu
2019-05-03 19:01 ` Alex Gramiak
2019-05-03 21:33 ` mituharu
2019-05-04 4:00 ` mituharu
2019-05-01 18:19 ` Eli Zaretskii
2019-05-02 19:41 ` Alex Gramiak
2019-05-02 20:14 ` Eli Zaretskii
2019-05-03 15:26 ` Basil L. Contovounesios
2019-05-04 8:17 ` Eli Zaretskii
2019-05-04 19:29 ` Alex Gramiak
2019-05-05 0:10 ` mituharu
2019-05-05 16:00 ` Eli Zaretskii
2019-05-05 2:34 ` Eli Zaretskii
2019-04-30 20:11 ` Alan Third
2019-05-01 17:38 ` Eli Zaretskii
2019-05-01 21:08 ` Alan Third
2019-05-02 18:14 ` Alex Gramiak
2019-05-03 21:12 ` Alan Third
2021-05-12 14:43 ` Lars Ingebrigtsen
2021-07-22 12:55 ` Lars Ingebrigtsen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=877ebeor2d.fsf@gmail.com \
--to=agrambot@gmail.com \
--cc=35468@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).