From 7b5d6677eca241b608f32b1de8d60e03758ec157 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 20 Oct 2011 14:39:52 +0200 Subject: [PATCH] Improve the speedup of bidi display introduced in 2011-10-18T16:56:09Z!eliz@gnu.org for bug#9771. src/dispextern.h (struct bidi_it): New member next_en_type. src/bidi.c (bidi_line_init): Initialize the next_en_type member. (bidi_resolve_explicit_1): When next_en_pos is valid for the current character, check also for next_en_type being WEAK_EN. (bidi_resolve_weak): Don't enter the expensive loop if the current position is before next_en_pos. Record the bidi type of the first non-ET, non-BN character we find, in addition to its position. (bidi_level_of_next_char): Invalidate next_en_type when next_en_pos is over-stepped. --- src/ChangeLog | 13 +++++++++++++ src/bidi.c | 42 ++++++++++++++++++++++++++++-------------- src/dispextern.h | 3 ++- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 36b205a120d..3f9b5beeab6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2011-10-20 Eli Zaretskii + + * dispextern.h (struct bidi_it): New member next_en_type. + + * bidi.c (bidi_line_init): Initialize the next_en_type member. + (bidi_resolve_explicit_1): When next_en_pos is valid for the + current character, check also for next_en_type being WEAK_EN. + (bidi_resolve_weak): Don't enter the expensive loop if the current + position is before next_en_pos. Record the bidi type of the first + non-ET, non-BN character we find, in addition to its position. + (bidi_level_of_next_char): Invalidate next_en_type when + next_en_pos is over-stepped. + 2011-10-20 Paul Eggert Time zone name fixes for non-ASCII locales (Bug#641, Bug#9794) diff --git a/src/bidi.c b/src/bidi.c index 29e3c817318..d13baed63ed 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -849,6 +849,7 @@ bidi_line_init (struct bidi_it *bidi_it) /* Setting this to zero will force its recomputation the first time we need it for W5. */ bidi_it->next_en_pos = 0; + bidi_it->next_en_type = UNKNOWN_BT; bidi_it->next_for_ws.type = UNKNOWN_BT; bidi_set_sor_type (bidi_it, (bidi_it->paragraph_dir == R2L ? 1 : 0), @@ -1437,7 +1438,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) } } else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ - || bidi_it->next_en_pos > bidi_it->charpos) + || (bidi_it->next_en_pos > bidi_it->charpos + && bidi_it->next_en_type == WEAK_EN)) type = WEAK_EN; break; case LRE: /* X3 */ @@ -1473,7 +1475,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) } } else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ - || bidi_it->next_en_pos > bidi_it->charpos) + || (bidi_it->next_en_pos > bidi_it->charpos + && bidi_it->next_en_type == WEAK_EN)) type = WEAK_EN; break; case PDF: /* X7 */ @@ -1499,7 +1502,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) } } else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ - || bidi_it->next_en_pos > bidi_it->charpos) + || (bidi_it->next_en_pos > bidi_it->charpos + && bidi_it->next_en_type == WEAK_EN)) type = WEAK_EN; break; default: @@ -1731,10 +1735,15 @@ bidi_resolve_weak (struct bidi_it *bidi_it) else if (type == WEAK_ET /* W5: ET with EN before or after it */ || type == WEAK_BN) /* W5/Retaining */ { - if (bidi_it->prev.type_after_w1 == WEAK_EN /* ET/BN w/EN before it */ - || bidi_it->next_en_pos > bidi_it->charpos) + if (bidi_it->prev.type_after_w1 == WEAK_EN) /* ET/BN w/EN before it */ type = WEAK_EN; - else if (bidi_it->next_en_pos >=0) /* W5: ET/BN with EN after it. */ + else if (bidi_it->next_en_pos > bidi_it->charpos + && bidi_it->next_en_type != WEAK_BN) + { + if (bidi_it->next_en_type == WEAK_EN) /* ET/BN with EN after it */ + type = WEAK_EN; + } + else if (bidi_it->next_en_pos >=0) { EMACS_INT en_pos = bidi_it->charpos + bidi_it->nchars; const unsigned char *s = (STRINGP (bidi_it->string.lstring) @@ -1763,25 +1772,27 @@ bidi_resolve_weak (struct bidi_it *bidi_it) en_pos = bidi_it->charpos; bidi_copy_it (bidi_it, &saved_it); } + /* Remember this position, to speed up processing of the + next ETs. */ + bidi_it->next_en_pos = en_pos; if (type_of_next == WEAK_EN) { /* If the last strong character is AL, the EN we've found will become AN when we get to it (W2). */ - if (bidi_it->last_strong.type_after_w1 != STRONG_AL) - { - type = WEAK_EN; - /* Remember this EN position, to speed up processing - of the next ETs. */ - bidi_it->next_en_pos = en_pos; - } + if (bidi_it->last_strong.type_after_w1 == STRONG_AL) + type_of_next = WEAK_AN; else if (type == WEAK_BN) type = NEUTRAL_ON; /* W6/Retaining */ + else + type = WEAK_EN; } else if (type_of_next == NEUTRAL_B) /* Record the fact that there are no more ENs from here to the end of paragraph, to avoid entering the loop above ever again in this paragraph. */ bidi_it->next_en_pos = -1; + /* Record the type of the character where we ended our search. */ + bidi_it->next_en_type = type_of_next; } } } @@ -2053,7 +2064,10 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) bidi_it->next_for_neutral.type = UNKNOWN_BT; if (bidi_it->next_en_pos >= 0 && bidi_it->charpos >= bidi_it->next_en_pos) - bidi_it->next_en_pos = 0; + { + bidi_it->next_en_pos = 0; + bidi_it->next_en_type = UNKNOWN_BT; + } if (bidi_it->next_for_ws.type != UNKNOWN_BT && bidi_it->charpos >= bidi_it->next_for_ws.charpos) bidi_it->next_for_ws.type = UNKNOWN_BT; diff --git a/src/dispextern.h b/src/dispextern.h index 3c157371ef3..dd5f67d2d10 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1856,7 +1856,8 @@ struct bidi_it { struct bidi_saved_info next_for_neutral; /* surrounding characters for... */ struct bidi_saved_info prev_for_neutral; /* ...resolving neutrals */ struct bidi_saved_info next_for_ws; /* character after sequence of ws */ - EMACS_INT next_en_pos; /* position of next EN char for ET */ + EMACS_INT next_en_pos; /* pos. of next char for determining ET type */ + bidi_type_t next_en_type; /* type of char at next_en_pos */ EMACS_INT ignore_bn_limit; /* position until which to ignore BNs */ bidi_dir_t sor; /* direction of start-of-run in effect */ int scan_dir; /* direction of text scan, 1: forw, -1: back */ -- 2.39.2