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:
parent
37d3c1618b
commit
d98afc1019
2 changed files with 67 additions and 29 deletions
|
|
@ -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. */
|
||||
|
|
|
|||
93
src/xdisp.c
93
src/xdisp.c
|
|
@ -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))
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue