]> git.eshelyaron.com Git - emacs.git/commitdiff
Speed up display of RTL text with many character compositions
authorEli Zaretskii <eliz@gnu.org>
Thu, 21 Mar 2024 08:25:56 +0000 (10:25 +0200)
committerEshel Yaron <me@eshelyaron.com>
Sun, 24 Mar 2024 14:14:19 +0000 (15:14 +0100)
* src/bidi.c (bidi_level_start): New function.
* src/dispextern.h (bidi_level_start): Add prototype.
* src/xdisp.c (compute_stop_pos, set_iterator_to_next)
(get_visually_first_element, next_element_from_buffer): Call
'bidi_level_start' when looking for composed characters backwards,
to set limit of searching back, instead of looking all the way to
BOB.  (Bug#69385)

(cherry picked from commit fe24a8c3c091c1e051fe6a8c1ec4fd30ca052ca7)

src/bidi.c
src/dispextern.h
src/xdisp.c

index 36d1a0496b84d35d845403d95e49ac73fd010c06..bdf6000178122081c501554207c2636961ad2b0d 100644 (file)
@@ -754,6 +754,19 @@ bidi_cache_find_level_change (int level, int dir, bool before)
   return -1;
 }
 
+/* Find the previous character position where LEVEL changes to a lower
+   one.  Return -1 if not found (which really shouldn't happen if this
+   function is called on a backward scan).  */
+ptrdiff_t
+bidi_level_start (int level)
+{
+  ptrdiff_t slot = bidi_cache_find_level_change (level, -1, true);
+
+  if (slot >= 0)
+    return bidi_cache[slot].charpos;
+  return -1;
+}
+
 static void
 bidi_cache_ensure_space (ptrdiff_t idx)
 {
index 5387cb456032204f77d3b0ae8539e8f867500143..1c3232fae3dc132a5935ed4c9bc3e989d9a0d92d 100644 (file)
@@ -3438,6 +3438,7 @@ extern void bidi_pop_it (struct bidi_it *);
 extern void *bidi_shelve_cache (void);
 extern void bidi_unshelve_cache (void *, bool);
 extern ptrdiff_t bidi_find_first_overridden (struct bidi_it *);
+extern ptrdiff_t bidi_level_start (int);
 
 /* Defined in xdisp.c */
 
index d03769e2a31acb92915874f19a737d896682e572..140d71129f3da084ea2a98c5937c32fdecc6c831 100644 (file)
@@ -4353,7 +4353,7 @@ compute_stop_pos (struct it *it)
          an automatic composition, limit the search of composable
          characters to that position.  */
       if (it->bidi_p && it->bidi_it.scan_dir < 0)
-       stoppos = -1;
+       stoppos = bidi_level_start (it->bidi_it.resolved_level) - 1;
       else if (!STRINGP (it->string)
               && it->cmp_it.stop_pos <= IT_CHARPOS (*it)
               && cmp_limit_pos > 0)
@@ -8712,9 +8712,8 @@ set_iterator_to_next (struct it *it, bool reseat_p)
              ptrdiff_t stop = it->end_charpos;
 
              if (it->bidi_it.scan_dir < 0)
-               /* Now we are scanning backward and don't know
-                  where to stop.  */
-               stop = -1;
+               /* Now we are scanning backward; figure out where to stop.  */
+               stop = bidi_level_start (it->bidi_it.resolved_level) - 1;
              composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
                                            IT_BYTEPOS (*it), stop, Qnil, true);
            }
@@ -8745,7 +8744,7 @@ set_iterator_to_next (struct it *it, bool reseat_p)
                     re-compute the stop position for composition.  */
                  ptrdiff_t stop = it->end_charpos;
                  if (it->bidi_it.scan_dir < 0)
-                   stop = -1;
+                   stop = bidi_level_start (it->bidi_it.resolved_level) - 1;
                  composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
                                                IT_BYTEPOS (*it), stop, Qnil,
                                                true);
@@ -9190,7 +9189,9 @@ get_visually_first_element (struct it *it)
          bytepos = IT_BYTEPOS (*it);
        }
       if (it->bidi_it.scan_dir < 0)
-       stop = -1;
+       stop = STRINGP (it->string)
+              ? -1
+              : bidi_level_start (it->bidi_it.resolved_level) - 1;
       composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
                                    it->string, true);
     }
@@ -9694,9 +9695,10 @@ next_element_from_buffer (struct it *it)
                    && PT < it->end_charpos) ? PT : it->end_charpos;
        }
       else
-       stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
-      if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
-                          stop)
+       stop = it->bidi_it.scan_dir < 0
+              ? bidi_level_start (it->bidi_it.resolved_level) - 1
+              : it->end_charpos;
+      if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it), stop)
          && next_element_from_composition (it))
        {
          return true;