remove Lisp_Free struct type
[bpt/emacs.git] / src / bidi.c
index 6b3ac53..53c2dad 100644 (file)
@@ -1,6 +1,6 @@
 /* Low-level bidirectional buffer/string-scanning functions for GNU Emacs.
-   Copyright (C) 2000-2001, 2004-2005, 2009-2012
-   Free Software Foundation, Inc.
+   Copyright (C) 2000-2001, 2004-2005, 2009-2014 Free Software
+   Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -22,9 +22,16 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    A sequential implementation of the Unicode Bidirectional algorithm,
    (UBA) as per UAX#9, a part of the Unicode Standard.
 
-   Unlike the reference and most other implementations, this one is
-   designed to be called once for every character in the buffer or
-   string.
+   Unlike the Reference Implementation and most other implementations,
+   this one is designed to be called once for every character in the
+   buffer or string.  That way, we can leave intact the design of the
+   Emacs display engine, whereby an iterator object is used to
+   traverse buffer or string text character by character, and generate
+   the necessary data for displaying each character in 'struct glyph'
+   objects.  (See xdisp.c for the details of that iteration.)  The
+   functions on this file replace the original linear iteration in the
+   logical order of the text with a non-linear iteration in the visual
+   order, i.e. in the order characters should be shown on display.
 
    The main entry point is bidi_move_to_visually_next.  Each time it
    is called, it finds the next character in the visual order, and
@@ -52,31 +59,205 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    A note about references to UAX#9 rules: if the reference says
    something like "X9/Retaining", it means that you need to refer to
    rule X9 and to its modifications described in the "Implementation
-   Notes" section of UAX#9, under "Retaining Format Codes".  */
+   Notes" section of UAX#9, under "Retaining Format Codes".
+
+   Here's the overview of the design of the reordering engine
+   implemented by this file.
+
+   Basic implementation structure
+   ------------------------------
+
+   The sequential processing steps described by UAX#9 are implemented
+   as recursive levels of processing, all of which examine the next
+   character in the logical order.  This hierarchy of processing looks
+   as follows, from the innermost (deepest) to the outermost level,
+   omitting some subroutines used by each level:
+
+     bidi_fetch_char         -- fetch next character
+     bidi_resolve_explicit   -- resolve explicit levels and directions
+     bidi_resolve_weak       -- resolve weak types
+     bidi_resolve_neutral    -- resolve neutral types
+     bidi_level_of_next_char -- resolve implicit levels
+
+   Each level calls the level below it, and works on the result
+   returned by the lower level, including all of its sub-levels.
+
+   Unlike all the levels below it, bidi_level_of_next_char can return
+   the information about either the next or previous character in the
+   logical order, depending on the current direction of scanning the
+   buffer or string.  For the next character, it calls all the levels
+   below it; for the previous character, it uses the cache, described
+   below.
+
+   Thus, the result of calling bidi_level_of_next_char is the resolved
+   level of the next or the previous character in the logical order.
+   Based on this information, the function bidi_move_to_visually_next
+   finds the next character in the visual order and updates the
+   direction in which the buffer is scanned, either forward or
+   backward, to find the next character to be displayed.  (Text is
+   scanned backwards when it needs to be reversed for display, i.e. if
+   the visual order is the inverse of the logical order.)  This
+   implements the last, reordering steps of the UBA, by successively
+   calling bidi_level_of_next_char until the character of the required
+   embedding level is found; the scan direction is dynamically updated
+   as a side effect.  See the commentary before the 'while' loop in
+   bidi_move_to_visually_next, for the details.
+
+   Fetching characters
+   -------------------
+
+   In a nutshell, fetching the next character boils down to calling
+   STRING_CHAR_AND_LENGTH, passing it the address of a buffer or
+   string position.  See bidi_fetch_char.  However, if the next
+   character is "covered" by a display property of some kind,
+   bidi_fetch_char returns the u+FFFC "object replacement character"
+   that represents the entire run of text covered by the display
+   property.  (The ch_len and nchars members of 'struct bidi_it'
+   reflect the length in bytes and characters of that text.)  This is
+   so we reorder text on both sides of the display property as
+   appropriate for an image or embedded string.  Similarly, text
+   covered by a display spec of the form '(space ...)', is replaced
+   with the u+2029 paragraph separator character, so such display
+   specs produce the same effect as a TAB under UBA.  Both these
+   special characters are not actually displayed -- the display
+   property is displayed instead -- but just used to compute the
+   embedding level of the surrounding text so as to produce the
+   required effect.
+
+   Bidi iterator states
+   --------------------
+
+   The UBA is highly context dependent in some of its parts,
+   i.e. results of processing a character can generally depend on
+   characters very far away.  The UAX#9 description of the UBA
+   prescribes a stateful processing of each character, whereby the
+   results of this processing depend on various state variables, such
+   as the current embedding level, level stack, and directional
+   override status.  In addition, the UAX#9 description includes many
+   passages like this (from rule W2 in this case):
+
+     Search backward from each instance of a European number until the
+     first strong type (R, L, AL, or sos) is found. If an AL is found,
+     change the type of the European number to Arabic number.
+
+   To support this, we use a bidi iterator object, 'struct bidi_it',
+   which is a sub-structure of 'struct it' used by xdisp.c (see
+   dispextern.h for the definition of both of these structures).  The
+   bidi iterator holds the entire state of the iteration required by
+   the UBA, and is updated as the text is traversed.  In particular,
+   the embedding level of the current character being resolved is
+   recorded in the iterator state.  To avoid costly searches backward
+   in support of rules like W2 above, the necessary character types
+   are also recorded in the iterator state as they are found during
+   the forward scan, and then used when such rules need to be applied.
+   (Forward scans cannot be avoided in this way; they need to be
+   performed at least once, and the results recorded in the iterator
+   state, to be reused until the forward scan oversteps the recorded
+   position.)
+
+   In this manner, the iterator state acts as a mini-cache of
+   contextual information required for resolving the level of the
+   current character by various UBA rules.
+
+   Caching of bidi iterator states
+   -------------------------------
+
+   As described above, the reordering engine uses the information
+   recorded in the bidi iterator state in order to resolve the
+   embedding level of the current character.  When the reordering
+   engine needs to process the next character in the logical order, it
+   fetches it and applies to it all the UBA levels, updating the
+   iterator state as it goes.  But when the buffer or string is
+   scanned backwards, i.e. in the reverse order of buffer/string
+   positions, the scanned characters were already processed during the
+   preceding forward scan (see bidi_find_other_level_edge).  To avoid
+   costly re-processing of characters that were already processed
+   during the forward scan, the iterator states computed while
+   scanning forward are cached.
+
+   The cache is just a linear array of 'struct bidi_it' objects, which
+   is dynamically allocated and reallocated as needed, since the size
+   of the cache depends on the text being processed.  We only need the
+   cache while processing embedded levels higher than the base
+   paragraph embedding level, because these higher levels require
+   changes in scan direction.  Therefore, as soon as we are back to
+   the base embedding level, we can free the cache; see the calls to
+   bidi_cache_reset and bidi_cache_shrink, for the conditions to do
+   this.
+
+   The cache maintains the index of the next unused cache slot -- this
+   is where the next iterator state will be cached.  The function
+   bidi_cache_iterator_state saves an instance of the state in the
+   cache and increments the unused slot index.  The companion function
+   bidi_cache_find looks up a cached state that corresponds to a given
+   buffer/string position.  All of the cached states must correspond
+   1:1 to the buffer or string region whose processing they reflect;
+   bidi.c will abort if it finds cache slots that violate this 1:1
+   correspondence.
+
+   When the parent iterator 'struct it' is pushed (see push_it in
+   xdisp.c) to pause the current iteration and start iterating over a
+   different object (e.g., a 'display' string that covers some buffer
+   text), the bidi iterator cache needs to be "pushed" as well, so
+   that a new empty cache could be used while iterating over the new
+   object.  Later, when the new object is exhausted, and xdisp.c calls
+   pop_it, we need to "pop" the bidi cache as well and return to the
+   original cache.  See bidi_push_it and bidi_pop_it for how this is
+   done.
+
+   Some functions of the display engine save copies of 'struct it' in
+   local variables, and restore them later.  For examples, see
+   pos_visible_p and move_it_in_display_line_to in xdisp.c, and
+   window_scroll_pixel_based in window.c.  When this happens, we need
+   to save and restore the bidi cache as well, because conceptually
+   the cache is part of the 'struct it' state, and needs to be in
+   perfect sync with the portion of the buffer/string that is being
+   processed.  This saving and restoring of the cache state is handled
+   by bidi_shelve_cache and bidi_unshelve_cache, and the helper macros
+   SAVE_IT and RESTORE_IT defined on xdisp.c.
+
+   Note that, because reordering is implemented below the level in
+   xdisp.c that breaks glyphs into screen lines, we are violating
+   paragraph 3.4 of UAX#9. which mandates that line breaking shall be
+   done before reordering each screen line separately.  However,
+   following UAX#9 to the letter in this matter goes against the basic
+   design of the Emacs display engine, and so we choose here this
+   minor deviation from the UBA letter in preference to redesign of
+   the display engine.  The effect of this is only seen in continued
+   lines that are broken into screen lines in the middle of a run
+   whose direction is opposite to the paragraph's base direction.
+
+   Important design and implementation note: when the code needs to
+   scan far ahead, be sure to avoid such scans as much as possible
+   when the buffer/string doesn't contain any RTL characters.  Users
+   of left-to-right scripts will never forgive you if you introduce
+   some slow-down due to bidi in situations that don't involve any
+   bidirectional text.  See the large comment near the beginning of
+   bidi_resolve_neutral, for one situation where such shortcut was
+   necessary.  */
 
 #include <config.h>
 #include <stdio.h>
