Commit 7b5d6677 authored by Eli Zaretskii's avatar Eli Zaretskii
Browse files

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.
parent 1ebc9c87
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)
......
......@@ -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;
......
......@@ -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 */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment