diff options
| author | Eli Zaretskii | 2012-07-15 17:41:08 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2012-07-15 17:41:08 +0300 |
| commit | ce811ad97550ff70e2bd71e1ada496b4715d9b08 (patch) | |
| tree | f953b1a117509e1c42d743c89e3bf8945aeb37ec /src | |
| parent | c9adfeaa04c1b70bbf1b22b8b77b3bb9b804fe6e (diff) | |
| download | emacs-ce811ad97550ff70e2bd71e1ada496b4715d9b08.tar.gz emacs-ce811ad97550ff70e2bd71e1ada496b4715d9b08.zip | |
Fix bug #11943 with slow redisplay in large paragraphs full of weak characters.
src/bidi.c (MAX_STRONG_CHAR_SEARCH): New macro.
(bidi_paragraph_init): Use it to limit search forward for a strong
directional character in abnormally large paragraphs full of
neutral or weak characters.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 7 | ||||
| -rw-r--r-- | src/bidi.c | 20 |
2 files changed, 23 insertions, 4 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 5c946e62373..d7deaf9244c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | 2012-07-15 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * bidi.c (MAX_STRONG_CHAR_SEARCH): New macro. | ||
| 4 | (bidi_paragraph_init): Use it to limit search forward for a strong | ||
| 5 | directional character in abnormally large paragraphs full of | ||
| 6 | neutral or weak characters. (Bug#11943) | ||
| 7 | |||
| 1 | 2012-07-15 Stefano Facchini <stefano.facchini@gmail.com> (tiny change) | 8 | 2012-07-15 Stefano Facchini <stefano.facchini@gmail.com> (tiny change) |
| 2 | 9 | ||
| 3 | * gtkutil.c (xg_create_tool_bar): Apply "primary-toolbar" style to | 10 | * gtkutil.c (xg_create_tool_bar): Apply "primary-toolbar" style to |
diff --git a/src/bidi.c b/src/bidi.c index 0fa1cc2b0e2..4df585d4f48 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -1123,6 +1123,12 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte) | |||
| 1123 | return pos_byte; | 1123 | return pos_byte; |
| 1124 | } | 1124 | } |
| 1125 | 1125 | ||
| 1126 | /* On a 3.4 GHz machine, searching forward for a strong directional | ||
| 1127 | character in a long paragraph full of weaks or neutrals takes about | ||
| 1128 | 1 ms for each 20K characters. The number below limits each call to | ||
| 1129 | bidi_paragraph_init to less than 10 ms even on slow machines. */ | ||
| 1130 | #define MAX_STRONG_CHAR_SEARCH 100000 | ||
| 1131 | |||
| 1126 | /* Determine the base direction, a.k.a. base embedding level, of the | 1132 | /* Determine the base direction, a.k.a. base embedding level, of the |
| 1127 | paragraph we are about to iterate through. If DIR is either L2R or | 1133 | paragraph we are about to iterate through. If DIR is either L2R or |
| 1128 | R2L, just use that. Otherwise, determine the paragraph direction | 1134 | R2L, just use that. Otherwise, determine the paragraph direction |
| @@ -1218,6 +1224,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) | |||
| 1218 | /* The following loop is run more than once only if NO_DEFAULT_P | 1224 | /* The following loop is run more than once only if NO_DEFAULT_P |
| 1219 | is non-zero, and only if we are iterating on a buffer. */ | 1225 | is non-zero, and only if we are iterating on a buffer. */ |
| 1220 | do { | 1226 | do { |
| 1227 | ptrdiff_t pos1; | ||
| 1228 | |||
| 1221 | bytepos = pstartbyte; | 1229 | bytepos = pstartbyte; |
| 1222 | if (!string_p) | 1230 | if (!string_p) |
| 1223 | pos = BYTE_TO_CHAR (bytepos); | 1231 | pos = BYTE_TO_CHAR (bytepos); |
| @@ -1226,11 +1234,15 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) | |||
| 1226 | bidi_it->frame_window_p, &ch_len, &nchars); | 1234 | bidi_it->frame_window_p, &ch_len, &nchars); |
| 1227 | type = bidi_get_type (ch, NEUTRAL_DIR); | 1235 | type = bidi_get_type (ch, NEUTRAL_DIR); |
| 1228 | 1236 | ||
| 1237 | pos1 = pos; | ||
| 1229 | for (pos += nchars, bytepos += ch_len; | 1238 | for (pos += nchars, bytepos += ch_len; |
| 1230 | (bidi_get_category (type) != STRONG) | 1239 | ((bidi_get_category (type) != STRONG) |
| 1231 | || (bidi_ignore_explicit_marks_for_paragraph_level | 1240 | || (bidi_ignore_explicit_marks_for_paragraph_level |
| 1232 | && (type == RLE || type == RLO | 1241 | && (type == RLE || type == RLO |
| 1233 | || type == LRE || type == LRO)); | 1242 | || type == LRE || type == LRO))) |
| 1243 | /* Stop when searched too far into an abnormally large | ||
| 1244 | paragraph full of weak or neutral characters. */ | ||
| 1245 | && pos - pos1 < MAX_STRONG_CHAR_SEARCH; | ||
| 1234 | type = bidi_get_type (ch, NEUTRAL_DIR)) | 1246 | type = bidi_get_type (ch, NEUTRAL_DIR)) |
| 1235 | { | 1247 | { |
| 1236 | if (pos >= end) | 1248 | if (pos >= end) |