-#include <setjmp.h>
 
 #include "lisp.h"
 #include "character.h"
 #include "buffer.h"
 #include "dispextern.h"
+#include "region-cache.h"
 
 static bool bidi_initialized = 0;
 
 static Lisp_Object bidi_type_table, bidi_mirror_table;
 
-#define LRM_CHAR   0x200E
-#define RLM_CHAR   0x200F
-#define BIDI_EOB   -1
+#define BIDI_EOB   (-1)
 
 /* Data type for describing the bidirectional character categories.  */
 typedef enum {
   UNKNOWN_BC,
   NEUTRAL,
   WEAK,
-  STRONG
+  STRONG,
+  EXPLICIT_FORMATTING
 } bidi_category_t;
 
 /* UAX#9 says to search only for L, AL, or R types of characters, and
@@ -97,7 +278,7 @@ static Lisp_Object Qparagraph_start, Qparagraph_separate;
 
 /* Return the bidi type of a character CH, subject to the current
    directional OVERRIDE.  */
-static inline bidi_type_t
+static bidi_type_t
 bidi_get_type (int ch, bidi_dir_t override)
 {
   bidi_type_t default_type;
@@ -105,7 +286,7 @@ bidi_get_type (int ch, bidi_dir_t override)
   if (ch == BIDI_EOB)
     return NEUTRAL_B;
   if (ch < 0 || ch > MAX_CHAR)
-    abort ();
+    emacs_abort ();
 
   default_type = (bidi_type_t) XINT (CHAR_TABLE_REF (bidi_type_table, ch));
   /* Every valid character code, even those that are unassigned by the
@@ -113,15 +294,11 @@ bidi_get_type (int ch, bidi_dir_t override)
      DerivedBidiClass.txt file.  Therefore, if we ever get UNKNOWN_BT
      (= zero) code from CHAR_TABLE_REF, that's a bug.  */
   if (default_type == UNKNOWN_BT)
-    abort ();
-
-  if (override == NEUTRAL_DIR)
-    return default_type;
+    emacs_abort ();
 
   switch (default_type)
     {
-      /* Although UAX#9 does not tell, it doesn't make sense to
-        override NEUTRAL_B and LRM/RLM characters.  */
+      case WEAK_BN:
       case NEUTRAL_B:
       case LRE:
       case LRO:
@@ -129,31 +306,31 @@ bidi_get_type (int ch, bidi_dir_t override)
       case RLO:
       case PDF:
        return default_type;
+       /* FIXME: The isolate controls are treated as BN until we add
+          support for UBA v6.3.  */
+      case LRI:
+      case RLI:
+      case FSI:
+      case PDI:
+       return WEAK_BN;
       default:
-       switch (ch)
-         {
-           case LRM_CHAR:
-           case RLM_CHAR:
-             return default_type;
-           default:
-             if (override == L2R) /* X6 */
-               return STRONG_L;
-             else if (override == R2L)
-               return STRONG_R;
-             else
-               abort ();       /* can't happen: handled above */
-         }
+       if (override == L2R)
+         return STRONG_L;
+       else if (override == R2L)
+         return STRONG_R;
+       else
+         return default_type;
     }
 }
 
