summaryrefslogtreecommitdiff
path: root/src/bidi.c
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2014-09-26 12:24:15 +0300
committerEli Zaretskii <eliz@gnu.org>2014-09-26 12:24:15 +0300
commit0df5896cd2851947d2bc186ff82c5a43e7bdd0c7 (patch)
tree4dd746f90b2855552ec4b7583e5c9a3a7ec48501 /src/bidi.c
parent027fa018a9cf6a0454d985a427e68bc72c70299d (diff)
downloademacs-0df5896cd2851947d2bc186ff82c5a43e7bdd0c7.tar.gz
Fix bidi_resolve_explicit when one directional control follows another.
Diffstat (limited to 'src/bidi.c')
-rw-r--r--src/bidi.c176
1 files changed, 88 insertions, 88 deletions
diff --git a/src/bidi.c b/src/bidi.c
index 0614f5f0263..7beadb25455 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -1680,7 +1680,7 @@ static int
bidi_resolve_explicit (struct bidi_it *bidi_it)
{
int curchar;
- bidi_type_t type, typ1, prev_type = UNKNOWN_BT;;
+ bidi_type_t type, typ1, prev_type = UNKNOWN_BT;
int current_level;
int new_level;
bidi_dir_t override;
@@ -1743,12 +1743,13 @@ bidi_resolve_explicit (struct bidi_it *bidi_it)
bidi_it->bytepos += bidi_it->ch_len;
prev_type = bidi_it->orig_type;
}
+ else /* EOB or end of string */
+ prev_type = NEUTRAL_B;
current_level = bidi_it->level_stack[bidi_it->stack_idx].level; /* X1 */
override = bidi_it->level_stack[bidi_it->stack_idx].override;
isolate_status = bidi_it->level_stack[bidi_it->stack_idx].isolate_status;
new_level = current_level;
- bidi_it->resolved_level = new_level;
if (bidi_it->charpos >= (string_p ? bidi_it->string.schars : ZV))
{
@@ -1760,6 +1761,82 @@ bidi_resolve_explicit (struct bidi_it *bidi_it)
}
else
{
+ /* LRI, RLI, and FSI increment, and PDF decrements, the
+ embedding level of the _following_ characters, so we must
+ first look at the type of the previous character to support
+ that. */
+ switch (prev_type)
+ {
+ case FSI: /* X5c */
+ end = string_p ? bidi_it->string.schars : ZV;
+ disp_pos = bidi_it->disp_pos;
+ disp_prop = bidi_it->disp_prop;
+ nchars = bidi_it->nchars;
+ ch_len = bidi_it->ch_len;
+ typ1 = find_first_strong_char (bidi_it->charpos,
+ bidi_it->bytepos, end,
+ &disp_pos, &disp_prop,
+ &bidi_it->string, bidi_it->w,
+ string_p, bidi_it->frame_window_p,
+ &ch_len, &nchars, true);
+ if (typ1 != STRONG_R && typ1 != STRONG_AL)
+ {
+ type = LRI;
+ goto fsi_as_lri;
+ }
+ else
+ type = RLI;
+ /* FALLTHROUGH */
+ case RLI: /* X5a */
+ if (override == NEUTRAL_DIR)
+ bidi_it->type_after_w1 = type;
+ else /* Unicode 8.0 correction. */
+ bidi_it->type_after_w1 = (override == L2R ? STRONG_L : STRONG_R);
+ bidi_check_type (bidi_it->type_after_w1);
+ if (current_level < BIDI_MAXDEPTH
+ && bidi_it->invalid_levels == 0
+ && bidi_it->invalid_isolates == 0)
+ {
+ new_level = ((current_level + 1) & ~1) + 1;
+ bidi_it->isolate_level++;
+ bidi_push_embedding_level (bidi_it, new_level,
+ NEUTRAL_DIR, true);
+ }
+ else
+ bidi_it->invalid_isolates++;
+ break;
+ case LRI: /* X5b */
+ fsi_as_lri:
+ if (override == NEUTRAL_DIR)
+ bidi_it->type_after_w1 = type;
+ else /* Unicode 8.0 correction. */
+ bidi_it->type_after_w1 = (override == L2R ? STRONG_L : STRONG_R);
+ bidi_check_type (bidi_it->type_after_w1);
+ if (current_level < BIDI_MAXDEPTH - 1
+ && bidi_it->invalid_levels == 0
+ && bidi_it->invalid_isolates == 0)
+ {
+ new_level = ((current_level + 2) & ~1);
+ bidi_it->isolate_level++;
+ bidi_push_embedding_level (bidi_it, new_level,
+ NEUTRAL_DIR, true);
+ }
+ else
+ bidi_it->invalid_isolates++;
+ break;
+ case PDF: /* X7 */
+ if (!bidi_it->invalid_isolates)
+ {
+ if (bidi_it->invalid_levels)
+ bidi_it->invalid_levels--;
+ else if (!isolate_status && bidi_it->stack_idx >= 1)
+ new_level = bidi_pop_embedding_level (bidi_it);
+ }
+ break;
+ default:
+ /* Nothing. */
+ break;
+ }
/* Fetch the character at BYTEPOS. If it is covered by a
display string, treat the entire run of covered characters as
a single character u+FFFC. */
@@ -1770,6 +1847,7 @@ bidi_resolve_explicit (struct bidi_it *bidi_it)
&bidi_it->ch_len, &bidi_it->nchars);
}
bidi_it->ch = curchar;
+ bidi_it->resolved_level = new_level;
/* Don't apply directional override here, as all the types we handle
below will not be affected by the override anyway, and we need
@@ -1788,13 +1866,13 @@ bidi_resolve_explicit (struct bidi_it *bidi_it)
bidi_it->type_after_w1 = type;
bidi_check_type (bidi_it->type_after_w1);
type = WEAK_BN; /* X9/Retaining */
- if (current_level < BIDI_MAXDEPTH
+ if (new_level < BIDI_MAXDEPTH
&& bidi_it->invalid_levels == 0
&& bidi_it->invalid_isolates == 0)
{
/* Compute the least odd embedding level greater than
the current level. */
- new_level = ((current_level + 1) & ~1) + 1;
+ new_level = ((new_level + 1) & ~1) + 1;
if (bidi_it->type_after_w1 == RLE)
override = NEUTRAL_DIR;
else
@@ -1813,13 +1891,13 @@ bidi_resolve_explicit (struct bidi_it *bidi_it)
bidi_it->type_after_w1 = type;
bidi_check_type (bidi_it->type_after_w1);
type = WEAK_BN; /* X9/Retaining */
- if (current_level < BIDI_MAXDEPTH - 1
+ if (new_level < BIDI_MAXDEPTH - 1
&& bidi_it->invalid_levels == 0
&& bidi_it->invalid_isolates == 0)
{
/* Compute the least even embedding level greater than
the current level. */
- new_level = ((current_level + 2) & ~1);
+ new_level = ((new_level + 2) & ~1);
if (bidi_it->type_after_w1 == LRE)
override = NEUTRAL_DIR;
else
@@ -1835,10 +1913,7 @@ bidi_resolve_explicit (struct bidi_it *bidi_it)
break;
case PDI: /* X6a */
if (bidi_it->invalid_isolates)
- {
- bidi_it->invalid_isolates--;
- new_level = current_level;
- }
+ bidi_it->invalid_isolates--;
else if (bidi_it->isolate_level > 0)
{
bidi_it->invalid_levels = 0;
@@ -1863,83 +1938,8 @@ bidi_resolve_explicit (struct bidi_it *bidi_it)
type = WEAK_BN; /* X9/Retaining */
break;
default:
- /* LRI, RLI, and FSI increment, and PDF decrements, the
- embedding level of the _following_ characters, so we must
- look at the type of the previous character to support
- that. */
- switch (prev_type)
- {
- case FSI: /* X5c */
- end = string_p ? bidi_it->string.schars : ZV;
- disp_pos = bidi_it->disp_pos;
- disp_prop = bidi_it->disp_prop;
- nchars = bidi_it->nchars;
- ch_len = bidi_it->ch_len;
- typ1 = find_first_strong_char (bidi_it->charpos,
- bidi_it->bytepos, end,
- &disp_pos, &disp_prop,
- &bidi_it->string, bidi_it->w,
- string_p, bidi_it->frame_window_p,
- &ch_len, &nchars, true);
- if (typ1 != STRONG_R && typ1 != STRONG_AL)
- {
- type = LRI;
- goto fsi_as_lri;
- }
- else
- type = RLI;
- /* FALLTHROUGH */
- case RLI: /* X5a */
- if (override == NEUTRAL_DIR)
- bidi_it->type_after_w1 = type;
- else /* Unicode 8.0 correction. */
- bidi_it->type_after_w1 = (override == L2R ? STRONG_L : STRONG_R);
- bidi_check_type (bidi_it->type_after_w1);
- if (current_level < BIDI_MAXDEPTH
- && bidi_it->invalid_levels == 0
- && bidi_it->invalid_isolates == 0)
- {
- new_level = ((current_level + 1) & ~1) + 1;
- bidi_it->isolate_level++;
- bidi_push_embedding_level (bidi_it, new_level,
- NEUTRAL_DIR, true);
- }
- else
- bidi_it->invalid_isolates++;
- break;
- case LRI: /* X5b */
- fsi_as_lri:
- if (override == NEUTRAL_DIR)
- bidi_it->type_after_w1 = type;
- else /* Unicode 8.0 correction. */
- bidi_it->type_after_w1 = (override == L2R ? STRONG_L : STRONG_R);
- bidi_check_type (bidi_it->type_after_w1);
- if (current_level < BIDI_MAXDEPTH - 1
- && bidi_it->invalid_levels == 0
- && bidi_it->invalid_isolates == 0)
- {
- new_level = ((current_level + 2) & ~1);
- bidi_it->isolate_level++;
- bidi_push_embedding_level (bidi_it, new_level,
- NEUTRAL_DIR, true);
- }
- else
- bidi_it->invalid_isolates++;
- break;
- case PDF: /* X7 */
- if (!bidi_it->invalid_isolates)
- {
- if (bidi_it->invalid_levels)
- bidi_it->invalid_levels--;
- else if (!isolate_status && bidi_it->stack_idx >= 1)
- new_level = bidi_pop_embedding_level (bidi_it);
- }
- bidi_it->resolved_level = new_level;
- break;
- default:
- /* Nothing. */
- break;
- }
+ /* Nothing. */
+ break;
}
bidi_it->type = type;
@@ -1959,7 +1959,7 @@ bidi_resolve_explicit (struct bidi_it *bidi_it)
static bool
bidi_isolate_fmt_char (bidi_type_t ch_type)
{
- return (ch_type == LRI || ch_type == RLI || ch_type == PDI);
+ return (ch_type == LRI || ch_type == RLI || ch_type == PDI || ch_type == FSI);
}
/* Advance in the buffer/string, resolve weak types and return the