aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2016-03-06 18:14:46 +0200
committerEli Zaretskii2016-03-06 18:14:46 +0200
commitcc057e43130780e566f4b901a59a88edb3f5130d (patch)
tree085a5bb85eb5a019f8d17a837a6110ff58a3ab55 /src
parente51b27ec2ce214ef3d8377a27ee9d857bcc66afc (diff)
downloademacs-cc057e43130780e566f4b901a59a88edb3f5130d.tar.gz
emacs-cc057e43130780e566f4b901a59a88edb3f5130d.zip
Speed up redisplay of binary files with long series of nulls
* src/bidi.c (bidi_resolve_weak): Avoid entering a loop searching for a character needed for resolving the type of a series of BN and ET characters, as required by rule W5 of UAX#9, if the results of the resolution are known in advance, because we are at level zero, and the previous strong character was L. (bidi_resolve_neutral): Partially resurrect the optimization for a long series of control characters in an otherwise strictly L2R text. (bidi_level_of_next_char): Don't enter the loop that searches for a paragraph separator if the current character is already at base embedding level. (Bug#22739)
Diffstat (limited to 'src')
-rw-r--r--src/bidi.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/src/bidi.c b/src/bidi.c
index e7787054e23..9797517e420 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -2318,7 +2318,31 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
2318 if (bidi_it->next_en_type == WEAK_EN) /* ET/BN with EN after it */ 2318 if (bidi_it->next_en_type == WEAK_EN) /* ET/BN with EN after it */
2319 type = WEAK_EN; 2319 type = WEAK_EN;
2320 } 2320 }
2321 else if (bidi_it->next_en_pos >=0) 2321 else if (type == WEAK_BN
2322 /* This condition is for the following important case:
2323
2324 . we are at level zero
2325 . either previous strong character was L,
2326 or we've seen no strong characters since sos
2327 and the base paragraph direction is L2R
2328 . this BN is NOT a bidi directional control
2329
2330 For such a situation, either this BN will be
2331 converted to EN per W5, and then to L by virtue
2332 of W7; or it will become ON per W6, and then L
2333 because of N1/N2. So we take a shortcut here
2334 and make it L right away, to avoid the
2335 potentially costly loop below. This is
2336 important when the buffer has a long series of
2337 control characters, like binary nulls, and no
2338 R2L characters at all. */
2339 && new_level == 0
2340 && !bidi_explicit_dir_char (bidi_it->ch)
2341 && ((bidi_it->last_strong.type == STRONG_L)
2342 || (bidi_it->last_strong.type == UNKNOWN_BT
2343 && bidi_it->sos == L2R)))
2344 type = STRONG_L;
2345 else if (bidi_it->next_en_pos >= 0)
2322 { 2346 {
2323 /* We overstepped the last known position for ET 2347 /* We overstepped the last known position for ET
2324 resolution but there could be other such characters 2348 resolution but there could be other such characters
@@ -2981,9 +3005,10 @@ bidi_resolve_neutral (struct bidi_it *bidi_it)
2981 entering the expensive loop in the "else" clause. */ 3005 entering the expensive loop in the "else" clause. */
2982 else if (current_level == 0 3006 else if (current_level == 0
2983 && bidi_it->prev_for_neutral.type == STRONG_L 3007 && bidi_it->prev_for_neutral.type == STRONG_L
2984 && type != WEAK_BN 3008 && (ASCII_CHAR_P (bidi_it->ch)
2985 && !bidi_explicit_dir_char (bidi_it->ch) 3009 || (type != WEAK_BN
2986 && !bidi_isolate_fmt_char (type)) 3010 && !bidi_explicit_dir_char (bidi_it->ch)
3011 && !bidi_isolate_fmt_char (type))))
2987 type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type, 3012 type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type,
2988 STRONG_L, current_level); 3013 STRONG_L, current_level);
2989 else if (/* current level is 1 */ 3014 else if (/* current level is 1 */
@@ -3163,7 +3188,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
3163 } 3188 }
3164 } 3189 }
3165 3190
3166 /* Perhaps the character we want is already cached s fully resolved. 3191 /* Perhaps the character we want is already cached as fully resolved.
3167 If it is, the call to bidi_cache_find below will return a type 3192 If it is, the call to bidi_cache_find below will return a type
3168 other than UNKNOWN_BT. */ 3193 other than UNKNOWN_BT. */
3169 if (bidi_cache_idx > bidi_cache_start && !bidi_it->first_elt) 3194 if (bidi_cache_idx > bidi_cache_start && !bidi_it->first_elt)
@@ -3223,7 +3248,10 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
3223 if ((bidi_it->orig_type == NEUTRAL_WS 3248 if ((bidi_it->orig_type == NEUTRAL_WS
3224 || bidi_it->orig_type == WEAK_BN 3249 || bidi_it->orig_type == WEAK_BN
3225 || bidi_isolate_fmt_char (bidi_it->orig_type)) 3250 || bidi_isolate_fmt_char (bidi_it->orig_type))
3226 && bidi_it->next_for_ws.charpos < bidi_it->charpos) 3251 && bidi_it->next_for_ws.charpos < bidi_it->charpos
3252 /* If this character is already at base level, we don't need to
3253 reset it, so avoid the potentially costly loop below. */
3254 && level != bidi_it->level_stack[0].level)
3227 { 3255 {
3228 int ch; 3256 int ch;
3229 ptrdiff_t clen = bidi_it->ch_len; 3257 ptrdiff_t clen = bidi_it->ch_len;