diff options
| author | Eli Zaretskii | 2014-02-27 19:42:00 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2014-02-27 19:42:00 +0200 |
| commit | 11de63ede082fe5913f9714f4bba05ac6e6b984c (patch) | |
| tree | 0b015bd6df7141b1b283857336ba82bbca3cb344 /src | |
| parent | 79fc11918a932cfa20abf489267f4d88b48c7bd1 (diff) | |
| download | emacs-11de63ede082fe5913f9714f4bba05ac6e6b984c.tar.gz emacs-11de63ede082fe5913f9714f4bba05ac6e6b984c.zip | |
Fix bug #16870 with 'box' face in display strings.
src/xdisp.c (pop_it): Restore the it->face_box_p flag which could be
reset by the face of the object just displayed. See also bug#76.
(get_next_display_element): If the string came from a display
property, examine the box face attribute at it->position, not at
it->current.pos, since the latter was not updated yet.
(handle_face_prop): Improve commentary.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 9 | ||||
| -rw-r--r-- | src/xdisp.c | 63 |
2 files changed, 61 insertions, 11 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 88458de6b01..5850431cf93 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,12 @@ | |||
| 1 | 2014-02-27 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (pop_it): Restore the it->face_box_p flag which could be | ||
| 4 | reset by the face of the object just displayed. See also bug#76. | ||
| 5 | (get_next_display_element): If the string came from a display | ||
| 6 | property, examine the box face attribute at it->position, not at | ||
| 7 | it->current.pos, since the latter was not updated yet. (Bug#16870) | ||
| 8 | (handle_face_prop): Improve commentary. | ||
| 9 | |||
| 1 | 2014-02-27 Michael Albinus <michael.albinus@gmx.de> | 10 | 2014-02-27 Michael Albinus <michael.albinus@gmx.de> |
| 2 | 11 | ||
| 3 | * dbusbind.c (Fdbus__init_bus, Qdbus__init_bus, Sdbus__init_bus): | 12 | * dbusbind.c (Fdbus__init_bus, Qdbus__init_bus, Sdbus__init_bus): |
diff --git a/src/xdisp.c b/src/xdisp.c index 836b825aafa..203fd303c4a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -3923,6 +3923,15 @@ handle_face_prop (struct it *it) | |||
| 3923 | For strings from wrap-prefix and line-prefix properties, | 3923 | For strings from wrap-prefix and line-prefix properties, |
| 3924 | use the default face, possibly remapped via | 3924 | use the default face, possibly remapped via |
| 3925 | Vface_remapping_alist. */ | 3925 | Vface_remapping_alist. */ |
| 3926 | /* Note that the fact that we use the face at _buffer_ | ||
| 3927 | position means that a 'display' property on an overlay | ||
| 3928 | string will not inherit the face of that overlay string, | ||
| 3929 | but will instead revert to the face of buffer text | ||
| 3930 | covered by the overlay. This is visible, e.g., when the | ||
| 3931 | overlay specifies a box face, but neither the buffer nor | ||
| 3932 | the display string do. This sounds like a design bug, | ||
| 3933 | but Emacs always did that since v21.1, so changing that | ||
| 3934 | might be a big deal. */ | ||
| 3926 | base_face_id = it->string_from_prefix_prop_p | 3935 | base_face_id = it->string_from_prefix_prop_p |
| 3927 | ? (!NILP (Vface_remapping_alist) | 3936 | ? (!NILP (Vface_remapping_alist) |
| 3928 | ? lookup_basic_face (it->f, DEFAULT_FACE_ID) | 3937 | ? lookup_basic_face (it->f, DEFAULT_FACE_ID) |
| @@ -5956,7 +5965,16 @@ pop_it (struct it *it) | |||
| 5956 | it->object = it->w->contents; | 5965 | it->object = it->w->contents; |
| 5957 | break; | 5966 | break; |
| 5958 | case GET_FROM_STRING: | 5967 | case GET_FROM_STRING: |
| 5959 | it->object = it->string; | 5968 | { |
| 5969 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | ||
| 5970 | |||
| 5971 | /* Restore the face_box_p flag, since it could have been | ||
| 5972 | overwritten by the face of the object that we just finished | ||
| 5973 | displaying. */ | ||
| 5974 | if (face) | ||
| 5975 | it->face_box_p = face->box != FACE_NO_BOX; | ||
| 5976 | it->object = it->string; | ||
| 5977 | } | ||
| 5960 | break; | 5978 | break; |
| 5961 | case GET_FROM_DISPLAY_VECTOR: | 5979 | case GET_FROM_DISPLAY_VECTOR: |
| 5962 | if (it->s) | 5980 | if (it->s) |
| @@ -7043,21 +7061,44 @@ get_next_display_element (struct it *it) | |||
| 7043 | If this is the last string character displayed, check | 7061 | If this is the last string character displayed, check |
| 7044 | the next buffer location. */ | 7062 | the next buffer location. */ |
| 7045 | else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1) | 7063 | else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1) |
| 7046 | && (it->current.overlay_string_index | 7064 | /* n_overlay_strings is unreliable unless |
| 7047 | == it->n_overlay_strings - 1)) | 7065 | overlay_string_index is non-negative. */ |
| 7066 | && ((it->current.overlay_string_index >= 0 | ||
| 7067 | && (it->current.overlay_string_index | ||
| 7068 | == it->n_overlay_strings - 1)) | ||
| 7069 | /* A string from display property. */ | ||
| 7070 | || it->from_disp_prop_p)) | ||
| 7048 | { | 7071 | { |
| 7049 | ptrdiff_t ignore; | 7072 | ptrdiff_t ignore; |
| 7050 | int next_face_id; | 7073 | int next_face_id; |
| 7051 | struct text_pos pos = it->current.pos; | 7074 | struct text_pos pos = it->current.pos; |
| 7052 | INC_TEXT_POS (pos, it->multibyte_p); | ||
| 7053 | 7075 | ||
| 7054 | next_face_id = face_at_buffer_position | 7076 | /* For a string from a display property, the next |
| 7055 | (it->w, CHARPOS (pos), &ignore, | 7077 | buffer position is stored in the 'position' |
| 7056 | (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0, | 7078 | member of the iteration stack slot below the |
| 7057 | -1); | 7079 | current one, see handle_single_display_spec. By |
| 7058 | it->end_of_box_run_p | 7080 | contrast, it->current.pos was is not yet updated |
| 7059 | = (FACE_FROM_ID (it->f, next_face_id)->box | 7081 | to point to that buffer position; that will |
| 7060 | == FACE_NO_BOX); | 7082 | happen in pop_it, after we finish displaying the |
| 7083 | current string. Note that we already checked | ||
| 7084 | above that it->sp is positive, so subtracting one | ||
| 7085 | from it is safe. */ | ||
| 7086 | if (it->from_disp_prop_p) | ||
| 7087 | pos = (it->stack + it->sp - 1)->position; | ||
| 7088 | else | ||
| 7089 | INC_TEXT_POS (pos, it->multibyte_p); | ||
| 7090 | |||
| 7091 | if (CHARPOS (pos) >= ZV) | ||
| 7092 | it->end_of_box_run_p = true; | ||
| 7093 | else | ||
| 7094 | { | ||
| 7095 | next_face_id = face_at_buffer_position | ||
| 7096 | (it->w, CHARPOS (pos), &ignore, | ||
| 7097 | CHARPOS (pos) + TEXT_PROP_DISTANCE_LIMIT, 0, -1); | ||
| 7098 | it->end_of_box_run_p | ||
| 7099 | = (FACE_FROM_ID (it->f, next_face_id)->box | ||
| 7100 | == FACE_NO_BOX); | ||
| 7101 | } | ||
| 7061 | } | 7102 | } |
| 7062 | } | 7103 | } |
| 7063 | } | 7104 | } |