From: Po Lu Date: Sun, 8 May 2022 12:48:42 +0000 (+0800) Subject: Disable scrolling optimizations when a stipple is present X-Git-Tag: emacs-29.0.90~1910^2~907 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=2f1410562ea36f1143c9d7b2e1341cef93ae1c19;p=emacs.git Disable scrolling optimizations when a stipple is present * src/dispextern.h (struct glyph_row): New field `stippled_p'. We cannot just use the contents of the glyph row, since it has to be set in `gui_clear_end_of_line' and is more convenient to set inside the various draw_glyph_string functions. * src/dispnew.c (scrolling_window): Disable if a row in the current matrix has the stipple_p flag set. * src/xdisp.c (gui_clear_end_of_line): * src/xterm.c (x_draw_image_glyph_string) (x_draw_stretch_glyph_string, x_draw_glyph_string): Set `stipple_p' if a stipple pattern was drawn. --- diff --git a/src/dispextern.h b/src/dispextern.h index e9b19a7f135..a7f478acdf8 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1075,6 +1075,9 @@ struct glyph_row right-to-left paragraph. */ bool_bf reversed_p : 1; + /* Whether or not a stipple was drawn in this row at some point. */ + bool_bf stipple_p : 1; + /* Continuation lines width at the start of the row. */ int continuation_lines_width; diff --git a/src/dispnew.c b/src/dispnew.c index 1dd64be4ead..c49c38cba86 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -4392,7 +4392,6 @@ add_row_entry (struct glyph_row *row) return entry; } - /* Try to reuse part of the current display of W by scrolling lines. HEADER_LINE_P means W has a header line. @@ -4438,6 +4437,14 @@ scrolling_window (struct window *w, int tab_line_p) struct glyph_row *d = MATRIX_ROW (desired_matrix, i); struct glyph_row *c = MATRIX_ROW (current_matrix, i); + /* If there is a row with a stipple currently on the glass, give + up. Stipples look different depending on where on the + display they are drawn, so scrolling the display will produce + incorrect results. */ + + if (c->stipple_p) + return 0; + if (c->enabled_p && d->enabled_p && !d->redraw_fringe_bitmaps_p @@ -4467,6 +4474,16 @@ scrolling_window (struct window *w, int tab_line_p) first_old = first_new = i; + while (i < current_matrix->nrows - 1) + { + /* If there is a stipple after the first change, give up as + well. */ + if (MATRIX_ROW (current_matrix, i)->stipple_p) + return 0; + + ++i; + } + /* Set last_new to the index + 1 of the row that reaches the bottom boundary in the desired matrix. Give up if we find a disabled row before we reach the bottom boundary. */ diff --git a/src/xdisp.c b/src/xdisp.c index 50efa50c55b..f09f209b2e3 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -32015,14 +32015,16 @@ gui_insert_glyphs (struct window *w, struct glyph_row *updated_row, void gui_clear_end_of_line (struct window *w, struct glyph_row *updated_row, - enum glyph_row_area updated_area, int to_x) + enum glyph_row_area updated_area, int to_x) { struct frame *f; int max_x, min_y, max_y; int from_x, from_y, to_y; + struct face *face; eassert (updated_row); f = XFRAME (w->frame); + face = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID); if (updated_row->full_width_p) max_x = (WINDOW_PIXEL_WIDTH (w) @@ -32074,6 +32076,9 @@ gui_clear_end_of_line (struct window *w, struct glyph_row *updated_row, block_input (); FRAME_RIF (f)->clear_frame_area (f, from_x, from_y, to_x - from_x, to_y - from_y); + + if (face && !updated_row->stipple_p) + updated_row->stipple_p = face->stipple; unblock_input (); } } diff --git a/src/xterm.c b/src/xterm.c index a7f0f3d7efa..fe9531bdb4e 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -8052,6 +8052,9 @@ x_draw_image_glyph_string (struct glyph_string *s) || s->img->pixmap == 0 || s->width != s->background_width) { + if (s->stippled_p) + s->row->stipple_p = true; + #ifndef USE_CAIRO if (s->img->mask) { @@ -8232,6 +8235,8 @@ x_draw_stretch_glyph_string (struct glyph_string *s) XSetFillStyle (display, gc, FillOpaqueStippled); x_fill_rectangle (s->f, gc, x, y, w, h, true); XSetFillStyle (display, gc, FillSolid); + + s->row->stipple_p = true; } else { @@ -8258,8 +8263,13 @@ x_draw_stretch_glyph_string (struct glyph_string *s) background_width -= text_left_x - x; x = text_left_x; } + + if (!s->row->stipple_p) + s->row->stipple_p = s->stippled_p; + if (background_width > 0) - x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height); + x_draw_glyph_string_bg_rect (s, x, s->y, + background_width, s->height); } s->background_filled_p = true; @@ -8708,6 +8718,14 @@ x_draw_glyph_string (struct glyph_string *s) /* Reset clipping. */ x_reset_clip_rectangles (s->f, s->gc); s->num_clips = 0; + + /* Set the stippled flag that tells redisplay whether or not a + stipple was actually draw. */ + + if (s->first_glyph->type != STRETCH_GLYPH + && s->first_glyph->type != IMAGE_GLYPH + && !s->row->stipple_p) + s->row->stipple_p = s->stippled_p; } /* Shift display to make room for inserted glyphs. */