-static inline void
+static void
 bidi_check_type (bidi_type_t type)
 {
   eassert (UNKNOWN_BT <= type && type <= NEUTRAL_ON);
 }
 
 /* Given a bidi TYPE of a character, return its category.  */
-static inline bidi_category_t
+static bidi_category_t
 bidi_get_category (bidi_type_t type)
 {
   switch (type)
@@ -163,12 +340,7 @@ bidi_get_category (bidi_type_t type)
       case STRONG_L:
       case STRONG_R:
       case STRONG_AL:
-      case LRE:
-      case LRO:
-      case RLE:
-      case RLO:
        return STRONG;
-      case PDF:                /* ??? really?? */
       case WEAK_EN:
       case WEAK_ES:
       case WEAK_ET:
@@ -176,14 +348,32 @@ bidi_get_category (bidi_type_t type)
       case WEAK_CS:
       case WEAK_NSM:
       case WEAK_BN:
+       /* FIXME */
+      case LRI:
+      case RLI:
+      case FSI:
+      case PDI:
        return WEAK;
       case NEUTRAL_B:
       case NEUTRAL_S:
       case NEUTRAL_WS:
       case NEUTRAL_ON:
        return NEUTRAL;
+      case LRE:
+      case LRO:
+      case RLE:
+      case RLO:
+      case PDF:
+#if 0
+       /* FIXME: This awaits implementation of isolate support.  */
+      case LRI:
+      case RLI:
+      case FSI:
+      case PDI:
+#endif
+       return EXPLICIT_FORMATTING;
       default:
-       abort ();
+       emacs_abort ();
     }
 }
 
@@ -199,7 +389,7 @@ bidi_mirror_char (int c)
   if (c == BIDI_EOB)
     return c;
   if (c < 0 || c > MAX_CHAR)
-    abort ();
+    emacs_abort ();
 
   val = CHAR_TABLE_REF (bidi_mirror_table, c);
   if (INTEGERP (val))
@@ -215,7 +405,7 @@ bidi_mirror_char (int c)
       /* Minimal test we must do in optimized builds, to prevent weird
         crashes further down the road.  */
       if (v < 0 || v > MAX_CHAR)
-       abort ();
+       emacs_abort ();
 
       return v;
     }
@@ -227,7 +417,7 @@ bidi_mirror_char (int c)
    embedding levels on either side of the run boundary.  Also, update
    the saved info about previously seen characters, since that info is
    generally valid for a single level run.  */
-static inline void
+static void
 bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after)
 {
   int higher_level = (level_before > level_after ? level_before : level_after);
@@ -258,7 +448,7 @@ bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after)
 
 /* Push the current embedding level and override status; reset the
    current level to LEVEL and the current override status to OVERRIDE.  */
