]> git.eshelyaron.com Git - emacs.git/commitdiff
Updated pushing and popping the bidi stack, and sos calculations.
authorEli Zaretskii <eliz@gnu.org>
Sat, 30 Aug 2014 12:19:26 +0000 (15:19 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sat, 30 Aug 2014 12:19:26 +0000 (15:19 +0300)
Added the necessary members to bidi_stack.

src/bidi.c
src/dispextern.h

index e01b77d0e961d66f5c9c4c72a2e1025972388446..a99fd7489817138745d0e7c4e121f6f997ce3f70 100644 (file)
@@ -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
index a5b78a6f95296c6b9a36d5d58954ddd7b8504342..5e90a4ef23bab562399e81c4d183b42b946ca5cb 100644 (file)
@@ -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.  */