From a625ec9510f4c44af5d81265e8e971efe5c2907d Mon Sep 17 00:00:00 2001 From: Po Lu Date: Thu, 2 May 2024 16:56:26 +0800 Subject: [PATCH] Fix display of stipples on NS with respect to cursor highlight * src/nsfont.m (nsfont_draw): Delete redundant code. * src/nsterm.m (ns_maybe_dumpglyphs_background): Conform logic to X version by always displaying the background if s->stipple_p should be set. (ns_draw_stretch_glyph_string): Set stipple background as appropriate. (ns_set_glyph_string_gc): New function. (ns_draw_glyph_string): Call it, as on X. Reported by Arash Esbati . (cherry picked from commit ef6ffbdc79645e719d3b5ef23c9200405c58c61e) --- src/nsfont.m | 19 +++------ src/nsterm.m | 115 ++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 86 insertions(+), 48 deletions(-) diff --git a/src/nsfont.m b/src/nsfont.m index 4e1d85a5c4a..e1b1b097c17 100644 --- a/src/nsfont.m +++ b/src/nsfont.m @@ -1180,21 +1180,12 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y, { NSRect br = NSMakeRect (x, y - FONT_BASE (s->font), s->width, FONT_HEIGHT (s->font)); - - if (!s->face->stipple) - { - if (s->hl != DRAW_CURSOR) - [(NS_FACE_BACKGROUND (face) != 0 - ? [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] - : FRAME_BACKGROUND_COLOR (s->f)) set]; - else - [FRAME_CURSOR_COLOR (s->f) set]; - } + if (s->hl != DRAW_CURSOR) + [(NS_FACE_BACKGROUND (face) != 0 + ? [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] + : FRAME_BACKGROUND_COLOR (s->f)) set]; else - { - struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f); - [[dpyinfo->bitmaps[face->stipple-1].img stippleMask] set]; - } + [FRAME_CURSOR_COLOR (s->f) set]; NSRectFill (br); } diff --git a/src/nsterm.m b/src/nsterm.m index 71fa6e22164..f26cdb17903 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3808,7 +3808,6 @@ ns_dumpglyphs_box_or_relief (struct glyph_string *s) } } - static void ns_maybe_dumpglyphs_background (struct glyph_string *s, char force_p) /* -------------------------------------------------------------------------- @@ -3816,45 +3815,47 @@ ns_maybe_dumpglyphs_background (struct glyph_string *s, char force_p) certain cases. Others are left to the text rendering routine. -------------------------------------------------------------------------- */ { + struct face *face = s->face; + NSRect r; + NSTRACE ("ns_maybe_dumpglyphs_background"); - if (!s->background_filled_p/* || s->hl == DRAW_MOUSE_FACE*/) + if (!s->background_filled_p) { int box_line_width = max (s->face->box_horizontal_line_width, 0); - if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width - /* When xdisp.c ignores FONT_HEIGHT, we cannot trust font - dimensions, since the actual glyphs might be much - smaller. So in that case we always clear the rectangle - with background color. */ - || FONT_TOO_HIGH (s->font) - || s->font_not_found_p || s->extends_to_end_of_line_p || force_p) + if (s->stippled_p) { - struct face *face = s->face; - if (!face->stipple) - { - if (s->hl != DRAW_CURSOR) - [(NS_FACE_BACKGROUND (face) != 0 - ? [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] - : FRAME_BACKGROUND_COLOR (s->f)) set]; - else if (face && (NS_FACE_BACKGROUND (face) - == [(NSColor *) FRAME_CURSOR_COLOR (s->f) - unsignedLong])) - [[NSColor colorWithUnsignedLong:NS_FACE_FOREGROUND (face)] set]; - else - [FRAME_CURSOR_COLOR (s->f) set]; - } - else - { - struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f); - [[dpyinfo->bitmaps[face->stipple-1].img stippleMask] set]; - } + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f); + [[dpyinfo->bitmaps[face->stipple-1].img stippleMask] set]; + goto fill; + } + else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width + /* When xdisp.c ignores FONT_HEIGHT, we cannot trust font + dimensions, since the actual glyphs might be much + smaller. So in that case we always clear the + rectangle with background color. */ + || FONT_TOO_HIGH (s->font) + || s->font_not_found_p + || s->extends_to_end_of_line_p + || force_p) + { + if (s->hl != DRAW_CURSOR) + [(NS_FACE_BACKGROUND (face) != 0 + ? [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] + : FRAME_BACKGROUND_COLOR (s->f)) set]; + else if (face && (NS_FACE_BACKGROUND (face) + == [(NSColor *) FRAME_CURSOR_COLOR (s->f) + unsignedLong])) + [[NSColor colorWithUnsignedLong:NS_FACE_FOREGROUND (face)] set]; + else + [FRAME_CURSOR_COLOR (s->f) set]; - NSRect r = NSMakeRect (s->x, s->y + box_line_width, - s->background_width, - s->height - 2 * box_line_width); + fill: + r = NSMakeRect (s->x, s->y + box_line_width, + s->background_width, + s->height - 2 * box_line_width); NSRectFill (r); - s->background_filled_p = 1; } } @@ -4083,8 +4084,7 @@ ns_draw_stretch_glyph_string (struct glyph_string *s) struct face *face; NSColor *fg_color; - if (s->hl == DRAW_CURSOR - && !x_stretch_cursor_p) + if (s->hl == DRAW_CURSOR && !x_stretch_cursor_p) { /* If `x-stretch-cursor' is nil, don't draw a block cursor as wide as the stretch glyph. */ @@ -4170,8 +4170,13 @@ ns_draw_stretch_glyph_string (struct glyph_string *s) if (background_width > 0) { + struct ns_display_info *dpyinfo; + + dpyinfo = FRAME_DISPLAY_INFO (s->f); if (s->hl == DRAW_CURSOR) [FRAME_CURSOR_COLOR (s->f) set]; + else if (s->stippled_p) + [[dpyinfo->bitmaps[s->face->stipple - 1].img stippleMask] set]; else [[NSColor colorWithUnsignedLong: s->face->background] set]; @@ -4389,6 +4394,45 @@ ns_draw_glyphless_glyph_string_foreground (struct glyph_string *s) s->char2b = NULL; } +/* Transfer glyph string parameters from S's face to S itself. + Set S->stipple_p as appropriate, taking the draw type into + account. */ + +static void +ns_set_glyph_string_gc (struct glyph_string *s) +{ + prepare_face_for_display (s->f, s->face); + + if (s->hl == DRAW_NORMAL_TEXT) + { + /* s->gc = s->face->gc; */ + s->stippled_p = s->face->stipple != 0; + } + else if (s->hl == DRAW_INVERSE_VIDEO) + { + /* x_set_mode_line_face_gc (s); */ + s->stippled_p = s->face->stipple != 0; + } + else if (s->hl == DRAW_CURSOR) + { + /* x_set_cursor_gc (s); */ + s->stippled_p = false; + } + else if (s->hl == DRAW_MOUSE_FACE) + { + /* x_set_mouse_face_gc (s); */ + s->stippled_p = s->face->stipple != 0; + } + else if (s->hl == DRAW_IMAGE_RAISED + || s->hl == DRAW_IMAGE_SUNKEN) + { + /* s->gc = s->face->gc; */ + s->stippled_p = s->face->stipple != 0; + } + else + emacs_abort (); +} + static void ns_draw_glyph_string (struct glyph_string *s) /* -------------------------------------------------------------------------- @@ -4414,6 +4458,7 @@ ns_draw_glyph_string (struct glyph_string *s) width += next->width, next = next->next) if (next->first_glyph->type != IMAGE_GLYPH) { + ns_set_glyph_string_gc (next); n = ns_get_glyph_string_clip_rect (s->next, r); ns_focus (s->f, r, n); if (next->first_glyph->type != STRETCH_GLYPH) @@ -4425,6 +4470,8 @@ ns_draw_glyph_string (struct glyph_string *s) } } + ns_set_glyph_string_gc (s); + if (!s->for_overlaps && s->face->box != FACE_NO_BOX && (s->first_glyph->type == CHAR_GLYPH || s->first_glyph->type == COMPOSITE_GLYPH)) -- 2.39.5