-static inline void
+static void
 bidi_push_embedding_level (struct bidi_it *bidi_it,
                           int level, bidi_dir_t override)
 {
@@ -270,7 +460,7 @@ bidi_push_embedding_level (struct bidi_it *bidi_it,
 
 /* Pop the embedding level and directional override status from the
    stack, and return the new level.  */
-static inline int
+static int
 bidi_pop_embedding_level (struct bidi_it *bidi_it)
 {
   /* UAX#9 says to ignore invalid PDFs.  */
@@ -280,7 +470,7 @@ bidi_pop_embedding_level (struct bidi_it *bidi_it)
 }
 
 /* Record in SAVED_INFO the information about the current character.  */
-static inline void
+static void
 bidi_remember_char (struct bidi_saved_info *saved_info,
                    struct bidi_it *bidi_it)
 {
@@ -296,18 +486,14 @@ bidi_remember_char (struct bidi_saved_info *saved_info,
 
 /* Copy the bidi iterator from FROM to TO.  To save cycles, this only
    copies the part of the level stack that is actually in use.  */
-static inline void
+static void
 bidi_copy_it (struct bidi_it *to, struct bidi_it *from)
 {
-  int i;
-
-  /* Copy everything except the level stack and beyond.  */
-  memcpy (to, from, offsetof (struct bidi_it, level_stack[0]));
-
-  /* Copy the active part of the level stack.  */
-  to->level_stack[0] = from->level_stack[0]; /* level zero is always in use */
-  for (i = 1; i <= from->stack_idx; i++)
-    to->level_stack[i] = from->level_stack[i];
+  /* Copy everything from the start through the active part of
+     the level stack.  */
+  memcpy (to, from,
+         (offsetof (struct bidi_it, level_stack[1])
+          + from->stack_idx * sizeof from->level_stack[0]));
 }
 
 \f
@@ -345,7 +531,7 @@ enum
    intact.  This is called when the cached information is no more
    useful for the current iteration, e.g. when we were reseated to a
    new position on the same object.  */
-static inline void
+static void
 bidi_cache_reset (void)
 {
   bidi_cache_idx = bidi_cache_start;
@@ -356,7 +542,7 @@ bidi_cache_reset (void)
    iterator for reordering a buffer or a string that does not come
    from display properties, because that means all the previously
    cached info is of no further use.  */
-static inline void
+static void
 bidi_cache_shrink (void)
 {
   if (bidi_cache_size > BIDI_CACHE_CHUNK)
@@ -367,13 +553,13 @@ bidi_cache_shrink (void)
   bidi_cache_reset ();
 }
 
-static inline void
+static void
 bidi_cache_fetch_state (ptrdiff_t idx, struct bidi_it *bidi_it)
 {
   int current_scan_dir = bidi_it->scan_dir;
 
   if (idx < bidi_cache_start || idx >= bidi_cache_idx)
-    abort ();
+    emacs_abort ();
 
   bidi_copy_it (bidi_it, &bidi_cache[idx]);
   bidi_it->scan_dir = current_scan_dir;
@@ -384,7 +570,7 @@ bidi_cache_fetch_state (ptrdiff_t idx, struct bidi_it *bidi_it)
    level less or equal to LEVEL.  if LEVEL is -1, disregard the
    resolved levels in cached states.  DIR, if non-zero, means search
    in that direction from the last cache hit.  */
-static inline ptrdiff_t
+static ptrdiff_t
 bidi_cache_search (ptrdiff_t charpos, int level, int dir)
 {
   ptrdiff_t i, i_start;
@@ -489,7 +675,7 @@ bidi_cache_find_level_change (int level, int dir, bool before)
   return -1;
 }
 
-static inline void
+static void
 bidi_cache_ensure_space (ptrdiff_t idx)
 {
   /* Enlarge the cache as needed.  */
@@ -511,14 +697,14 @@ bidi_cache_ensure_space (ptrdiff_t idx)
     }
 }
 
-static inline void
+static void
 bidi_cache_iterator_state (struct bidi_it *bidi_it, bool resolved)
 {
   ptrdiff_t idx;
 
   /* We should never cache on backward scans.  */
   if (bidi_it->scan_dir == -1)
-    abort ();
+    emacs_abort ();
   idx = bidi_cache_search (bidi_it->charpos, -1, 1);
 
   if (idx < 0)
@@ -537,7 +723,7 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, bool resolved)
          idx = bidi_cache_start;
        }
       if (bidi_it->nchars <= 0)
-       abort ();
+       emacs_abort ();
       bidi_copy_it (&bidi_cache[idx], bidi_it);
       if (!resolved)
        bidi_cache[idx].resolved_level = -1;
@@ -568,7 +754,7 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, bool resolved)
     bidi_cache_idx = idx + 1;
 }
 
-static inline bidi_type_t
+static bidi_type_t
 bidi_cache_find (ptrdiff_t charpos, int level, struct bidi_it *bidi_it)
 {
   ptrdiff_t i = bidi_cache_search (charpos, level, bidi_it->scan_dir);
@@ -588,11 +774,11 @@ bidi_cache_find (ptrdiff_t charpos, int level, struct bidi_it *bidi_it)
   return UNKNOWN_BT;
 }
 
-static inline int
+static int
 bidi_peek_at_next_level (struct bidi_it *bidi_it)
 {
   if (bidi_cache_idx == bidi_cache_start || bidi_cache_last_idx == -1)
-    abort ();
+    emacs_abort ();
   return bidi_cache[bidi_cache_last_idx + bidi_it->scan_dir].resolved_level;
 }
 
@@ -612,7 +798,7 @@ bidi_push_it (struct bidi_it *bidi_it)
   /* Save the current iterator state in its entirety after the last
      used cache slot.  */
   bidi_cache_ensure_space (bidi_cache_idx);
-  memcpy (&bidi_cache[bidi_cache_idx++], bidi_it, sizeof (struct bidi_it));
+  bidi_cache[bidi_cache_idx++] = *bidi_it;
 
   /* Push the current cache start onto the stack.  */
   eassert (bidi_cache_sp < IT_STACK_SIZE);
@@ -629,18 +815,18 @@ void
 bidi_pop_it (struct bidi_it *bidi_it)
 {
   if (bidi_cache_start <= 0)
-    abort ();
+    emacs_abort ();
 
   /* Reset the next free cache slot index to what it was before the
      call to bidi_push_it.  */
   bidi_cache_idx = bidi_cache_start - 1;
 
   /* Restore the bidi iterator state saved in the cache.  */
-  memcpy (bidi_it, &bidi_cache[bidi_cache_idx], sizeof (struct bidi_it));
+  *bidi_it = bidi_cache[bidi_cache_idx];
 
   /* Pop the previous cache start from the stack.  */
   if (bidi_cache_sp <= 0)
-    abort ();
+    emacs_abort ();
   bidi_cache_start = bidi_cache_start_stack[--bidi_cache_sp];
 
   /* Invalidate the last-used cache slot data.  */
@@ -762,12 +948,12 @@ bidi_initialize (void)
 {
   bidi_type_table = uniprop_table (intern ("bidi-class"));
   if (NILP (bidi_type_table))
-    abort ();
+    emacs_abort ();
   staticpro (&bidi_type_table);
 
   bidi_mirror_table = uniprop_table (intern ("mirroring"));
   if (NILP (bidi_mirror_table))
-    abort ();
+    emacs_abort ();
   staticpro (&bidi_mirror_table);
 
   Qparagraph_start = intern ("paragraph-start");
@@ -791,7 +977,7 @@ bidi_initialize (void)
 
 /* Do whatever UAX#9 clause X8 says should be done at paragraph's
    end.  */
-static inline void
+static void
 bidi_set_paragraph_end (struct bidi_it *bidi_it)
 {
   bidi_it->invalid_levels = 0;
@@ -873,9 +1059,9 @@ bidi_line_init (struct bidi_it *bidi_it)
 /* Count bytes in string S between BEG/BEGBYTE and END.  BEG and END
    are zero-based character positions in S, BEGBYTE is byte position
    corresponding to BEG.  UNIBYTE means S is a unibyte string.  */
-static inline ptrdiff_t
-bidi_count_bytes (const unsigned char *s, const ptrdiff_t beg,
-                 const ptrdiff_t begbyte, const ptrdiff_t end, bool unibyte)
+static ptrdiff_t
+bidi_count_bytes (const unsigned char *s, ptrdiff_t beg,
+                 ptrdiff_t begbyte, ptrdiff_t end, bool unibyte)
 {
   ptrdiff_t pos = beg;
   const unsigned char *p = s + begbyte, *start = p;
@@ -885,7 +1071,7 @@ bidi_count_bytes (const unsigned char *s, const ptrdiff_t beg,
   else
     {
       if (!CHAR_HEAD_P (*p))
-       abort ();
+       emacs_abort ();
 
       while (pos < end)
        {
@@ -897,25 +1083,25 @@ bidi_count_bytes (const unsigned char *s, const ptrdiff_t beg,
   return p - start;
 }
 
-/* Fetch and returns the character at byte position BYTEPOS.  If S is
+/* Fetch and return the character at byte position BYTEPOS.  If S is
    non-NULL, fetch the character from string S; otherwise fetch the
    character from the current buffer.  UNIBYTE means S is a
    unibyte string.  */
-static inline int
+static int
 bidi_char_at_pos (ptrdiff_t bytepos, const unsigned char *s, bool unibyte)
 {
   if (s)
     {
+      s += bytepos;
       if (unibyte)
-       return s[bytepos];
-      else
-       return STRING_CHAR (s + bytepos);
+       return *s;
     }
   else
-    return FETCH_MULTIBYTE_CHAR (bytepos);
+    s = BYTE_POS_ADDR (bytepos);
+  return STRING_CHAR (s);
 }
 
-/* Fetch and return the character at BYTEPOS/CHARPOS.  If that
+/* Fetch and return the character at CHARPOS/BYTEPOS.  If that
    character is covered by a display string, treat the entire run of
    covered characters as a single character, either u+2029 or u+FFFC,
    and return their combined length in CH_LEN and NCHARS.  DISP_POS
@@ -929,9 +1115,10 @@ bidi_char_at_pos (ptrdiff_t bytepos, const unsigned char *s, bool unibyte)
    u+2029 to handle it as a paragraph separator.  STRING->s is the C
    string to iterate, or NULL if iterating over a buffer or a Lisp
    string; in the latter case, STRING->lstring is the Lisp string.  */
-static inline int
-bidi_fetch_char (ptrdiff_t bytepos, ptrdiff_t charpos, ptrdiff_t *disp_pos,
+static int
+bidi_fetch_char (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t *disp_pos,
                 int *disp_prop, struct bidi_string_data *string,
+                struct window *w,
                 bool frame_window_p, ptrdiff_t *ch_len, ptrdiff_t *nchars)
 {
   int ch;
@@ -945,7 +1132,7 @@ bidi_fetch_char (ptrdiff_t bytepos, ptrdiff_t charpos, ptrdiff_t *disp_pos,
   if (charpos < endpos && charpos > *disp_pos)
     {
       SET_TEXT_POS (pos, charpos, bytepos);
-      *disp_pos = compute_display_string_pos (&pos, string, frame_window_p,
+      *disp_pos = compute_display_string_pos (&pos, string, w, frame_window_p,
                                              disp_prop);
     }
 
@@ -965,7 +1152,7 @@ bidi_fetch_char (ptrdiff_t bytepos, ptrdiff_t charpos, ptrdiff_t *disp_pos,
       /* We don't expect to find ourselves in the middle of a display
         property.  Hopefully, it will never be needed.  */
       if (charpos > *disp_pos)
-       abort ();
+       emacs_abort ();
       /* Text covered by `display' properties and overlays with
         display properties or display strings is handled as a single
         character that represents the entire run of characters
@@ -995,7 +1182,7 @@ bidi_fetch_char (ptrdiff_t bytepos, ptrdiff_t charpos, ptrdiff_t *disp_pos,
        }
       *nchars = disp_end_pos - *disp_pos;
       if (*nchars <= 0)
-       abort ();
+       emacs_abort ();
       if (string->s)
        *ch_len = bidi_count_bytes (string->s, *disp_pos, bytepos,
                                    disp_end_pos, string->unibyte);
@@ -1050,7 +1237,7 @@ bidi_fetch_char (ptrdiff_t bytepos, ptrdiff_t charpos, ptrdiff_t *disp_pos,
       && *disp_prop)
     {
       SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len);
-      *disp_pos = compute_display_string_pos (&pos, string, frame_window_p,
+      *disp_pos = compute_display_string_pos (&pos, string, w, frame_window_p,
                                              disp_prop);
     }
 
@@ -1089,6 +1276,53 @@ bidi_at_paragraph_end (ptrdiff_t charpos, ptrdiff_t bytepos)
   return val;
 }
 
+/* If the user has requested the long scans caching, make sure that
+   BIDI cache is enabled.  Otherwise, make sure it's disabled.  */
+
+static struct region_cache *
+bidi_paragraph_cache_on_off (void)
+{
+  struct buffer *cache_buffer = current_buffer;
+  bool indirect_p = false;
+
+  /* For indirect buffers, make sure to use the cache of their base
+     buffer.  */
+  if (cache_buffer->base_buffer)
+    {
+      cache_buffer = cache_buffer->base_buffer;
+      indirect_p = true;
+    }
+
+  /* Don't turn on or off the cache in the base buffer, if the value
+     of cache-long-scans of the base buffer is inconsistent with that.
+     This is because doing so will just make the cache pure overhead,
+     since if we turn it on via indirect buffer, it will be
+     immediately turned off by its base buffer.  */
+  if (NILP (BVAR (current_buffer, cache_long_scans)))
+    {
+      if (!indirect_p
+         || NILP (BVAR (cache_buffer, cache_long_scans)))
+       {
+         if (cache_buffer->bidi_paragraph_cache)
+           {
+             free_region_cache (cache_buffer->bidi_paragraph_cache);
+             cache_buffer->bidi_paragraph_cache = 0;
+           }
+       }
+      return NULL;
+    }
+  else
+    {
+      if (!indirect_p
+         || !NILP (BVAR (cache_buffer, cache_long_scans)))
+       {
+         if (!cache_buffer->bidi_paragraph_cache)
+           cache_buffer->bidi_paragraph_cache = new_region_cache ();
+       }
+      return cache_buffer->bidi_paragraph_cache;
+    }
+}
+
 /* On my 2005-vintage machine, searching back for paragraph start
    takes ~1 ms per line.  And bidi_paragraph_init is called 4 times
    when user types C-p.  The number below limits each call to
@@ -1104,7 +1338,12 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte)
 {
   Lisp_Object re = paragraph_start_re;
   ptrdiff_t limit = ZV, limit_byte = ZV_BYTE;
-  ptrdiff_t n = 0;
+  struct region_cache *bpc = bidi_paragraph_cache_on_off ();
+  ptrdiff_t n = 0, oldpos = pos, next;
+  struct buffer *cache_buffer = current_buffer;
+
+  if (cache_buffer->base_buffer)
+    cache_buffer = cache_buffer->base_buffer;
 
   while (pos_byte > BEGV_BYTE
         && n++ < MAX_PARAGRAPH_SEARCH
@@ -1114,11 +1353,22 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte)
         display string?  And what if a display string covering some
         of the text over which we scan back includes
         paragraph_start_re?  */
-      pos = find_next_newline_no_quit (pos - 1, -1);
-      pos_byte = CHAR_TO_BYTE (pos);
+      DEC_BOTH (pos, pos_byte);
+      if (bpc && region_cache_backward (cache_buffer, bpc, pos, &next))
+       {
+         pos = next, pos_byte = CHAR_TO_BYTE (pos);
+         break;
+       }
+      else
+       pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte);
     }
   if (n >= MAX_PARAGRAPH_SEARCH)
-    pos_byte = BEGV_BYTE;
+    pos = BEGV, pos_byte = BEGV_BYTE;
+  if (bpc)
+    know_region_cache (cache_buffer, bpc, pos, oldpos);
+  /* Positions returned by the region cache are not limited to
+     BEGV..ZV range, so we limit them here.  */
+  pos_byte = clip_to_bounds (BEGV_BYTE, pos_byte, ZV_BYTE);
   return pos_byte;
 }
 
@@ -1160,7 +1410,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p)
     dir = L2R;
   /* We should never be called at EOB or before BEGV.  */
   else if (bidi_it->charpos >= end || bytepos < begbyte)
-    abort ();
+    emacs_abort ();
 
   if (dir == L2R)
     {
@@ -1228,8 +1478,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p)
        bytepos = pstartbyte;
        if (!string_p)
          pos = BYTE_TO_CHAR (bytepos);
-       ch = bidi_fetch_char (bytepos, pos, &disp_pos, &disp_prop,
-                             &bidi_it->string,
+       ch = bidi_fetch_char (pos, bytepos, &disp_pos, &disp_prop,
+                             &bidi_it->string, bidi_it->w,
                              bidi_it->frame_window_p, &ch_len, &nchars);
        type = bidi_get_type (ch, NEUTRAL_DIR);
 
@@ -1256,8 +1506,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p)
                && bidi_at_paragraph_end (pos, bytepos) >= -1)
              break;
            /* Fetch next character and advance to get past it.  */
-           ch = bidi_fetch_char (bytepos, pos, &disp_pos,
-                                 &disp_prop, &bidi_it->string,
+           ch = bidi_fetch_char (pos, bytepos, &disp_pos,
+                                 &disp_prop, &bidi_it->string, bidi_it->w,
                                  bidi_it->frame_window_p, &ch_len, &nchars);
            pos += nchars;
            bytepos += ch_len;
@@ -1287,8 +1537,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p)
                    /* FXIME: What if p is covered by a display
                       string?  See also a FIXME inside
                       bidi_find_paragraph_start.  */
-                   p--;
-                   pbyte = CHAR_TO_BYTE (p);
+                   DEC_BOTH (p, pbyte);
                    prevpbyte = bidi_find_paragraph_start (p, pbyte);
                  }
                pstartbyte = prevpbyte;
@@ -1298,7 +1547,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p)
               && no_default_p && bidi_it->paragraph_dir == NEUTRAL_DIR);
     }
   else
-    abort ();
+    emacs_abort ();
 
   /* Contrary to UAX#9 clause P3, we only default the paragraph
      direction to L2R if we have no previous usable paragraph
@@ -1319,13 +1568,13 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p)
   The rest of this file constitutes the core of the UBA implementation.
  ***********************************************************************/
 
-static inline bool
+static bool
 bidi_explicit_dir_char (int ch)
 {
   bidi_type_t ch_type;
 
   if (!bidi_initialized)
-    abort ();
+    emacs_abort ();
   ch_type = (bidi_type_t) XINT (CHAR_TABLE_REF (bidi_type_table, ch));
   return (ch_type == LRE || ch_type == LRO
          || ch_type == RLE || ch_type == RLO
@@ -1361,15 +1610,19 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
               : bidi_it->string.s);
 
          if (bidi_it->charpos < 0)
-           bidi_it->charpos = 0;
-         bidi_it->bytepos = bidi_count_bytes (p, 0, 0, bidi_it->charpos,
-                                              bidi_it->string.unibyte);
+           bidi_it->charpos = bidi_it->bytepos = 0;
+         eassert (bidi_it->bytepos == bidi_count_bytes (p, 0, 0,
+                                                        bidi_it->charpos,
+                                                        bidi_it->string.unibyte));
        }
       else
        {
          if (bidi_it->charpos < BEGV)
-           bidi_it->charpos = BEGV;
-         bidi_it->bytepos = CHAR_TO_BYTE (bidi_it->charpos);
+           {
+             bidi_it->charpos = BEGV;
+             bidi_it->bytepos = BEGV_BYTE;
+           }
+         eassert (bidi_it->bytepos == CHAR_TO_BYTE (bidi_it->charpos));
        }
     }
   /* Don't move at end of buffer/string.  */
@@ -1378,10 +1631,10 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
       /* Advance to the next character, skipping characters covered by
         display strings (nchars > 1).  */
       if (bidi_it->nchars <= 0)
-       abort ();
+       emacs_abort ();
       bidi_it->charpos += bidi_it->nchars;
       if (bidi_it->ch_len == 0)
-       abort ();
+       emacs_abort ();
       bidi_it->bytepos += bidi_it->ch_len;
     }
 
@@ -1402,9 +1655,10 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
       /* 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.  */
-      curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos,
+      curchar = bidi_fetch_char (bidi_it->charpos, bidi_it->bytepos,
                                 &bidi_it->disp_pos, &bidi_it->disp_prop,
-                                &bidi_it->string, bidi_it->frame_window_p,
+                                &bidi_it->string, bidi_it->w,
+                                bidi_it->frame_window_p,
                                 &bidi_it->ch_len, &bidi_it->nchars);
     }
   bidi_it->ch = curchar;
@@ -1581,7 +1835,7 @@ bidi_resolve_explicit (struct bidi_it *bidi_it)
        }
 
       if (bidi_it->nchars <= 0)
-       abort ();
+       emacs_abort ();
       if (level == prev_level) /* empty embedding */
        saved_it.ignore_bn_limit = bidi_it->charpos + bidi_it->nchars;
       else                     /* this embedding is non-empty */
@@ -1644,7 +1898,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
       || type == RLE
       || type == RLO
       || type == PDF)
