mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-29 07:58:28 +00:00
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.
This commit is contained in:
parent
50e913c956
commit
50281b4007
51
src/xterm.c
51
src/xterm.c
@ -1167,7 +1167,7 @@ static struct terminal *x_create_terminal (struct x_display_info *);
|
||||
static void x_frame_rehighlight (struct x_display_info *);
|
||||
|
||||
static void x_clip_to_row (struct window *, struct glyph_row *,
|
||||
enum glyph_row_area, GC);
|
||||
enum glyph_row_area, GC, XRectangle *);
|
||||
static struct scroll_bar *x_window_to_scroll_bar (Display *, Window, int);
|
||||
static struct frame *x_window_to_frame (struct x_display_info *, int);
|
||||
static 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,
|
||||
Display *display = FRAME_X_DISPLAY (f);
|
||||
GC gc = f->output_data.x->normal_gc;
|
||||
struct face *face = p->face;
|
||||
XRectangle clip_rect;
|
||||
|
||||
/* Must clip because of partially visible lines. */
|
||||
x_clip_to_row (w, row, ANY_AREA, gc);
|
||||
x_clip_to_row (w, row, ANY_AREA, gc, &clip_rect);
|
||||
|
||||
if (p->bx >= 0 && !p->overlay_p)
|
||||
{
|
||||
@ -7914,6 +7915,30 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
|
||||
|
||||
memset (&attrs, 0, sizeof attrs);
|
||||
#endif
|
||||
XRectangle image_rect, dest;
|
||||
int window_x, window_y, window_width;
|
||||
int px, py, pwidth, pheight;
|
||||
|
||||
/* Intersect the destination rectangle with that of the row.
|
||||
Setting a clip mask overrides the clip rectangles provided by
|
||||
x_clip_to_row, so clipping must be performed by hand. */
|
||||
|
||||
image_rect.x = p->x;
|
||||
image_rect.y = p->y;
|
||||
image_rect.width = p->wd;
|
||||
image_rect.height = p->h;
|
||||
|
||||
if (!gui_intersect_rectangles (&clip_rect, &image_rect, &dest))
|
||||
/* The entire destination rectangle falls outside the row. */
|
||||
goto undo_clip;
|
||||
|
||||
/* Extrapolate the source rectangle from the difference between
|
||||
the destination and image rectangles. */
|
||||
|
||||
px = dest.x - image_rect.x;
|
||||
py = dest.y - image_rect.y;
|
||||
pwidth = dest.width;
|
||||
pheight = dest.height;
|
||||
|
||||
if (p->wd > 8)
|
||||
bits = (char *) (p->bits + p->dh);
|
||||
@ -7985,15 +8010,16 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
|
||||
x_xr_apply_ext_clip (f, gc);
|
||||
XRenderComposite (display, PictOpSrc, picture,
|
||||
None, FRAME_X_PICTURE (f),
|
||||
0, 0, 0, 0, p->x, p->y, p->wd, p->h);
|
||||
px, py, px, py, dest.x, dest.y,
|
||||
pwidth, pheight);
|
||||
x_xr_reset_ext_clip (f);
|
||||
|
||||
XRenderFreePicture (display, picture);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
XCopyArea (display, pixmap, drawable, gc, 0, 0,
|
||||
p->wd, p->h, p->x, p->y);
|
||||
XCopyArea (display, pixmap, drawable, gc, px, py,
|
||||
pwidth, pheight, dest.x, dest.y);
|
||||
XFreePixmap (display, pixmap);
|
||||
|
||||
if (p->overlay_p)
|
||||
@ -8003,6 +8029,8 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
|
||||
XFreePixmap (display, clipmask);
|
||||
}
|
||||
}
|
||||
|
||||
undo_clip:
|
||||
#endif /* not USE_CAIRO */
|
||||
|
||||
x_reset_clip_rectangles (f, gc);
|
||||
@ -25646,13 +25674,17 @@ XTread_socket (struct terminal *terminal, struct input_event *hold_quit)
|
||||
/* Set clipping for output in glyph row ROW. W is the window in which
|
||||
we operate. GC is the graphics context to set clipping in.
|
||||
|
||||
If RECT_RETURN is non-NULL, return the clip rectangle within
|
||||
*RECT_RETURN.
|
||||
|
||||
ROW may be a text row or, e.g., a mode line. Text rows must be
|
||||
clipped to the interior of the window dedicated to text display,
|
||||
mode lines must be clipped to the whole window. */
|
||||
|
||||
static void
|
||||
x_clip_to_row (struct window *w, struct glyph_row *row,
|
||||
enum glyph_row_area area, GC gc)
|
||||
enum glyph_row_area area, GC gc,
|
||||
XRectangle *rect_return)
|
||||
{
|
||||
struct frame *f = XFRAME (WINDOW_FRAME (w));
|
||||
XRectangle clip_rect;
|
||||
@ -25667,6 +25699,9 @@ x_clip_to_row (struct window *w, struct glyph_row *row,
|
||||
clip_rect.height = row->visible_height;
|
||||
|
||||
x_set_clip_rectangles (f, gc, &clip_rect, 1);
|
||||
|
||||
if (rect_return)
|
||||
*rect_return = clip_rect;
|
||||
}
|
||||
|
||||
|
||||
@ -25715,7 +25750,7 @@ x_draw_hollow_cursor (struct window *w, struct glyph_row *row)
|
||||
wd -= 1;
|
||||
}
|
||||
/* Set clipping, draw the rectangle, and reset clipping again. */
|
||||
x_clip_to_row (w, row, TEXT_AREA, gc);
|
||||
x_clip_to_row (w, row, TEXT_AREA, gc, NULL);
|
||||
x_draw_rectangle (f, gc, x, y, wd, h - 1);
|
||||
x_reset_clip_rectangles (f, gc);
|
||||
}
|
||||
@ -25785,7 +25820,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
|
||||
FRAME_DISPLAY_INFO (f)->scratch_cursor_gc = gc;
|
||||
}
|
||||
|
||||
x_clip_to_row (w, row, TEXT_AREA, gc);
|
||||
x_clip_to_row (w, row, TEXT_AREA, gc, NULL);
|
||||
|
||||
if (kind == BAR_CURSOR)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user