diff options
| author | Eli Zaretskii | 2020-03-19 16:57:35 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2020-03-19 16:57:35 +0200 |
| commit | d98afc1019d9f177dd05042371dd8239b7901d47 (patch) | |
| tree | 3c388edab33bd6fc9c10b6f1d83230c7950308d3 /src | |
| parent | 37d3c1618b6cdf7efc90015fb2786aa30ef0de47 (diff) | |
| download | emacs-d98afc1019d9f177dd05042371dd8239b7901d47.tar.gz emacs-d98afc1019d9f177dd05042371dd8239b7901d47.zip | |
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)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dispextern.h | 3 | ||||
| -rw-r--r-- | src/xdisp.c | 93 |
2 files changed, 67 insertions, 29 deletions
diff --git a/src/dispextern.h b/src/dispextern.h index 724aad4227e..08380f1f17f 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -2782,7 +2782,8 @@ struct it | |||
| 2782 | else \ | 2782 | else \ |
| 2783 | produce_glyphs ((IT)); \ | 2783 | produce_glyphs ((IT)); \ |
| 2784 | if ((IT)->glyph_row != NULL) \ | 2784 | if ((IT)->glyph_row != NULL) \ |
| 2785 | inhibit_free_realized_faces = true; \ | 2785 | inhibit_free_realized_faces =true; \ |
| 2786 | reset_box_start_end_flags ((IT)); \ | ||
| 2786 | } while (false) | 2787 | } while (false) |
| 2787 | 2788 | ||
| 2788 | /* Bit-flags indicating what operation move_it_to should perform. */ | 2789 | /* Bit-flags indicating what operation move_it_to should perform. */ |
diff --git a/src/xdisp.c b/src/xdisp.c index 3c594b54add..04fc8aa3c45 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -1020,6 +1020,7 @@ static Lisp_Object calc_line_height_property (struct it *, Lisp_Object, | |||
| 1020 | static void produce_special_glyphs (struct it *, enum display_element_type); | 1020 | static void produce_special_glyphs (struct it *, enum display_element_type); |
| 1021 | static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face); | 1021 | static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face); |
| 1022 | static bool coords_in_mouse_face_p (struct window *, int, int); | 1022 | static bool coords_in_mouse_face_p (struct window *, int, int); |
| 1023 | static void reset_box_start_end_flags (struct it *); | ||
| 1023 | 1024 | ||
| 1024 | 1025 | ||
| 1025 | 1026 | ||
| @@ -1435,6 +1436,29 @@ window_hscroll_limited (struct window *w, struct frame *f) | |||
| 1435 | return window_hscroll; | 1436 | return window_hscroll; |
| 1436 | } | 1437 | } |
| 1437 | 1438 | ||
| 1439 | /* Reset the box-face start and end flags in the iterator. This is | ||
| 1440 | called after producing glyphs, such that we reset these flags only | ||
| 1441 | after producing a glyph with the flag set. */ | ||
| 1442 | |||
| 1443 | static void | ||
| 1444 | reset_box_start_end_flags (struct it *it) | ||
| 1445 | { | ||
| 1446 | /* Don't reset if we've drawn the glyph in the display margins -- | ||
| 1447 | those don't count as "produced glyphs". */ | ||
| 1448 | if (it->area == TEXT_AREA | ||
| 1449 | /* Don't reset if we displayed a fringe bitmap. */ | ||
| 1450 | && !(it->what == IT_IMAGE && it->image_id < 0)) | ||
| 1451 | { | ||
| 1452 | /* Don't reset if the face is not a box face: that might mean we | ||
| 1453 | are iterating some overlay or display string, and the first | ||
| 1454 | character to have the box face is yet to be seen, when we pop | ||
| 1455 | the iterator stack. */ | ||
| 1456 | if (it->face_box_p) | ||
| 1457 | it->start_of_box_run_p = false; | ||
| 1458 | it->end_of_box_run_p = false; | ||
| 1459 | } | ||
| 1460 | } | ||
| 1461 | |||
| 1438 | /* Return true if position CHARPOS is visible in window W. | 1462 | /* Return true if position CHARPOS is visible in window W. |
| 1439 | CHARPOS < 0 means return info about WINDOW_END position. | 1463 | CHARPOS < 0 means return info about WINDOW_END position. |
| 1440 | If visible, set *X and *Y to pixel coordinates of top left corner. | 1464 | If visible, set *X and *Y to pixel coordinates of top left corner. |
| @@ -4315,8 +4339,11 @@ handle_face_prop (struct it *it) | |||
| 4315 | this is the start of a run of characters with box face, | 4339 | this is the start of a run of characters with box face, |
| 4316 | i.e. this character has a shadow on the left side. */ | 4340 | i.e. this character has a shadow on the left side. */ |
| 4317 | it->face_id = new_face_id; | 4341 | it->face_id = new_face_id; |
| 4318 | it->start_of_box_run_p = (new_face->box != FACE_NO_BOX | 4342 | /* Don't reset the start_of_box_run_p flag, only set it if |
| 4319 | && (old_face == NULL || !old_face->box)); | 4343 | needed. */ |
| 4344 | if (!(it->start_of_box_run_p && old_face && old_face->box)) | ||
| 4345 | it->start_of_box_run_p = (new_face->box != FACE_NO_BOX | ||
| 4346 | && (old_face == NULL || !old_face->box)); | ||
| 4320 | it->face_box_p = new_face->box != FACE_NO_BOX; | 4347 | it->face_box_p = new_face->box != FACE_NO_BOX; |
| 4321 | } | 4348 | } |
| 4322 | 4349 | ||
| @@ -6457,7 +6484,16 @@ pop_it (struct it *it) | |||
| 6457 | it->object = p->u.stretch.object; | 6484 | it->object = p->u.stretch.object; |
| 6458 | break; | 6485 | break; |
| 6459 | case GET_FROM_BUFFER: | 6486 | case GET_FROM_BUFFER: |
| 6460 | it->object = it->w->contents; | 6487 | { |
| 6488 | struct face *face = FACE_FROM_ID_OR_NULL (it->f, it->face_id); | ||
| 6489 | |||
| 6490 | /* Restore the face_box_p flag, since it could have been | ||
| 6491 | overwritten by the face of the object that we just finished | ||
| 6492 | displaying. */ | ||
| 6493 | if (face) | ||
| 6494 | it->face_box_p = face->box != FACE_NO_BOX; | ||
| 6495 | it->object = it->w->contents; | ||
| 6496 | } | ||
| 6461 | break; | 6497 | break; |
| 6462 | case GET_FROM_STRING: | 6498 | case GET_FROM_STRING: |
| 6463 | { | 6499 | { |
| @@ -7586,9 +7622,8 @@ get_next_display_element (struct it *it) | |||
| 7586 | /* If the box comes from face properties in a | 7622 | /* If the box comes from face properties in a |
| 7587 | display string, check faces in that string. */ | 7623 | display string, check faces in that string. */ |
| 7588 | int string_face_id = face_after_it_pos (it); | 7624 | int string_face_id = face_after_it_pos (it); |
| 7589 | it->end_of_box_run_p | 7625 | if (FACE_FROM_ID (it->f, string_face_id)->box == FACE_NO_BOX) |
| 7590 | = (FACE_FROM_ID (it->f, string_face_id)->box | 7626 | it->end_of_box_run_p = true; |
| 7591 | == FACE_NO_BOX); | ||
| 7592 | } | 7627 | } |
| 7593 | /* Otherwise, the box comes from the underlying face. | 7628 | /* Otherwise, the box comes from the underlying face. |
| 7594 | If this is the last string character displayed, check | 7629 | If this is the last string character displayed, check |
| @@ -7657,9 +7692,9 @@ get_next_display_element (struct it *it) | |||
| 7657 | CHARPOS (pos), 0, | 7692 | CHARPOS (pos), 0, |
| 7658 | &ignore, face_id, | 7693 | &ignore, face_id, |
| 7659 | false, 0); | 7694 | false, 0); |
| 7660 | it->end_of_box_run_p | 7695 | if (FACE_FROM_ID (it->f, next_face_id)->box |
| 7661 | = (FACE_FROM_ID (it->f, next_face_id)->box | 7696 | == FACE_NO_BOX) |
| 7662 | == FACE_NO_BOX); | 7697 | it->end_of_box_run_p = true; |
| 7663 | } | 7698 | } |
| 7664 | } | 7699 | } |
| 7665 | else if (CHARPOS (pos) >= ZV) | 7700 | else if (CHARPOS (pos) >= ZV) |
| @@ -7672,9 +7707,9 @@ get_next_display_element (struct it *it) | |||
| 7672 | CHARPOS (pos) | 7707 | CHARPOS (pos) |
| 7673 | + TEXT_PROP_DISTANCE_LIMIT, | 7708 | + TEXT_PROP_DISTANCE_LIMIT, |
| 7674 | false, -1, 0); | 7709 | false, -1, 0); |
| 7675 | it->end_of_box_run_p | 7710 | if (FACE_FROM_ID (it->f, next_face_id)->box |
| 7676 | = (FACE_FROM_ID (it->f, next_face_id)->box | 7711 | == FACE_NO_BOX) |
| 7677 | == FACE_NO_BOX); | 7712 | it->end_of_box_run_p = true; |
| 7678 | } | 7713 | } |
| 7679 | } | 7714 | } |
| 7680 | } | 7715 | } |
| @@ -7684,9 +7719,9 @@ get_next_display_element (struct it *it) | |||
| 7684 | else if (it->method != GET_FROM_DISPLAY_VECTOR) | 7719 | else if (it->method != GET_FROM_DISPLAY_VECTOR) |
| 7685 | { | 7720 | { |
| 7686 | int face_id = face_after_it_pos (it); | 7721 | int face_id = face_after_it_pos (it); |
| 7687 | it->end_of_box_run_p | 7722 | if (face_id != it->face_id |
| 7688 | = (face_id != it->face_id | 7723 | && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX) |
| 7689 | && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX); | 7724 | it->end_of_box_run_p = true; |
| 7690 | } | 7725 | } |
| 7691 | } | 7726 | } |
| 7692 | /* If we reached the end of the object we've been iterating (e.g., a | 7727 | /* 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) | |||
| 7723 | void | 7758 | void |
| 7724 | set_iterator_to_next (struct it *it, bool reseat_p) | 7759 | set_iterator_to_next (struct it *it, bool reseat_p) |
| 7725 | { | 7760 | { |
| 7726 | /* Reset flags indicating start and end of a sequence of characters | ||
| 7727 | with box. Reset them at the start of this function because | ||
| 7728 | moving the iterator to a new position might set them. */ | ||
| 7729 | it->start_of_box_run_p = it->end_of_box_run_p = false; | ||
| 7730 | 7761 | ||
| 7731 | switch (it->method) | 7762 | switch (it->method) |
| 7732 | { | 7763 | { |
| @@ -8138,9 +8169,9 @@ next_element_from_display_vector (struct it *it) | |||
| 8138 | } | 8169 | } |
| 8139 | } | 8170 | } |
| 8140 | next_face = FACE_FROM_ID_OR_NULL (it->f, next_face_id); | 8171 | next_face = FACE_FROM_ID_OR_NULL (it->f, next_face_id); |
| 8141 | it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX | 8172 | if (this_face && this_face->box != FACE_NO_BOX |
| 8142 | && (!next_face | 8173 | && (!next_face || next_face->box == FACE_NO_BOX)) |
| 8143 | || next_face->box == FACE_NO_BOX)); | 8174 | it->end_of_box_run_p = true; |
| 8144 | it->face_box_p = this_face && this_face->box != FACE_NO_BOX; | 8175 | it->face_box_p = this_face && this_face->box != FACE_NO_BOX; |
| 8145 | } | 8176 | } |
| 8146 | else | 8177 | else |
| @@ -21485,6 +21516,8 @@ append_space_for_newline (struct it *it, bool default_face_p) | |||
| 21485 | 21516 | ||
| 21486 | const int indicator_column = | 21517 | const int indicator_column = |
| 21487 | fill_column_indicator_column (it, char_width); | 21518 | fill_column_indicator_column (it, char_width); |
| 21519 | int saved_end_of_box_run = it->end_of_box_run_p; | ||
| 21520 | bool should_keep_end_of_box_run = false; | ||
| 21488 | 21521 | ||
| 21489 | if (it->current_x == indicator_column) | 21522 | if (it->current_x == indicator_column) |
| 21490 | { | 21523 | { |
| @@ -21507,14 +21540,18 @@ append_space_for_newline (struct it *it, bool default_face_p) | |||
| 21507 | have the end_of_box_run_p flag set for it, so there's no | 21540 | have the end_of_box_run_p flag set for it, so there's no |
| 21508 | need for the appended newline glyph to have that flag | 21541 | need for the appended newline glyph to have that flag |
| 21509 | set. */ | 21542 | set. */ |
| 21510 | if (it->glyph_row->reversed_p | 21543 | if (!(it->glyph_row->reversed_p |
| 21511 | /* But if the appended newline glyph goes all the way to | 21544 | /* But if the appended newline glyph goes all the way to |
| 21512 | the end of the row, there will be no stretch glyph, | 21545 | the end of the row, there will be no stretch glyph, |
| 21513 | so leave the box flag set. */ | 21546 | so leave the box flag set. */ |
| 21514 | && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x) | 21547 | && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)) |
| 21515 | it->end_of_box_run_p = false; | 21548 | should_keep_end_of_box_run = true; |
| 21516 | } | 21549 | } |
| 21517 | PRODUCE_GLYPHS (it); | 21550 | PRODUCE_GLYPHS (it); |
| 21551 | /* Restore the end_of_box_run_p flag which was reset by | ||
| 21552 | PRODUCE_GLYPHS. */ | ||
| 21553 | if (should_keep_end_of_box_run) | ||
| 21554 | it->end_of_box_run_p = saved_end_of_box_run; | ||
| 21518 | #ifdef HAVE_WINDOW_SYSTEM | 21555 | #ifdef HAVE_WINDOW_SYSTEM |
| 21519 | if (FRAME_WINDOW_P (it->f)) | 21556 | if (FRAME_WINDOW_P (it->f)) |
| 21520 | { | 21557 | { |