-    abort ();
+    emacs_abort ();
 
   if (new_level != prev_level
       || bidi_it->type == NEUTRAL_B)
@@ -1685,7 +1939,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
          else if (bidi_it->sor == L2R)
            type = STRONG_L;
          else /* shouldn't happen! */
-           abort ();
+           emacs_abort ();
        }
       if (type == WEAK_EN      /* W2 */
          && bidi_it->last_strong.type_after_w1 == STRONG_AL)
@@ -1767,7 +2021,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
                                        : bidi_it->string.s);
 
              if (bidi_it->nchars <= 0)
-               abort ();
+               emacs_abort ();
              next_char
                = (bidi_it->charpos + bidi_it->nchars >= eob
                   ? BIDI_EOB
@@ -1842,7 +2096,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
 
 /* Resolve the type of a neutral character according to the type of
    surrounding strong text and the current embedding level.  */
-static inline bidi_type_t
+static bidi_type_t
 bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev)
 {
   /* N1: European and Arabic numbers are treated as though they were R.  */
@@ -1875,7 +2129,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it)
        || type == NEUTRAL_S
        || type == NEUTRAL_WS
        || type == NEUTRAL_ON))
-    abort ();
+    emacs_abort ();
 
   if ((type != NEUTRAL_B /* Don't risk entering the long loop below if
                            we are already at paragraph end.  */
@@ -1930,7 +2184,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it)
          bidi_type_t next_type;
 
          if (bidi_it->scan_dir == -1)
-           abort ();
+           emacs_abort ();
 
          bidi_copy_it (&saved_it, bidi_it);
          /* Scan the text forward until we find the first non-neutral
@@ -1978,8 +2232,9 @@ bidi_resolve_neutral (struct bidi_it *bidi_it)
                next_type = STRONG_R;
                break;
              case WEAK_BN:
+             case NEUTRAL_ON:  /* W6/Retaining */
                if (!bidi_explicit_dir_char (bidi_it->ch))
-                 abort ();             /* can't happen: BNs are skipped */
+                 emacs_abort (); /* can't happen: BNs are skipped */
                /* FALLTHROUGH */
              case NEUTRAL_B:
                /* Marched all the way to the end of this level run.
@@ -1998,7 +2253,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it)
                  }
                break;
              default:
-               abort ();
+               emacs_abort ();
            }
          type = bidi_resolve_neutral_1 (saved_it.prev_for_neutral.type,
                                         next_type, current_level);
@@ -2023,7 +2278,7 @@ bidi_type_of_next_char (struct bidi_it *bidi_it)
 
   /* This should always be called during a forward scan.  */
   if (bidi_it->scan_dir != 1)
-    abort ();
+    emacs_abort ();
 
   /* Reset the limit until which to ignore BNs if we step out of the
      area where we found only empty levels.  */
@@ -2107,7 +2362,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
       if (bidi_it->scan_dir > 0)
        {
          if (bidi_it->nchars <= 0)
-           abort ();
+           emacs_abort ();
          next_char_pos = bidi_it->charpos + bidi_it->nchars;
        }
       else if (bidi_it->charpos >= bob)
@@ -2143,7 +2398,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
   if (bidi_it->scan_dir == -1)
     /* If we are going backwards, the iterator state is already cached
        from previous scans, and should be fully resolved.  */
-    abort ();
+    emacs_abort ();
 
   if (type == UNKNOWN_BT)
     type = bidi_type_of_next_char (bidi_it);
@@ -2156,7 +2411,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
       || (type == WEAK_BN && prev_level == level))
     {
       if (bidi_it->next_for_neutral.type == UNKNOWN_BT)
-       abort ();
+       emacs_abort ();
 
       /* If the cached state shows a neutral character, it was not
         resolved by bidi_resolve_neutral, so do it now.  */
@@ -2170,7 +2425,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
        || type == WEAK_BN
        || type == WEAK_EN
        || type == WEAK_AN))
