diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 33 | ||||
| -rw-r--r-- | src/bidi.c | 44 | ||||
| -rw-r--r-- | src/chartab.c | 2 | ||||
| -rw-r--r-- | src/dispextern.h | 5 | ||||
| -rw-r--r-- | src/keymap.c | 21 | ||||
| -rw-r--r-- | src/lisp.h | 1 | ||||
| -rw-r--r-- | src/xdisp.c | 67 |
7 files changed, 101 insertions, 72 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 4e8217cdf5f..3717924ff68 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,36 @@ | |||
| 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 | |||
| 19 | 2011-08-02 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 20 | |||
| 21 | * keymap.c (Fdefine_key): Fix Lisp_Object/int mixup; apply some CSE. | ||
| 22 | |||
| 23 | 2010-12-03 Don March <don@ohspite.net> | ||
| 24 | |||
| 25 | * keymap.c (Fdefine_key): Fix non-prefix key error message when | ||
| 26 | last character M-[char] is translated to ESC [char] (bug#7541). | ||
| 27 | |||
| 28 | 2011-08-02 Kenichi Handa <handa@m17n.org> | ||
| 29 | |||
| 30 | * lisp.h (uniprop_table): Extern it. | ||
| 31 | |||
| 32 | * chartab.c (uniprop_table): Make it non-static. | ||
| 33 | |||
| 1 | 2011-08-01 Eli Zaretskii <eliz@gnu.org> | 34 | 2011-08-01 Eli Zaretskii <eliz@gnu.org> |
| 2 | 35 | ||
| 3 | * xdisp.c (forward_to_next_line_start): Accept additional argument | 36 | * xdisp.c (forward_to_next_line_start): Accept additional argument |
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/chartab.c b/src/chartab.c index efe23eca83f..fb72004356e 100644 --- a/src/chartab.c +++ b/src/chartab.c | |||
| @@ -1310,7 +1310,7 @@ uniprop_get_encoder (Lisp_Object table) | |||
| 1310 | function may load a Lisp file and thus may cause | 1310 | function may load a Lisp file and thus may cause |
| 1311 | garbage-collection. */ | 1311 | garbage-collection. */ |
| 1312 | 1312 | ||
| 1313 | static Lisp_Object | 1313 | Lisp_Object |
| 1314 | uniprop_table (Lisp_Object prop) | 1314 | uniprop_table (Lisp_Object prop) |
| 1315 | { | 1315 | { |
| 1316 | Lisp_Object val, table, result; | 1316 | Lisp_Object val, table, result; |
diff --git a/src/dispextern.h b/src/dispextern.h index 94c72e5ce3c..a3dfcff3521 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1878,6 +1878,8 @@ struct bidi_it { | |||
| 1878 | bidi_dir_t paragraph_dir; /* current paragraph direction */ | 1878 | bidi_dir_t paragraph_dir; /* current paragraph direction */ |
| 1879 | EMACS_INT separator_limit; /* where paragraph separator should end */ | 1879 | EMACS_INT separator_limit; /* where paragraph separator should end */ |
| 1880 | EMACS_INT disp_pos; /* position of display string after ch */ | 1880 | EMACS_INT disp_pos; /* position of display string after ch */ |
| 1881 | int disp_prop_p; /* if non-zero, there really is a | ||
| 1882 | `display' property/string at disp_pos */ | ||
| 1881 | unsigned first_elt : 1; /* if non-zero, examine current char first */ | 1883 | unsigned first_elt : 1; /* if non-zero, examine current char first */ |
| 1882 | unsigned new_paragraph : 1; /* if non-zero, we expect a new paragraph */ | 1884 | unsigned new_paragraph : 1; /* if non-zero, we expect a new paragraph */ |
| 1883 | unsigned frame_window_p : 1; /* non-zero if displaying on a GUI frame */ | 1885 | unsigned frame_window_p : 1; /* non-zero if displaying on a GUI frame */ |
| @@ -3063,7 +3065,8 @@ extern Lisp_Object lookup_glyphless_char_display (int, struct it *); | |||
| 3063 | extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object, | 3065 | extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object, |
| 3064 | struct font *, int, int *); | 3066 | struct font *, int, int *); |
| 3065 | extern EMACS_INT compute_display_string_pos (struct text_pos *, | 3067 | extern EMACS_INT compute_display_string_pos (struct text_pos *, |
| 3066 | struct bidi_string_data *, int); | 3068 | struct bidi_string_data *, |
| 3069 | int, int *); | ||
| 3067 | extern EMACS_INT compute_display_string_end (EMACS_INT, | 3070 | extern EMACS_INT compute_display_string_end (EMACS_INT, |
| 3068 | struct bidi_string_data *); | 3071 | struct bidi_string_data *); |
| 3069 | 3072 | ||
diff --git a/src/keymap.c b/src/keymap.c index 0169276bef9..c461fdddbbc 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -1216,13 +1216,20 @@ binding KEY to DEF is added at the front of KEYMAP. */) | |||
| 1216 | 1216 | ||
| 1217 | keymap = get_keymap (cmd, 0, 1); | 1217 | keymap = get_keymap (cmd, 0, 1); |
| 1218 | if (!CONSP (keymap)) | 1218 | if (!CONSP (keymap)) |
| 1219 | /* We must use Fkey_description rather than just passing key to | 1219 | { |
| 1220 | error; key might be a vector, not a string. */ | 1220 | const char *trailing_esc = ((EQ (c, meta_prefix_char) && metized) |
| 1221 | error ("Key sequence %s starts with non-prefix key %s", | 1221 | ? (idx == 0 ? "ESC" : " ESC") |
| 1222 | SDATA (Fkey_description (key, Qnil)), | 1222 | : ""); |
| 1223 | SDATA (Fkey_description (Fsubstring (key, make_number (0), | 1223 | |
| 1224 | make_number (idx)), | 1224 | /* We must use Fkey_description rather than just passing key to |
| 1225 | Qnil))); | 1225 | error; key might be a vector, not a string. */ |
| 1226 | error ("Key sequence %s starts with non-prefix key %s%s", | ||
| 1227 | SDATA (Fkey_description (key, Qnil)), | ||
| 1228 | SDATA (Fkey_description (Fsubstring (key, make_number (0), | ||
| 1229 | make_number (idx)), | ||
| 1230 | Qnil)), | ||
| 1231 | trailing_esc); | ||
| 1232 | } | ||
| 1226 | } | 1233 | } |
| 1227 | } | 1234 | } |
| 1228 | 1235 | ||
diff --git a/src/lisp.h b/src/lisp.h index 2359ff177dd..14bd429a45e 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -2865,6 +2865,7 @@ extern void map_char_table_for_charset (void (*c_function) (Lisp_Object, Lisp_Ob | |||
| 2865 | Lisp_Object, Lisp_Object, | 2865 | Lisp_Object, Lisp_Object, |
| 2866 | Lisp_Object, struct charset *, | 2866 | Lisp_Object, struct charset *, |
| 2867 | unsigned, unsigned); | 2867 | unsigned, unsigned); |
| 2868 | extern Lisp_Object uniprop_table (Lisp_Object); | ||
| 2868 | extern void syms_of_chartab (void); | 2869 | extern void syms_of_chartab (void); |
| 2869 | 2870 | ||
| 2870 | /* Defined in print.c */ | 2871 | /* Defined in print.c */ |
diff --git a/src/xdisp.c b/src/xdisp.c index 22d353b840b..e7c3ac301ba 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -3139,13 +3139,10 @@ next_overlay_change (EMACS_INT pos) | |||
| 3139 | return endpos; | 3139 | return endpos; |
| 3140 | } | 3140 | } |
| 3141 | 3141 | ||
| 3142 | /* Record one cached display string position found recently by | 3142 | /* How many characters forward to search for a display property or |
| 3143 | compute_display_string_pos. */ | 3143 | display string. Enough for a screenful of 100 lines x 50 |
| 3144 | static EMACS_INT cached_disp_pos; | 3144 | characters in a line. */ |
| 3145 | static EMACS_INT cached_prev_pos = -1; | 3145 | #define MAX_DISP_SCAN 5000 |
| 3146 | static struct buffer *cached_disp_buffer; | ||
| 3147 | static int cached_disp_modiff; | ||
| 3148 | static int cached_disp_overlay_modiff; | ||
| 3149 | 3146 | ||
| 3150 | /* Return the character position of a display string at or after | 3147 | /* Return the character position of a display string at or after |
| 3151 | position specified by POSITION. If no display string exists at or | 3148 | position specified by POSITION. If no display string exists at or |
| @@ -3157,57 +3154,33 @@ static int cached_disp_overlay_modiff; | |||
| 3157 | on a GUI frame. */ | 3154 | on a GUI frame. */ |
| 3158 | EMACS_INT | 3155 | EMACS_INT |
| 3159 | compute_display_string_pos (struct text_pos *position, | 3156 | compute_display_string_pos (struct text_pos *position, |
| 3160 | struct bidi_string_data *string, int frame_window_p) | 3157 | struct bidi_string_data *string, |
| 3158 | int frame_window_p, int *disp_prop_p) | ||
| 3161 | { | 3159 | { |
| 3162 | /* OBJECT = nil means current buffer. */ | 3160 | /* OBJECT = nil means current buffer. */ |
| 3163 | Lisp_Object object = | 3161 | Lisp_Object object = |
| 3164 | (string && STRINGP (string->lstring)) ? string->lstring : Qnil; | 3162 | (string && STRINGP (string->lstring)) ? string->lstring : Qnil; |
| 3165 | Lisp_Object pos, spec; | 3163 | Lisp_Object pos, spec, limpos; |
| 3166 | int string_p = (string && (STRINGP (string->lstring) || string->s)); | 3164 | int string_p = (string && (STRINGP (string->lstring) || string->s)); |
| 3167 | EMACS_INT eob = string_p ? string->schars : ZV; | 3165 | EMACS_INT eob = string_p ? string->schars : ZV; |
| 3168 | EMACS_INT begb = string_p ? 0 : BEGV; | 3166 | EMACS_INT begb = string_p ? 0 : BEGV; |
| 3169 | EMACS_INT bufpos, charpos = CHARPOS (*position); | 3167 | EMACS_INT bufpos, charpos = CHARPOS (*position); |
| 3168 | EMACS_INT lim = | ||
| 3169 | (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob; | ||
| 3170 | struct text_pos tpos; | 3170 | struct text_pos tpos; |
| 3171 | struct buffer *b; | 3171 | struct buffer *b; |
| 3172 | 3172 | ||
| 3173 | *disp_prop_p = 1; | ||
| 3174 | |||
| 3173 | if (charpos >= eob | 3175 | if (charpos >= eob |
| 3174 | /* We don't support display properties whose values are strings | 3176 | /* We don't support display properties whose values are strings |
| 3175 | that have display string properties. */ | 3177 | that have display string properties. */ |
| 3176 | || string->from_disp_str | 3178 | || string->from_disp_str |
| 3177 | /* C strings cannot have display properties. */ | 3179 | /* C strings cannot have display properties. */ |
| 3178 | || (string->s && !STRINGP (object))) | 3180 | || (string->s && !STRINGP (object))) |
| 3179 | return eob; | ||
| 3180 | |||
| 3181 | /* Check the cached values. */ | ||
| 3182 | if (!STRINGP (object)) | ||
| 3183 | { | 3181 | { |
| 3184 | if (NILP (object)) | 3182 | *disp_prop_p = 0; |
| 3185 | b = current_buffer; | 3183 | return eob; |
| 3186 | else | ||
| 3187 | b = XBUFFER (object); | ||
| 3188 | if (b == cached_disp_buffer | ||
| 3189 | && BUF_MODIFF (b) == cached_disp_modiff | ||
| 3190 | && BUF_OVERLAY_MODIFF (b) == cached_disp_overlay_modiff | ||
| 3191 | && !b->clip_changed) | ||
| 3192 | { | ||
| 3193 | if (cached_prev_pos >= 0 | ||
| 3194 | && cached_prev_pos < charpos && charpos <= cached_disp_pos) | ||
| 3195 | return cached_disp_pos; | ||
| 3196 | /* Handle overstepping either end of the known interval. */ | ||
| 3197 | if (charpos > cached_disp_pos) | ||
| 3198 | cached_prev_pos = cached_disp_pos; | ||
| 3199 | else /* charpos <= cached_prev_pos */ | ||
| 3200 | cached_prev_pos = max (charpos - 1, 0); | ||
| 3201 | } | ||
| 3202 | |||
| 3203 | /* Record new values in the cache. */ | ||
| 3204 | if (b != cached_disp_buffer) | ||
| 3205 | { | ||
| 3206 | cached_disp_buffer = b; | ||
| 3207 | cached_prev_pos = max (charpos - 1, 0); | ||
| 3208 | } | ||
| 3209 | cached_disp_modiff = BUF_MODIFF (b); | ||
| 3210 | cached_disp_overlay_modiff = BUF_OVERLAY_MODIFF (b); | ||
| 3211 | } | 3184 | } |
| 3212 | 3185 | ||
| 3213 | /* If the character at CHARPOS is where the display string begins, | 3186 | /* If the character at CHARPOS is where the display string begins, |
| @@ -3226,22 +3199,24 @@ compute_display_string_pos (struct text_pos *position, | |||
| 3226 | && handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, | 3199 | && handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, |
| 3227 | frame_window_p)) | 3200 | frame_window_p)) |
| 3228 | { | 3201 | { |
| 3229 | if (!STRINGP (object)) | ||
| 3230 | cached_disp_pos = charpos; | ||
| 3231 | return charpos; | 3202 | return charpos; |
| 3232 | } | 3203 | } |
| 3233 | 3204 | ||
| 3234 | /* Look forward for the first character with a `display' property | 3205 | /* Look forward for the first character with a `display' property |
| 3235 | that will replace the underlying text when displayed. */ | 3206 | that will replace the underlying text when displayed. */ |
| 3207 | limpos = make_number (lim); | ||
| 3236 | do { | 3208 | do { |
| 3237 | pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil); | 3209 | pos = Fnext_single_char_property_change (pos, Qdisplay, object, limpos); |
| 3238 | CHARPOS (tpos) = XFASTINT (pos); | 3210 | CHARPOS (tpos) = XFASTINT (pos); |
| 3211 | if (CHARPOS (tpos) >= lim) | ||
| 3212 | { | ||
| 3213 | *disp_prop_p = 0; | ||
| 3214 | break; | ||
| 3215 | } | ||
| 3239 | if (STRINGP (object)) | 3216 | if (STRINGP (object)) |
| 3240 | BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos)); | 3217 | BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos)); |
| 3241 | else | 3218 | else |
| 3242 | BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos)); | 3219 | BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos)); |
| 3243 | if (CHARPOS (tpos) >= eob) | ||
| 3244 | break; | ||
| 3245 | spec = Fget_char_property (pos, Qdisplay, object); | 3220 | spec = Fget_char_property (pos, Qdisplay, object); |
| 3246 | if (!STRINGP (object)) | 3221 | if (!STRINGP (object)) |
| 3247 | bufpos = CHARPOS (tpos); | 3222 | bufpos = CHARPOS (tpos); |
| @@ -3249,8 +3224,6 @@ compute_display_string_pos (struct text_pos *position, | |||
| 3249 | || !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, | 3224 | || !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, |
| 3250 | frame_window_p)); | 3225 | frame_window_p)); |
| 3251 | 3226 | ||
| 3252 | if (!STRINGP (object)) | ||
| 3253 | cached_disp_pos = CHARPOS (tpos); | ||
| 3254 | return CHARPOS (tpos); | 3227 | return CHARPOS (tpos); |
| 3255 | } | 3228 | } |
| 3256 | 3229 | ||