aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-09-26 09:30:04 +0800
committerPo Lu2023-09-26 09:30:04 +0800
commit50281b4007062533ca18f98deeac6b7d923d1922 (patch)
tree6197c28acbff0a1d340c3ab5a46281b895caf8b0 /src
parent50e913c956924fe7b6799ed1d42e02a707b83eb6 (diff)
downloademacs-50281b4007062533ca18f98deeac6b7d923d1922.tar.gz
emacs-50281b4007062533ca18f98deeac6b7d923d1922.zip
Properly clip overlaid fringe bitmaps
* src/xterm.c (x_draw_fringe_bitmap): Save clip rectangle from x_clip_to_row, and draw only the intersection between it and the fringe bitmap, for if the bitmap is overlaid, the clip mask will override the clip rectangle. (x_clip_to_row): New argument *RECT_RETURN. All callers changed.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/src/xterm.c b/src/xterm.c
index bd779cb21bf..33e12d48912 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1167,7 +1167,7 @@ static struct terminal *x_create_terminal (struct x_display_info *);
1167static void x_frame_rehighlight (struct x_display_info *); 1167static void x_frame_rehighlight (struct x_display_info *);
1168 1168
1169static void x_clip_to_row (struct window *, struct glyph_row *, 1169static void x_clip_to_row (struct window *, struct glyph_row *,
1170 enum glyph_row_area, GC); 1170 enum glyph_row_area, GC, XRectangle *);
1171static struct scroll_bar *x_window_to_scroll_bar (Display *, Window, int); 1171static struct scroll_bar *x_window_to_scroll_bar (Display *, Window, int);
1172static struct frame *x_window_to_frame (struct x_display_info *, int); 1172static struct frame *x_window_to_frame (struct x_display_info *, int);
1173static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, 1173static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
@@ -7842,9 +7842,10 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
7842 Display *display = FRAME_X_DISPLAY (f); 7842 Display *display = FRAME_X_DISPLAY (f);
7843 GC gc = f->output_data.x->normal_gc; 7843 GC gc = f->output_data.x->normal_gc;
7844 struct face *face = p->face; 7844 struct face *face = p->face;
7845 XRectangle clip_rect;
7845 7846
7846 /* Must clip because of partially visible lines. */ 7847 /* Must clip because of partially visible lines. */
7847 x_clip_to_row (w, row, ANY_AREA, gc); 7848 x_clip_to_row (w, row, ANY_AREA, gc, &clip_rect);
7848 7849
7849 if (p->bx >= 0 && !p->overlay_p) 7850 if (p->bx >= 0 && !p->overlay_p)
7850 { 7851 {
@@ -7914,6 +7915,30 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
7914 7915
7915 memset (&attrs, 0, sizeof attrs); 7916 memset (&attrs, 0, sizeof attrs);
7916#endif 7917#endif
7918 XRectangle image_rect, dest;
7919 int window_x, window_y, window_width;
7920 int px, py, pwidth, pheight;
7921
7922 /* Intersect the destination rectangle with that of the row.
7923 Setting a clip mask overrides the clip rectangles provided by
7924 x_clip_to_row, so clipping must be performed by hand. */
7925
7926 image_rect.x = p->x;
7927 image_rect.y = p->y;
7928 image_rect.width = p->wd;
7929 image_rect.height = p->h;
7930
7931 if (!gui_intersect_rectangles (&clip_rect, &image_rect, &dest))
7932 /* The entire destination rectangle falls outside the row. */
7933 goto undo_clip;
7934
7935 /* Extrapolate the source rectangle from the difference between
7936 the destination and image rectangles. */
7937
7938 px = dest.x - image_rect.x;
7939 py = dest.y - image_rect.y;
7940 pwidth = dest.width;
7941 pheight = dest.height;
7917 7942
7918 if (p->wd > 8) 7943 if (p->wd > 8)
7919 bits = (char *) (p->bits + p->dh); 7944 bits = (char *) (p->bits + p->dh);
@@ -7985,15 +8010,16 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
7985 x_xr_apply_ext_clip (f, gc); 8010 x_xr_apply_ext_clip (f, gc);
7986 XRenderComposite (display, PictOpSrc, picture, 8011 XRenderComposite (display, PictOpSrc, picture,
7987 None, FRAME_X_PICTURE (f), 8012 None, FRAME_X_PICTURE (f),
7988 0, 0, 0, 0, p->x, p->y, p->wd, p->h); 8013 px, py, px, py, dest.x, dest.y,
8014 pwidth, pheight);
7989 x_xr_reset_ext_clip (f); 8015 x_xr_reset_ext_clip (f);
7990 8016
7991 XRenderFreePicture (display, picture); 8017 XRenderFreePicture (display, picture);
7992 } 8018 }
7993 else 8019 else
7994#endif 8020#endif
7995 XCopyArea (display, pixmap, drawable, gc, 0, 0, 8021 XCopyArea (display, pixmap, drawable, gc, px, py,
7996 p->wd, p->h, p->x, p->y); 8022 pwidth, pheight, dest.x, dest.y);
7997 XFreePixmap (display, pixmap); 8023 XFreePixmap (display, pixmap);
7998 8024
7999 if (p->overlay_p) 8025 if (p->overlay_p)
@@ -8003,6 +8029,8 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
8003 XFreePixmap (display, clipmask); 8029 XFreePixmap (display, clipmask);
8004 } 8030 }
8005 } 8031 }
8032
8033 undo_clip:
8006#endif /* not USE_CAIRO */ 8034#endif /* not USE_CAIRO */
8007 8035
8008 x_reset_clip_rectangles (f, gc); 8036 x_reset_clip_rectangles (f, gc);
@@ -25646,13 +25674,17 @@ XTread_socket (struct terminal *terminal, struct input_event *hold_quit)
25646/* Set clipping for output in glyph row ROW. W is the window in which 25674/* Set clipping for output in glyph row ROW. W is the window in which
25647 we operate. GC is the graphics context to set clipping in. 25675 we operate. GC is the graphics context to set clipping in.
25648 25676
25677 If RECT_RETURN is non-NULL, return the clip rectangle within
25678 *RECT_RETURN.
25679
25649 ROW may be a text row or, e.g., a mode line. Text rows must be 25680 ROW may be a text row or, e.g., a mode line. Text rows must be
25650 clipped to the interior of the window dedicated to text display, 25681 clipped to the interior of the window dedicated to text display,
25651 mode lines must be clipped to the whole window. */ 25682 mode lines must be clipped to the whole window. */
25652 25683
25653static void 25684static void
25654x_clip_to_row (struct window *w, struct glyph_row *row, 25685x_clip_to_row (struct window *w, struct glyph_row *row,
25655 enum glyph_row_area area, GC gc) 25686 enum glyph_row_area area, GC gc,
25687 XRectangle *rect_return)
25656{ 25688{
25657 struct frame *f = XFRAME (WINDOW_FRAME (w)); 25689 struct frame *f = XFRAME (WINDOW_FRAME (w));
25658 XRectangle clip_rect; 25690 XRectangle clip_rect;
@@ -25667,6 +25699,9 @@ x_clip_to_row (struct window *w, struct glyph_row *row,
25667 clip_rect.height = row->visible_height; 25699 clip_rect.height = row->visible_height;
25668 25700
25669 x_set_clip_rectangles (f, gc, &clip_rect, 1); 25701 x_set_clip_rectangles (f, gc, &clip_rect, 1);
25702
25703 if (rect_return)
25704 *rect_return = clip_rect;
25670} 25705}
25671 25706
25672 25707
@@ -25715,7 +25750,7 @@ x_draw_hollow_cursor (struct window *w, struct glyph_row *row)
25715 wd -= 1; 25750 wd -= 1;
25716 } 25751 }
25717 /* Set clipping, draw the rectangle, and reset clipping again. */ 25752 /* Set clipping, draw the rectangle, and reset clipping again. */
25718 x_clip_to_row (w, row, TEXT_AREA, gc); 25753 x_clip_to_row (w, row, TEXT_AREA, gc, NULL);
25719 x_draw_rectangle (f, gc, x, y, wd, h - 1); 25754 x_draw_rectangle (f, gc, x, y, wd, h - 1);
25720 x_reset_clip_rectangles (f, gc); 25755 x_reset_clip_rectangles (f, gc);
25721} 25756}
@@ -25785,7 +25820,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
25785 FRAME_DISPLAY_INFO (f)->scratch_cursor_gc = gc; 25820 FRAME_DISPLAY_INFO (f)->scratch_cursor_gc = gc;
25786 } 25821 }
25787 25822
25788 x_clip_to_row (w, row, TEXT_AREA, gc); 25823 x_clip_to_row (w, row, TEXT_AREA, gc, NULL);
25789 25824
25790 if (kind == BAR_CURSOR) 25825 if (kind == BAR_CURSOR)
25791 { 25826 {