-    abort ();
+    emacs_abort ();
   bidi_it->type = type;
   bidi_check_type (bidi_it->type);
 
@@ -2192,10 +2447,10 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
       int dpp = bidi_it->disp_prop;
 
       if (bidi_it->nchars <= 0)
-       abort ();
+       emacs_abort ();
       do {
-       ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &dpp, &bs,
-                             fwp, &clen, &nc);
+       ch = bidi_fetch_char (cpos += nc, bpos += clen, &disp_pos, &dpp, &bs,
+                             bidi_it->w, fwp, &clen, &nc);
        if (ch == '\n' || ch == BIDI_EOB)
          chtype = NEUTRAL_B;
        else
@@ -2301,8 +2556,9 @@ bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, bool end_flag)
     {
       int new_level;
 
+      /* If we are at end of level, its edges must be cached.  */
       if (end_flag)
-       abort (); /* if we are at end of level, its edges must be cached */
+       emacs_abort ();
 
       bidi_cache_iterator_state (bidi_it, 1);
       do {
@@ -2320,7 +2576,7 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it)
   struct gcpro gcpro1;
 
   if (bidi_it->charpos < 0 || bidi_it->bytepos < 0)
-    abort ();
+    emacs_abort ();
 
   if (bidi_it->scan_dir == 0)
     {
@@ -2395,6 +2651,10 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it)
       next_level = bidi_peek_at_next_level (bidi_it);
       while (next_level != expected_next_level)
        {
+         /* If next_level is -1, it means we have an unresolved level
+            in the cache, which at this point should not happen.  If
+            it does, we will infloop.  */
+         eassert (next_level >= 0);
          expected_next_level += incr;
          level_to_search += incr;
          bidi_find_other_level_edge (bidi_it, level_to_search, !ascending);
@@ -2431,7 +2691,7 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it)
            = bidi_at_paragraph_end (bidi_it->charpos + bidi_it->nchars,
                                     bidi_it->bytepos + bidi_it->ch_len);
          if (bidi_it->nchars <= 0)
-           abort ();
+           emacs_abort ();
          if (sep_len >= 0)
            {
              bidi_it->new_paragraph = 1;