1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-15 10:30:25 -08:00

Fix display of :box face when overlay strings are around

* src/xdisp.c (reset_box_start_end_flags): New function.
(handle_face_prop): Only set the start_of_box_run_p flag, don't
reset it.
(pop_it): Set the face_box_p flag, if the popped face requires
that, when continuing iteration over buffer text.
(get_next_display_element, next_element_from_display_vector): Only
set the end_of_box_run_p flag, never reset it here.
(set_iterator_to_next): Don't reset the start_of_box_run_p and
end_of_box_run_p flags here.  They are now reset as side effect of
PRODUCE_GLYPHS.
(append_space_for_newline): Restore the end_of_box_run_p flag
after PRODUCE_GLYPHS where we previously didn't reset it.
* src/dispextern.h (PRODUCE_GLYPHS): Call
reset_box_start_end_flags after producing glyphs.
(Bug#40124)
This commit is contained in:
Eli Zaretskii 2020-03-19 16:57:35 +02:00
parent 37d3c1618b
commit d98afc1019
2 changed files with 67 additions and 29 deletions

View file

@ -2782,7 +2782,8 @@ struct it
else \
produce_glyphs ((IT)); \
if ((IT)->glyph_row != NULL) \
inhibit_free_realized_faces = true; \
inhibit_free_realized_faces =true; \
reset_box_start_end_flags ((IT)); \
} while (false)
/* Bit-flags indicating what operation move_it_to should perform. */

View file

