diff options
| author | Eli Zaretskii | 2011-08-02 22:16:32 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2011-08-02 22:16:32 +0300 |
| commit | 55439c615b8e04748a66a6d88ec70a9ac5acd672 (patch) | |
| tree | df8c9c478b012b4ac25c5be2cf881c9398bfe174 /src | |
| parent | 0e6a2bd74efe96eb9b171aa8011b1a13db7f80df (diff) | |
| download | emacs-55439c615b8e04748a66a6d88ec70a9ac5acd672.tar.gz emacs-55439c615b8e04748a66a6d88ec70a9ac5acd672.zip | |
Fix bug #9218 with slow cursor motion and scrolling Org Mode buffers.
src/dispextern.h (struct bidi_it): New member disp_prop_p.
src/xdisp.c: Remove one-slot cache of display string positions.
(compute_display_string_pos): Accept an additional argument
DISP_PROP_P; callers changed. Scan at most 5K characters forward
for a display string or property. If found, set DISP_PROP_P
non-zero.
src/bidi.c (bidi_fetch_char): Accept an additional argument
DISP_PROP_P, and pass it to compute_display_string_pos. Only
handle text covered by a display string if DISP_PROP_P is returned
non-zero. All callers of bidi_fetch_char changed.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 18 | ||||
| -rw-r--r-- | src/bidi.c | 44 | ||||
| -rw-r--r-- | src/dispextern.h | 5 | ||||
| -rw-r--r-- | src/xdisp.c | 67 |
4 files changed, 70 insertions, 64 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 59f09515829..3717924ff68 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,21 @@ | |||
| 1 | 2011-08-02 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | Fix slow cursor motion and scrolling in large buffers with | ||
| 4 | selective display, like Org Mode buffers. (Bug#9218) | ||
| 5 | |||
| 6 | * dispextern.h (struct bidi_it): New member disp_prop_p. | ||
| 7 | |||
| 8 | * xdisp.c: Remove one-slot cache of display string positions. | ||
| 9 | (compute_display_string_pos): Accept an additional argument | ||
| 10 | DISP_PROP_P; callers changed. Scan at most 5K characters forward | ||
| 11 | for a display string or property. If found, set DISP_PROP_P | ||
| 12 | non-zero. | ||
| 13 | |||
| 14 | * bidi.c (bidi_fetch_char): Accept an additional argument | ||
| 15 | DISP_PROP_P, and pass it to compute_display_string_pos. Only | ||
| 16 | handle text covered by a display string if DISP_PROP_P is returned | ||
| 17 | non-zero. All callers of bidi_fetch_char changed. | ||
| 18 | |||
| 1 | 2011-08-02 Stefan Monnier <monnier@iro.umontreal.ca> | 19 | 2011-08-02 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 20 | ||
| 3 | * keymap.c (Fdefine_key): Fix Lisp_Object/int mixup; apply some CSE. | 21 | * keymap.c (Fdefine_key): Fix Lisp_Object/int mixup; apply some CSE. |
diff --git a/src/bidi.c b/src/bidi.c index 697ebb92856..ae5143b37e0 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -792,6 +792,7 @@ bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, int frame_window_p, | |||
| 792 | bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT; | 792 | bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT; |
| 793 | bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */ | 793 | bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */ |
| 794 | bidi_it->disp_pos = -1; /* invalid/unknown */ | 794 | bidi_it->disp_pos = -1; /* invalid/unknown */ |
| 795 | bidi_it->disp_prop_p = 0; | ||
| 795 | /* We can only shrink the cache if we are at the bottom level of its | 796 | /* We can only shrink the cache if we are at the bottom level of its |
| 796 | "stack". */ | 797 | "stack". */ |
| 797 | if (bidi_cache_start == 0) | 798 | if (bidi_cache_start == 0) |
| @@ -874,14 +875,16 @@ bidi_char_at_pos (EMACS_INT bytepos, const unsigned char *s, int unibyte) | |||
| 874 | covered characters as a single character u+FFFC, and return their | 875 | covered characters as a single character u+FFFC, and return their |
| 875 | combined length in CH_LEN and NCHARS. DISP_POS specifies the | 876 | combined length in CH_LEN and NCHARS. DISP_POS specifies the |
| 876 | character position of the next display string, or -1 if not yet | 877 | character position of the next display string, or -1 if not yet |
| 877 | computed. When the next character is at or beyond that position, | 878 | computed. DISP_PROP_P non-zero means that there's really a display |
| 878 | the function updates DISP_POS with the position of the next display | 879 | string at DISP_POS, as opposed to when we searched till DISP_POS |
| 879 | string. STRING->s is the C string to iterate, or NULL if iterating | 880 | without findingone. When the next character is at or beyond that |
| 880 | over a buffer or a Lisp string; in the latter case, STRING->lstring | 881 | position, the function updates DISP_POS with the position of the |
| 881 | is the Lisp string. */ | 882 | next display string. STRING->s is the C string to iterate, or NULL |
| 883 | if iterating over a buffer or a Lisp string; in the latter case, | ||
| 884 | STRING->lstring is the Lisp string. */ | ||
| 882 | static inline int | 885 | static inline int |
| 883 | bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, | 886 | bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, |
| 884 | struct bidi_string_data *string, | 887 | int *disp_prop_p, struct bidi_string_data *string, |
| 885 | int frame_window_p, EMACS_INT *ch_len, EMACS_INT *nchars) | 888 | int frame_window_p, EMACS_INT *ch_len, EMACS_INT *nchars) |
| 886 | { | 889 | { |
| 887 | int ch; | 890 | int ch; |
| @@ -894,7 +897,8 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, | |||
| 894 | if (charpos < endpos && charpos > *disp_pos) | 897 | if (charpos < endpos && charpos > *disp_pos) |
| 895 | { | 898 | { |
| 896 | SET_TEXT_POS (pos, charpos, bytepos); | 899 | SET_TEXT_POS (pos, charpos, bytepos); |
| 897 | *disp_pos = compute_display_string_pos (&pos, string, frame_window_p); | 900 | *disp_pos = compute_display_string_pos (&pos, string, frame_window_p, |
| 901 | disp_prop_p); | ||
| 898 | } | 902 | } |
| 899 | 903 | ||
| 900 | /* Fetch the character at BYTEPOS. */ | 904 | /* Fetch the character at BYTEPOS. */ |
| @@ -904,8 +908,9 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, | |||
| 904 | *ch_len = 1; | 908 | *ch_len = 1; |
| 905 | *nchars = 1; | 909 | *nchars = 1; |
| 906 | *disp_pos = endpos; | 910 | *disp_pos = endpos; |
| 911 | *disp_prop_p = 0; | ||
| 907 | } | 912 | } |
| 908 | else if (charpos >= *disp_pos) | 913 | else if (charpos >= *disp_pos && *disp_prop_p) |
| 909 | { | 914 | { |
| 910 | EMACS_INT disp_end_pos; | 915 | EMACS_INT disp_end_pos; |
| 911 | 916 | ||
| @@ -972,10 +977,12 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, | |||
| 972 | 977 | ||
| 973 | /* If we just entered a run of characters covered by a display | 978 | /* If we just entered a run of characters covered by a display |
| 974 | string, compute the position of the next display string. */ | 979 | string, compute the position of the next display string. */ |
| 975 | if (charpos + *nchars <= endpos && charpos + *nchars > *disp_pos) | 980 | if (charpos + *nchars <= endpos && charpos + *nchars > *disp_pos |
| 981 | && *disp_prop_p) | ||
| 976 | { | 982 | { |
| 977 | SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len); | 983 | SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len); |
| 978 | *disp_pos = compute_display_string_pos (&pos, string, frame_window_p); | 984 | *disp_pos = compute_display_string_pos (&pos, string, frame_window_p, |
| 985 | disp_prop_p); | ||
| 979 | } | 986 | } |
| 980 | 987 | ||
| 981 | return ch; | 988 | return ch; |
| @@ -1083,6 +1090,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) | |||
| 1083 | int ch; | 1090 | int ch; |
| 1084 | EMACS_INT ch_len, nchars; | 1091 | EMACS_INT ch_len, nchars; |
| 1085 | EMACS_INT pos, disp_pos = -1; | 1092 | EMACS_INT pos, disp_pos = -1; |
| 1093 | int disp_prop_p = 0; | ||
| 1086 | bidi_type_t type; | 1094 | bidi_type_t type; |
| 1087 | const unsigned char *s; | 1095 | const unsigned char *s; |
| 1088 | 1096 | ||
| @@ -1130,7 +1138,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) | |||
| 1130 | bytepos = pstartbyte; | 1138 | bytepos = pstartbyte; |
| 1131 | if (!string_p) | 1139 | if (!string_p) |
| 1132 | pos = BYTE_TO_CHAR (bytepos); | 1140 | pos = BYTE_TO_CHAR (bytepos); |
| 1133 | ch = bidi_fetch_char (bytepos, pos, &disp_pos, &bidi_it->string, | 1141 | ch = bidi_fetch_char (bytepos, pos, &disp_pos, &disp_prop_p, |
| 1142 | &bidi_it->string, | ||
| 1134 | bidi_it->frame_window_p, &ch_len, &nchars); | 1143 | bidi_it->frame_window_p, &ch_len, &nchars); |
| 1135 | type = bidi_get_type (ch, NEUTRAL_DIR); | 1144 | type = bidi_get_type (ch, NEUTRAL_DIR); |
| 1136 | 1145 | ||
| @@ -1157,7 +1166,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) | |||
| 1157 | && bidi_at_paragraph_end (pos, bytepos) >= -1) | 1166 | && bidi_at_paragraph_end (pos, bytepos) >= -1) |
| 1158 | break; | 1167 | break; |
| 1159 | /* Fetch next character and advance to get past it. */ | 1168 | /* Fetch next character and advance to get past it. */ |
| 1160 | ch = bidi_fetch_char (bytepos, pos, &disp_pos, &bidi_it->string, | 1169 | ch = bidi_fetch_char (bytepos, pos, &disp_pos, |
| 1170 | &disp_prop_p, &bidi_it->string, | ||
| 1161 | bidi_it->frame_window_p, &ch_len, &nchars); | 1171 | bidi_it->frame_window_p, &ch_len, &nchars); |
| 1162 | pos += nchars; | 1172 | pos += nchars; |
| 1163 | bytepos += ch_len; | 1173 | bytepos += ch_len; |
| @@ -1290,6 +1300,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1290 | bidi_it->ch_len = 1; | 1300 | bidi_it->ch_len = 1; |
| 1291 | bidi_it->nchars = 1; | 1301 | bidi_it->nchars = 1; |
| 1292 | bidi_it->disp_pos = (string_p ? bidi_it->string.schars : ZV); | 1302 | bidi_it->disp_pos = (string_p ? bidi_it->string.schars : ZV); |
| 1303 | bidi_it->disp_prop_p = 0; | ||
| 1293 | } | 1304 | } |
| 1294 | else | 1305 | else |
| 1295 | { | 1306 | { |
| @@ -1297,8 +1308,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1297 | display string, treat the entire run of covered characters as | 1308 | display string, treat the entire run of covered characters as |
| 1298 | a single character u+FFFC. */ | 1309 | a single character u+FFFC. */ |
| 1299 | curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos, | 1310 | curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos, |
| 1300 | &bidi_it->disp_pos, &bidi_it->string, | 1311 | &bidi_it->disp_pos, &bidi_it->disp_prop_p, |
| 1301 | bidi_it->frame_window_p, | 1312 | &bidi_it->string, bidi_it->frame_window_p, |
| 1302 | &bidi_it->ch_len, &bidi_it->nchars); | 1313 | &bidi_it->ch_len, &bidi_it->nchars); |
| 1303 | } | 1314 | } |
| 1304 | bidi_it->ch = curchar; | 1315 | bidi_it->ch = curchar; |
| @@ -2032,12 +2043,13 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2032 | struct bidi_string_data bs = bidi_it->string; | 2043 | struct bidi_string_data bs = bidi_it->string; |
| 2033 | bidi_type_t chtype; | 2044 | bidi_type_t chtype; |
| 2034 | int fwp = bidi_it->frame_window_p; | 2045 | int fwp = bidi_it->frame_window_p; |
| 2046 | int dpp = bidi_it->disp_prop_p; | ||
| 2035 | 2047 | ||
| 2036 | if (bidi_it->nchars <= 0) | 2048 | if (bidi_it->nchars <= 0) |
| 2037 | abort (); | 2049 | abort (); |
| 2038 | do { | 2050 | do { |
| 2039 | ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &bs, fwp, | 2051 | ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &dpp, &bs, |
| 2040 | &clen, &nc); | 2052 | fwp, &clen, &nc); |
| 2041 | if (ch == '\n' || ch == BIDI_EOB /* || ch == LINESEP_CHAR */) | 2053 | if (ch == '\n' || ch == BIDI_EOB /* || ch == LINESEP_CHAR */) |
| 2042 | chtype = NEUTRAL_B; | 2054 | chtype = NEUTRAL_B; |
| 2043 | else | 2055 | else |
diff --git a/src/dispextern.h b/src/dispextern.h index dc44c698164..2e245479a81 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1868,6 +1868,8 @@ struct bidi_it { | |||
| 1868 | bidi_dir_t paragraph_dir; /* current paragraph direction */ | 1868 | bidi_dir_t paragraph_dir; /* current paragraph direction */ |
| 1869 | EMACS_INT separator_limit; /* where paragraph separator should end */ | 1869 | EMACS_INT separator_limit; /* where paragraph separator should end */ |
| 1870 | EMACS_INT disp_pos; /* position of display string after ch */ | 1870 | EMACS_INT disp_pos; /* position of display string after ch */ |
| 1871 | int disp_prop_p; /* if non-zero, there really is a | ||
| 1872 | `display' property/string at disp_pos */ | ||
| 1871 | unsigned first_elt : 1; /* if non-zero, examine current char first */ | 1873 | unsigned first_elt : 1; /* if non-zero, examine current char first */ |
| 1872 | unsigned new_paragraph : 1; /* if non-zero, we expect a new paragraph */ | 1874 | unsigned new_paragraph : 1; /* if non-zero, we expect a new paragraph */ |
| 1873 | unsigned frame_window_p : 1; /* non-zero if displaying on a GUI frame */ | 1875 | unsigned frame_window_p : 1; /* non-zero if displaying on a GUI frame */ |
| @@ -3035,7 +3037,8 @@ extern Lisp_Object lookup_glyphless_char_display (int, struct it *); | |||
| 3035 | extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object, | 3037 | extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object, |
| 3036 | struct font *, int, int *); | 3038 | struct font *, int, int *); |
| 3037 | extern EMACS_INT compute_display_string_pos (struct text_pos *, | 3039 | extern EMACS_INT compute_display_string_pos (struct text_pos *, |
| 3038 | struct bidi_string_data *, int); | 3040 | struct bidi_string_data *, |
| 3041 | int, int *); | ||
| 3039 | extern EMACS_INT compute_display_string_end (EMACS_INT, | 3042 | extern EMACS_INT compute_display_string_end (EMACS_INT, |
| 3040 | struct bidi_string_data *); | 3043 | struct bidi_string_data *); |
| 3041 | 3044 | ||
diff --git a/src/xdisp.c b/src/xdisp.c index 9d3e501787b..fa4b3c4f9ab 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -3134,13 +3134,10 @@ next_overlay_change (EMACS_INT pos) | |||
| 3134 | return endpos; | 3134 | return endpos; |
| 3135 | } | 3135 | } |
| 3136 | 3136 | ||
| 3137 | /* Record one cached display string position found recently by | 3137 | /* How many characters forward to search for a display property or |
| 3138 | compute_display_string_pos. */ | 3138 | display string. Enough for a screenful of 100 lines x 50 |
| 3139 | static EMACS_INT cached_disp_pos; | 3139 | characters in a line. */ |
| 3140 | static EMACS_INT cached_prev_pos = -1; | 3140 | #define MAX_DISP_SCAN 5000 |
| 3141 | static struct buffer *cached_disp_buffer; | ||
| 3142 | static int cached_disp_modiff; | ||
| 3143 | static int cached_disp_overlay_modiff; | ||
| 3144 | 3141 | ||
| 3145 | /* Return the character position of a display string at or after | 3142 | /* Return the character position of a display string at or after |
| 3146 | position specified by POSITION. If no display string exists at or | 3143 | position specified by POSITION. If no display string exists at or |
| @@ -3152,57 +3149,33 @@ static int cached_disp_overlay_modiff; | |||
| 3152 | on a GUI frame. */ | 3149 | on a GUI frame. */ |
| 3153 | EMACS_INT | 3150 | EMACS_INT |
| 3154 | compute_display_string_pos (struct text_pos *position, | 3151 | compute_display_string_pos (struct text_pos *position, |
| 3155 | struct bidi_string_data *string, int frame_window_p) | 3152 | struct bidi_string_data *string, |
| 3153 | int frame_window_p, int *disp_prop_p) | ||
| 3156 | { | 3154 | { |
| 3157 | /* OBJECT = nil means current buffer. */ | 3155 | /* OBJECT = nil means current buffer. */ |
| 3158 | Lisp_Object object = | 3156 | Lisp_Object object = |
| 3159 | (string && STRINGP (string->lstring)) ? string->lstring : Qnil; | 3157 | (string && STRINGP (string->lstring)) ? string->lstring : Qnil; |
| 3160 | Lisp_Object pos, spec; | 3158 | Lisp_Object pos, spec, limpos; |
| 3161 | int string_p = (string && (STRINGP (string->lstring) || string->s)); | 3159 | int string_p = (string && (STRINGP (string->lstring) || string->s)); |
| 3162 | EMACS_INT eob = string_p ? string->schars : ZV; | 3160 | EMACS_INT eob = string_p ? string->schars : ZV; |
| 3163 | EMACS_INT begb = string_p ? 0 : BEGV; | 3161 | EMACS_INT begb = string_p ? 0 : BEGV; |
| 3164 | EMACS_INT bufpos, charpos = CHARPOS (*position); | 3162 | EMACS_INT bufpos, charpos = CHARPOS (*position); |
| 3163 | EMACS_INT lim = | ||
| 3164 | (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob; | ||
| 3165 | struct text_pos tpos; | 3165 | struct text_pos tpos; |
| 3166 | struct buffer *b; | 3166 | struct buffer *b; |
| 3167 | 3167 | ||
| 3168 | *disp_prop_p = 1; | ||
| 3169 | |||
| 3168 | if (charpos >= eob | 3170 | if (charpos >= eob |
| 3169 | /* We don't support display properties whose values are strings | 3171 | /* We don't support display properties whose values are strings |
| 3170 | that have display string properties. */ | 3172 | that have display string properties. */ |
| 3171 | || string->from_disp_str | 3173 | || string->from_disp_str |
| 3172 | /* C strings cannot have display properties. */ | 3174 | /* C strings cannot have display properties. */ |
| 3173 | || (string->s && !STRINGP (object))) | 3175 | || (string->s && !STRINGP (object))) |
| 3174 | return eob; | ||
| 3175 | |||
| 3176 | /* Check the cached values. */ | ||
| 3177 | if (!STRINGP (object)) | ||
| 3178 | { | 3176 | { |
| 3179 | if (NILP (object)) | 3177 | *disp_prop_p = 0; |
| 3180 | b = current_buffer; | 3178 | return eob; |
| 3181 | else | ||
| 3182 | b = XBUFFER (object); | ||
| 3183 | if (b == cached_disp_buffer | ||
| 3184 | && BUF_MODIFF (b) == cached_disp_modiff | ||
| 3185 | && BUF_OVERLAY_MODIFF (b) == cached_disp_overlay_modiff | ||
| 3186 | && !b->clip_changed) | ||
| 3187 | { | ||
| 3188 | if (cached_prev_pos >= 0 | ||
| 3189 | && cached_prev_pos < charpos && charpos <= cached_disp_pos) | ||
| 3190 | return cached_disp_pos; | ||
| 3191 | /* Handle overstepping either end of the known interval. */ | ||
| 3192 | if (charpos > cached_disp_pos) | ||
| 3193 | cached_prev_pos = cached_disp_pos; | ||
| 3194 | else /* charpos <= cached_prev_pos */ | ||
| 3195 | cached_prev_pos = max (charpos - 1, 0); | ||
| 3196 | } | ||
| 3197 | |||
| 3198 | /* Record new values in the cache. */ | ||
| 3199 | if (b != cached_disp_buffer) | ||
| 3200 | { | ||
| 3201 | cached_disp_buffer = b; | ||
| 3202 | cached_prev_pos = max (charpos - 1, 0); | ||
| 3203 | } | ||
| 3204 | cached_disp_modiff = BUF_MODIFF (b); | ||
| 3205 | cached_disp_overlay_modiff = BUF_OVERLAY_MODIFF (b); | ||
| 3206 | } | 3179 | } |
| 3207 | 3180 | ||
| 3208 | /* If the character at CHARPOS is where the display string begins, | 3181 | /* If the character at CHARPOS is where the display string begins, |
| @@ -3221,22 +3194,24 @@ compute_display_string_pos (struct text_pos *position, | |||
| 3221 | && handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, | 3194 | && handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, |
| 3222 | frame_window_p)) | 3195 | frame_window_p)) |
| 3223 | { | 3196 | { |
| 3224 | if (!STRINGP (object)) | ||
| 3225 | cached_disp_pos = charpos; | ||
| 3226 | return charpos; | 3197 | return charpos; |
| 3227 | } | 3198 | } |
| 3228 | 3199 | ||
| 3229 | /* Look forward for the first character with a `display' property | 3200 | /* Look forward for the first character with a `display' property |
| 3230 | that will replace the underlying text when displayed. */ | 3201 | that will replace the underlying text when displayed. */ |
| 3202 | limpos = make_number (lim); | ||
| 3231 | do { | 3203 | do { |
| 3232 | pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil); | 3204 | pos = Fnext_single_char_property_change (pos, Qdisplay, object, limpos); |
| 3233 | CHARPOS (tpos) = XFASTINT (pos); | 3205 | CHARPOS (tpos) = XFASTINT (pos); |
| 3206 | if (CHARPOS (tpos) >= lim) | ||
| 3207 | { | ||
| 3208 | *disp_prop_p = 0; | ||
| 3209 | break; | ||
| 3210 | } | ||
| 3234 | if (STRINGP (object)) | 3211 | if (STRINGP (object)) |
| 3235 | BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos)); | 3212 | BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos)); |
| 3236 | else | 3213 | else |
| 3237 | BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos)); | 3214 | BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos)); |
| 3238 | if (CHARPOS (tpos) >= eob) | ||
| 3239 | break; | ||
| 3240 | spec = Fget_char_property (pos, Qdisplay, object); | 3215 | spec = Fget_char_property (pos, Qdisplay, object); |
| 3241 | if (!STRINGP (object)) | 3216 | if (!STRINGP (object)) |
| 3242 | bufpos = CHARPOS (tpos); | 3217 | bufpos = CHARPOS (tpos); |
| @@ -3244,8 +3219,6 @@ compute_display_string_pos (struct text_pos *position, | |||
| 3244 | || !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, | 3219 | || !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, |
| 3245 | frame_window_p)); | 3220 | frame_window_p)); |
| 3246 | 3221 | ||
| 3247 | if (!STRINGP (object)) | ||
| 3248 | cached_disp_pos = CHARPOS (tpos); | ||
| 3249 | return CHARPOS (tpos); | 3222 | return CHARPOS (tpos); |
| 3250 | } | 3223 | } |
| 3251 | 3224 | ||