From b408df11e350941eb099cde87d83340e8e7e0378 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 29 Apr 2023 11:50:47 +0300 Subject: [PATCH] Optimize search for composable characters in redisplay * src/composite.c (composition_compute_stop_pos): Accept new argument INCLUDE_STATIC, and look for potential static compositions only if this argument is non-zero. * src/xdisp.c: * src/composite.c: * src/indent.c: All callers adjusted. * src/xdisp.c (compute_stop_pos): Don't search for static compositions. Search for automatic compositions only after the iterator gets past the composition stop_pos computed last time. Use a better position for limiting search for automatic compositions. (Bug#62780) --- src/composite.c | 16 +++++++++++----- src/composite.h | 2 +- src/indent.c | 8 ++++---- src/xdisp.c | 35 +++++++++++++++++++++++++---------- 4 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/composite.c b/src/composite.c index 164eeb39598..34f369d167a 100644 --- a/src/composite.c +++ b/src/composite.c @@ -1040,7 +1040,9 @@ inhibit_auto_composition (void) composition closest to CHARPOS is found, set cmp_it->stop_pos to the last character of the composition. STRING, if non-nil, is the string (as opposed to a buffer) whose characters should be - tested for being composable. + tested for being composable. INCLUDE_STATIC non-zero means + consider both static and automatic compositions; if zero, look + only for potential automatic compositions. If no composition is found, set cmp_it->ch to -2. If a static composition is found, set cmp_it->ch to -1. Otherwise, set @@ -1050,7 +1052,7 @@ inhibit_auto_composition (void) void composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t endpos, - Lisp_Object string) + Lisp_Object string, bool include_static) { ptrdiff_t start, end; int c; @@ -1084,8 +1086,10 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos, cmp_it->stop_pos = endpos; if (charpos == endpos) return; + /* Look for static compositions. */ /* FIXME: Bidi is not yet handled well in static composition. */ - if (charpos < endpos + if (include_static + && charpos < endpos && find_composition (charpos, endpos, &start, &end, &prop, string) && start >= charpos && composition_valid_p (start, end, prop)) @@ -1106,6 +1110,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos, bytepos = string_char_to_byte (string, charpos); } + /* Look for automatic compositions. */ start = charpos; if (charpos < endpos) { @@ -1285,7 +1290,8 @@ composition_reseat_it (struct composition_it *cmp_it, ptrdiff_t charpos, { if (cmp_it->ch == -2) { - composition_compute_stop_pos (cmp_it, charpos, bytepos, endpos, string); + composition_compute_stop_pos (cmp_it, charpos, bytepos, endpos, string, + true); if (cmp_it->ch == -2 || cmp_it->stop_pos != charpos) /* The current position is not composed. */ return 0; @@ -1424,7 +1430,7 @@ composition_reseat_it (struct composition_it *cmp_it, ptrdiff_t charpos, } if (cmp_it->reversed_p) endpos = -1; - composition_compute_stop_pos (cmp_it, charpos, bytepos, endpos, string); + composition_compute_stop_pos (cmp_it, charpos, bytepos, endpos, string, true); return 0; } diff --git a/src/composite.h b/src/composite.h index e81465d90cc..0f791c1ea62 100644 --- a/src/composite.h +++ b/src/composite.h @@ -348,7 +348,7 @@ extern bool find_automatic_composition (ptrdiff_t, ptrdiff_t, ptrdiff_t, extern void composition_compute_stop_pos (struct composition_it *, ptrdiff_t, ptrdiff_t, ptrdiff_t, - Lisp_Object); + Lisp_Object, bool); extern bool composition_reseat_it (struct composition_it *, ptrdiff_t, ptrdiff_t, ptrdiff_t, struct window *, signed char, struct face *, Lisp_Object); diff --git a/src/indent.c b/src/indent.c index 08d2bf5ea28..16285ce84e2 100644 --- a/src/indent.c +++ b/src/indent.c @@ -616,7 +616,7 @@ scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol, memset (&cmp_it, 0, sizeof cmp_it); cmp_it.id = -1; - composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, Qnil); + composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, Qnil, true); /* Scan forward to the target position. */ while (scan < end) @@ -681,7 +681,7 @@ scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol, { cmp_it.id = -1; composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, - Qnil); + Qnil, true); } else cmp_it.from = cmp_it.to; @@ -1290,7 +1290,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, prev_tab_offset = tab_offset; memset (&cmp_it, 0, sizeof cmp_it); cmp_it.id = -1; - composition_compute_stop_pos (&cmp_it, pos, pos_byte, to, Qnil); + composition_compute_stop_pos (&cmp_it, pos, pos_byte, to, Qnil, true); unsigned short int quit_count = 0; @@ -1600,7 +1600,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, { cmp_it.id = -1; composition_compute_stop_pos (&cmp_it, pos, pos_byte, to, - Qnil); + Qnil, true); } else cmp_it.from = cmp_it.to; diff --git a/src/xdisp.c b/src/xdisp.c index 76d6592bf00..18ea042e212 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -4056,7 +4056,7 @@ compute_stop_pos (struct it *it) { register INTERVAL iv, next_iv; Lisp_Object object, limit, position; - ptrdiff_t charpos, bytepos; + ptrdiff_t charpos, bytepos, cmp_limit_pos = -1; if (STRINGP (it->string)) { @@ -4126,7 +4126,10 @@ compute_stop_pos (struct it *it) } } if (found) - pos--; + { + pos--; + cmp_limit_pos = pos; + } else if (it->stop_charpos < endpos) pos = it->stop_charpos; else @@ -4184,14 +4187,25 @@ compute_stop_pos (struct it *it) } } - if (it->cmp_it.id < 0) + if (it->cmp_it.id < 0 + && (STRINGP (it->string) + || ((!it->bidi_p || it->bidi_it.scan_dir >= 0) + && it->cmp_it.stop_pos <= IT_CHARPOS (*it)))) { ptrdiff_t stoppos = it->end_charpos; + /* If we found, above, a buffer position that cannot be part of + an automatic composition, limit the search of composable + characters to that position. */ if (it->bidi_p && it->bidi_it.scan_dir < 0) stoppos = -1; + else if (cmp_limit_pos > 0) + stoppos = cmp_limit_pos; + /* Force composition_compute_stop_pos avoid the costly search + for static compositions, since those were already found by + looking at text properties, above. */ composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, - stoppos, it->string); + stoppos, it->string, false); } eassert (STRINGP (it->string) @@ -7716,7 +7730,7 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string, if (endpos > it->end_charpos) endpos = it->end_charpos; composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos, - it->string); + it->string, true); } CHECK_IT (it); } @@ -8404,7 +8418,7 @@ set_iterator_to_next (struct it *it, bool reseat_p) where to stop. */ stop = -1; composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), - IT_BYTEPOS (*it), stop, Qnil); + IT_BYTEPOS (*it), stop, Qnil, true); } } else @@ -8435,7 +8449,8 @@ set_iterator_to_next (struct it *it, bool reseat_p) if (it->bidi_it.scan_dir < 0) stop = -1; composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), - IT_BYTEPOS (*it), stop, Qnil); + IT_BYTEPOS (*it), stop, Qnil, + true); } } eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it))); @@ -8591,7 +8606,7 @@ set_iterator_to_next (struct it *it, bool reseat_p) composition_compute_stop_pos (&it->cmp_it, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it), stop, - it->string); + it->string, true); } } else @@ -8628,7 +8643,7 @@ set_iterator_to_next (struct it *it, bool reseat_p) composition_compute_stop_pos (&it->cmp_it, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it), stop, - it->string); + it->string, true); } } } @@ -8879,7 +8894,7 @@ get_visually_first_element (struct it *it) if (it->bidi_it.scan_dir < 0) stop = -1; composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop, - it->string); + it->string, true); } } -- 2.39.5