diff options
author | Eli Zaretskii <eliz@gnu.org> | 2014-08-30 15:19:26 +0300 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2014-08-30 15:19:26 +0300 |
commit | 991b257bf8e216f036b30c5a79fdae63b4954e02 (patch) | |
tree | b445ca8af25dac6178db0b2cc9a465f9718848be | |
parent | 5d84f5d6985b2f9d146519d3c8a2147fa3d9aafd (diff) | |
download | emacs-991b257bf8e216f036b30c5a79fdae63b4954e02.tar.gz |
Updated pushing and popping the bidi stack, and sos calculations.
Added the necessary members to bidi_stack.
-rw-r--r-- | src/bidi.c | 66 | ||||
-rw-r--r-- | src/dispextern.h | 13 |
2 files changed, 65 insertions, 14 deletions
diff --git a/src/bidi.c b/src/bidi.c index e01b77d0e96..a99fd748981 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -407,7 +407,6 @@ bidi_set_sos_type (struct bidi_it *bidi_it, int level_before, int level_after) /* FIXME: should the default sos direction be user selectable? */ bidi_it->sos = ((higher_level & 1) != 0 ? R2L : L2R); - /* FIXME: This needs to be reviewed!! */ bidi_it->prev.type = UNKNOWN_BT; bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 = bidi_it->last_strong.orig_type = UNKNOWN_BT; @@ -425,21 +424,55 @@ static void bidi_push_embedding_level (struct bidi_it *bidi_it, int level, bidi_dir_t override, bool isolate_status) { + struct bidi_stack st; + bidi_it->stack_idx++; eassert (bidi_it->stack_idx < BIDI_MAXDEPTH+2+1); - bidi_it->level_stack[bidi_it->stack_idx].level = level; - bidi_it->level_stack[bidi_it->stack_idx].override = override; - bidi_it->level_stack[bidi_it->stack_idx].isolate_status = isolate_status; + st = bidi_it->level_stack[bidi_it->stack_idx]; + st.level = level; + st.override = override; + st.isolate_status = isolate_status; + if (isolate_status) + { + st.prev = bidi_it->prev; + st.last_strong = bidi_it->last_strong; + st.prev_for_neutral = bidi_it->prev_for_neutral; + st.next_for_neutral = bidi_it->next_for_neutral; + st.next_for_ws = bidi_it->next_for_ws; + st.next_en_pos = bidi_it->next_en_pos; + st.next_en_type = bidi_it->next_en_type; + st.sos = bidi_it->sos; + } } -/* Pop the embedding level and directional override status from the - stack, and return the new level. */ +/* Pop from the stack the embedding level, the directional override + status, and optionally saved information for the isolating run + sequence. Return the new level. */ static int bidi_pop_embedding_level (struct bidi_it *bidi_it) { - /* UAX#9 says to ignore invalid PDFs. */ + /* UAX#9 says to ignore invalid PDFs (X7, last bullet) + and PDIs (X6a, 2nd bullet). */ if (bidi_it->stack_idx > 0) - bidi_it->stack_idx--; + { + bool isolate_status + = bidi_it->level_stack[bidi_it->stack_idx].isolate_status; + struct bidi_stack st; + + st = bidi_it->level_stack[bidi_it->stack_idx]; + if (isolate_status) + { + bidi_it->prev = st.prev; + bidi_it->last_strong = st.last_strong; + bidi_it->prev_for_neutral = st.prev_for_neutral; + bidi_it->next_for_neutral = st.next_for_neutral; + bidi_it->next_for_ws = st.next_for_ws; + bidi_it->next_en_pos = st.next_en_pos; + bidi_it->next_en_type = st.next_en_type; + bidi_it->sos = st.sos; + } + bidi_it->stack_idx--; + } return bidi_it->level_stack[bidi_it->stack_idx].level; } @@ -475,6 +508,9 @@ bidi_copy_it (struct bidi_it *to, struct bidi_it *from) Caching the bidi iterator states ***********************************************************************/ +/* We allocate and de-allocate the cache in chunks of this size (in + characters). 200 was chosen as an upper limit for reasonably-long + lines in a text file/buffer. */ #define BIDI_CACHE_CHUNK 200 static struct bidi_it *bidi_cache; static ptrdiff_t bidi_cache_size = 0; @@ -954,6 +990,7 @@ static void bidi_set_paragraph_end (struct bidi_it *bidi_it) { bidi_it->invalid_levels = 0; + bidi_it->invalid_isolates = 0; bidi_it->stack_idx = 0; bidi_it->resolved_level = bidi_it->level_stack[0].level; } @@ -1016,7 +1053,6 @@ bidi_line_init (struct bidi_it *bidi_it) bidi_it->invalid_isolates = 0; /* X1 */ /* Setting this to zero will force its recomputation the first time we need it for W5. */ - /* FIXME: Review this!!! */ bidi_it->next_en_pos = 0; bidi_it->next_en_type = UNKNOWN_BT; bidi_it->next_for_ws.type = UNKNOWN_BT; @@ -2010,10 +2046,16 @@ bidi_resolve_weak (struct bidi_it *bidi_it) emacs_abort (); eassert (prev_level >= 0); - if (new_level != prev_level + if (new_level > prev_level + /* When the embedding level goes down, we only need to compute + the type of sos if this level is not an isolate, because the + sos type of the isolating sequence was already computed and + saved on the stack. */ + || (new_level < prev_level + && !bidi_it->level_stack[bidi_it->stack_idx].isolate_status) || bidi_it->type == NEUTRAL_B) { - /* We've got a new embedding level run, compute the directional + /* We've got a new isolating sequence, compute the directional type of sos and initialize per-run variables (UAX#9, clause X10). */ bidi_set_sos_type (bidi_it, prev_level, new_level); @@ -2350,7 +2392,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) /* FALLTHROUGH */ case NEUTRAL_B: /* Marched all the way to the end of this level run. - We need to use the eor type, whose information is + We need to use the eos type, whose information is stored by bidi_set_sos_type in the prev_for_neutral member. */ if (saved_it.type != WEAK_BN diff --git a/src/dispextern.h b/src/dispextern.h index a5b78a6f952..5e90a4ef23b 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1908,12 +1908,21 @@ struct bidi_saved_info { bidi_type_t orig_type; /* type as we found it in the buffer */ }; -/* Data type for keeping track of saved embedding levels, override - status, and isolate status information. */ +/* Data type for keeping track of information about saved embedding + levels, override status, isolate status, and isolating sequence + runs. */ struct bidi_stack { char level; bool isolate_status; bidi_dir_t override; + struct bidi_saved_info prev; + struct bidi_saved_info last_strong; + struct bidi_saved_info next_for_neutral; + struct bidi_saved_info prev_for_neutral; + struct bidi_saved_info next_for_ws; + ptrdiff_t next_en_pos; + bidi_type_t next_en_type; + bidi_dir_t sos; }; /* Data type for storing information about a string being iterated on. */ |