summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2011-10-20 14:39:52 +0200
committerEli Zaretskii <eliz@gnu.org>2011-10-20 14:39:52 +0200
commit7b5d6677eca241b608f32b1de8d60e03758ec157 (patch)
treeacb4c67188e9ca5e819c44350a3907812638a904 /src
parent1ebc9c872623dab285842f273a18937223f4d3c6 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog13
-rw-r--r--src/bidi.c42
-rw-r--r--src/dispextern.h3
3 files changed, 43 insertions, 15 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 36b205a120..3f9b5beeab 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,16 @@
+2011-10-20 Eli Zaretskii <eliz@gnu.org>
+
+ * 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 <eggert@cs.ucla.edu>
Time zone name fixes for non-ASCII locales (Bug#641, Bug#9794)
diff --git a/src/bidi.c b/src/bidi.c
index 29e3c81731..d13baed63e 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 3c157371ef..dd5f67d2d1 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 */