@ -1020,6 +1020,7 @@ static Lisp_Object calc_line_height_property (struct it *, Lisp_Object,
static void produce_special_glyphs (struct it *, enum display_element_type);
static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
static bool coords_in_mouse_face_p (struct window *, int, int);
static void reset_box_start_end_flags (struct it *);
@ -1435,6 +1436,29 @@ window_hscroll_limited (struct window *w, struct frame *f)
return window_hscroll;
}
/* Reset the box-face start and end flags in the iterator. This is
called after producing glyphs, such that we reset these flags only
after producing a glyph with the flag set. */
static void
reset_box_start_end_flags (struct it *it)
{
/* Don't reset if we've drawn the glyph in the display margins --
those don't count as "produced glyphs". */
if (it->area == TEXT_AREA
/* Don't reset if we displayed a fringe bitmap. */
&& !(it->what == IT_IMAGE && it->image_id < 0))
{
/* Don't reset if the face is not a box face: that might mean we
are iterating some overlay or display string, and the first
character to have the box face is yet to be seen, when we pop
the iterator stack. */
if (it->face_box_p)
it->start_of_box_run_p = false;
it->end_of_box_run_p = false;
}
}
/* Return true if position CHARPOS is visible in window W.
CHARPOS < 0 means return info about WINDOW_END position.
If visible, set *X and *Y to pixel coordinates of top left corner.
@ -4315,8 +4339,11 @@ handle_face_prop (struct it *it)
this is the start of a run of characters with box face,
i.e. this character has a shadow on the left side. */
it->face_id = new_face_id;
it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
&& (old_face == NULL || !old_face->box));
/* Don't reset the start_of_box_run_p flag, only set it if
needed. */
if (!(it->start_of_box_run_p && old_face && old_face->box))
it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
&& (old_face == NULL || !old_face->box));
it->face_box_p = new_face->box != FACE_NO_BOX;
}
@ -6457,7 +6484,16 @@ pop_it (struct it *it)
it->object = p->u.stretch.object;
break;
case GET_FROM_BUFFER:
it->object = it->w->contents;
{
struct face *face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
/* Restore the face_box_p flag, since it could have been
overwritten by the face of the object that we just finished
displaying. */
if (face)
it->face_box_p = face->box != FACE_NO_BOX;
it->object = it->w->contents;
}
break;
case GET_FROM_STRING:
{
@ -7586,9 +7622,8 @@ get_next_display_element (struct it *it)
/* If the box comes from face properties in a
display string, check faces in that string. */
int string_face_id = face_after_it_pos (it);
it->end_of_box_run_p
= (FACE_FROM_ID (it->f, string_face_id)->box
== FACE_NO_BOX);
if (FACE_FROM_ID (it->f, string_face_id)->box == FACE_NO_BOX)
it->end_of_box_run_p = true;
}
/* Otherwise, the box comes from the underlying face.
If this is the last string character displayed, check
@ -7657,9 +7692,9 @@ get_next_display_element (struct it *it)
CHARPOS (pos), 0,
&ignore, face_id,
false, 0);
it->end_of_box_run_p
= (FACE_FROM_ID (it->f, next_face_id)->box
== FACE_NO_BOX);
if (FACE_FROM_ID (it->f, next_face_id)->box
== FACE_NO_BOX)
it->end_of_box_run_p = true;
}
}
else if (CHARPOS (pos) >= ZV)
@ -7672,9 +7707,9 @@ get_next_display_element (struct it *it)
CHARPOS (pos)
+ TEXT_PROP_DISTANCE_LIMIT,
false, -1, 0);
it->end_of_box_run_p
= (FACE_FROM_ID (it->f, next_face_id)->box
== FACE_NO_BOX);
if (FACE_FROM_ID (it->f, next_face_id)->box
== FACE_NO_BOX)
it->end_of_box_run_p = true;
}
}
}
@ -7684,9 +7719,9 @@ get_next_display_element (struct it *it)
else if (it->method != GET_FROM_DISPLAY_VECTOR)
{
int face_id = face_after_it_pos (it);
it->end_of_box_run_p
= (face_id != it->face_id
&& FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
if (face_id != it->face_id
&& FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX)
it->end_of_box_run_p = true;
}
}
/* If we reached the end of the object we've been iterating (e.g., a
@ -7723,10 +7758,6 @@ get_next_display_element (struct it *it)
void
set_iterator_to_next (struct it *it, bool reseat_p)
{
/* Reset flags indicating start and end of a sequence of characters
with box. Reset them at the start of this function because
moving the iterator to a new position might set them. */
it->start_of_box_run_p = it->end_of_box_run_p = false;
switch (it->method)
{
@ -8138,9 +8169,9 @@ next_element_from_display_vector (struct it *it)
}
}
next_face = FACE_FROM_ID_OR_NULL (it->f, next_face_id);
it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
&& (!next_face
|| next_face->box == FACE_NO_BOX));
if (this_face && this_face->box != FACE_NO_BOX
&& (!next_face || next_face->box == FACE_NO_BOX))
it->end_of_box_run_p = true;
it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
}
else
@ -21485,6 +21516,8 @@ append_space_for_newline (struct it *it, bool default_face_p)
const int indicator_column =
fill_column_indicator_column (it, char_width);
int saved_end_of_box_run = it->end_of_box_run_p;
bool should_keep_end_of_box_run = false;
if (it->current_x == indicator_column)
{
@ -21507,14 +21540,18 @@ append_space_for_newline (struct it *it, bool default_face_p)
have the end_of_box_run_p flag set for it, so there's no
need for the appended newline glyph to have that flag
set. */
if (it->glyph_row->reversed_p
/* But if the appended newline glyph goes all the way to
the end of the row, there will be no stretch glyph,
so leave the box flag set. */
&& saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
it->end_of_box_run_p = false;
if (!(it->glyph_row->reversed_p
/* But if the appended newline glyph goes all the way to
the end of the row, there will be no stretch glyph,
so leave the box flag set. */
&& saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x))
should_keep_end_of_box_run = true;
}
PRODUCE_GLYPHS (it);
/* Restore the end_of_box_run_p flag which was reset by
PRODUCE_GLYPHS. */
if (should_keep_end_of_box_run)
it->end_of_box_run_p = saved_end_of_box_run;
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (it->f))
{