diff options
| author | Eli Zaretskii | 2023-04-29 11:50:47 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2023-04-29 11:50:47 +0300 |
| commit | b408df11e350941eb099cde87d83340e8e7e0378 (patch) | |
| tree | 22735d091e0934bcf80ec8261ea1fe4156dc89b5 /src | |
| parent | 5c0f0751d0541bbdf0696ef3e76e2ad6562adcb9 (diff) | |
| download | emacs-b408df11e350941eb099cde87d83340e8e7e0378.tar.gz emacs-b408df11e350941eb099cde87d83340e8e7e0378.zip | |
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)
Diffstat (limited to 'src')
| -rw-r--r-- | src/composite.c | 16 | ||||
| -rw-r--r-- | src/composite.h | 2 | ||||
| -rw-r--r-- | src/indent.c | 8 | ||||
| -rw-r--r-- | 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) | |||
| 1040 | composition closest to CHARPOS is found, set cmp_it->stop_pos to | 1040 | composition closest to CHARPOS is found, set cmp_it->stop_pos to |
| 1041 | the last character of the composition. STRING, if non-nil, is | 1041 | the last character of the composition. STRING, if non-nil, is |
| 1042 | the string (as opposed to a buffer) whose characters should be | 1042 | the string (as opposed to a buffer) whose characters should be |
| 1043 | tested for being composable. | 1043 | tested for being composable. INCLUDE_STATIC non-zero means |
| 1044 | consider both static and automatic compositions; if zero, look | ||
| 1045 | only for potential automatic compositions. | ||
| 1044 | 1046 | ||
| 1045 | If no composition is found, set cmp_it->ch to -2. If a static | 1047 | If no composition is found, set cmp_it->ch to -2. If a static |
| 1046 | composition is found, set cmp_it->ch to -1. Otherwise, set | 1048 | composition is found, set cmp_it->ch to -1. Otherwise, set |
| @@ -1050,7 +1052,7 @@ inhibit_auto_composition (void) | |||
| 1050 | void | 1052 | void |
| 1051 | composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos, | 1053 | composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos, |
| 1052 | ptrdiff_t bytepos, ptrdiff_t endpos, | 1054 | ptrdiff_t bytepos, ptrdiff_t endpos, |
| 1053 | Lisp_Object string) | 1055 | Lisp_Object string, bool include_static) |
| 1054 | { | 1056 | { |
| 1055 | ptrdiff_t start, end; | 1057 | ptrdiff_t start, end; |
| 1056 | int c; | 1058 | int c; |
| @@ -1084,8 +1086,10 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos, | |||
| 1084 | cmp_it->stop_pos = endpos; | 1086 | cmp_it->stop_pos = endpos; |
| 1085 | if (charpos == endpos) | 1087 | if (charpos == endpos) |
| 1086 | return; | 1088 | return; |
| 1089 | /* Look for static compositions. */ | ||
| 1087 | /* FIXME: Bidi is not yet handled well in static composition. */ | 1090 | /* FIXME: Bidi is not yet handled well in static composition. */ |
| 1088 | if (charpos < endpos | 1091 | if (include_static |
| 1092 | && charpos < endpos | ||
| 1089 | && find_composition (charpos, endpos, &start, &end, &prop, string) | 1093 | && find_composition (charpos, endpos, &start, &end, &prop, string) |
| 1090 | && start >= charpos | 1094 | && start >= charpos |
| 1091 | && composition_valid_p (start, end, prop)) | 1095 | && composition_valid_p (start, end, prop)) |
| @@ -1106,6 +1110,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos, | |||
| 1106 | bytepos = string_char_to_byte (string, charpos); | 1110 | bytepos = string_char_to_byte (string, charpos); |
| 1107 | } | 1111 | } |
| 1108 | 1112 | ||
| 1113 | /* Look for automatic compositions. */ | ||
| 1109 | start = charpos; | 1114 | start = charpos; |
| 1110 | if (charpos < endpos) | 1115 | if (charpos < endpos) |
| 1111 | { | 1116 | { |
| @@ -1285,7 +1290,8 @@ composition_reseat_it (struct composition_it *cmp_it, ptrdiff_t charpos, | |||
| 1285 | { | 1290 | { |
| 1286 | if (cmp_it->ch == -2) | 1291 | if (cmp_it->ch == -2) |
| 1287 | { | 1292 | { |
| 1288 | composition_compute_stop_pos (cmp_it, charpos, bytepos, endpos, string); | 1293 | composition_compute_stop_pos (cmp_it, charpos, bytepos, endpos, string, |
| 1294 | true); | ||
| 1289 | if (cmp_it->ch == -2 || cmp_it->stop_pos != charpos) | 1295 | if (cmp_it->ch == -2 || cmp_it->stop_pos != charpos) |
| 1290 | /* The current position is not composed. */ | 1296 | /* The current position is not composed. */ |
| 1291 | return 0; | 1297 | return 0; |
| @@ -1424,7 +1430,7 @@ composition_reseat_it (struct composition_it *cmp_it, ptrdiff_t charpos, | |||
| 1424 | } | 1430 | } |
| 1425 | if (cmp_it->reversed_p) | 1431 | if (cmp_it->reversed_p) |
| 1426 | endpos = -1; | 1432 | endpos = -1; |
| 1427 | composition_compute_stop_pos (cmp_it, charpos, bytepos, endpos, string); | 1433 | composition_compute_stop_pos (cmp_it, charpos, bytepos, endpos, string, true); |
| 1428 | return 0; | 1434 | return 0; |
| 1429 | } | 1435 | } |
| 1430 | 1436 | ||
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, | |||
| 348 | 348 | ||
| 349 | extern void composition_compute_stop_pos (struct composition_it *, | 349 | extern void composition_compute_stop_pos (struct composition_it *, |
| 350 | ptrdiff_t, ptrdiff_t, ptrdiff_t, | 350 | ptrdiff_t, ptrdiff_t, ptrdiff_t, |
| 351 | Lisp_Object); | 351 | Lisp_Object, bool); |
| 352 | extern bool composition_reseat_it (struct composition_it *, ptrdiff_t, | 352 | extern bool composition_reseat_it (struct composition_it *, ptrdiff_t, |
| 353 | ptrdiff_t, ptrdiff_t, struct window *, | 353 | ptrdiff_t, ptrdiff_t, struct window *, |
| 354 | signed char, struct face *, Lisp_Object); | 354 | 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, | |||
| 616 | 616 | ||
| 617 | memset (&cmp_it, 0, sizeof cmp_it); | 617 | memset (&cmp_it, 0, sizeof cmp_it); |
| 618 | cmp_it.id = -1; | 618 | cmp_it.id = -1; |
| 619 | composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, Qnil); | 619 | composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, Qnil, true); |
| 620 | 620 | ||
| 621 | /* Scan forward to the target position. */ | 621 | /* Scan forward to the target position. */ |
| 622 | while (scan < end) | 622 | while (scan < end) |
| @@ -681,7 +681,7 @@ scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol, | |||
| 681 | { | 681 | { |
| 682 | cmp_it.id = -1; | 682 | cmp_it.id = -1; |
| 683 | composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, | 683 | composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, |
| 684 | Qnil); | 684 | Qnil, true); |
| 685 | } | 685 | } |
| 686 | else | 686 | else |
| 687 | cmp_it.from = cmp_it.to; | 687 | cmp_it.from = cmp_it.to; |
| @@ -1290,7 +1290,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, | |||
| 1290 | prev_tab_offset = tab_offset; | 1290 | prev_tab_offset = tab_offset; |
| 1291 | memset (&cmp_it, 0, sizeof cmp_it); | 1291 | memset (&cmp_it, 0, sizeof cmp_it); |
| 1292 | cmp_it.id = -1; | 1292 | cmp_it.id = -1; |
| 1293 | composition_compute_stop_pos (&cmp_it, pos, pos_byte, to, Qnil); | 1293 | composition_compute_stop_pos (&cmp_it, pos, pos_byte, to, Qnil, true); |
| 1294 | 1294 | ||
| 1295 | unsigned short int quit_count = 0; | 1295 | unsigned short int quit_count = 0; |
| 1296 | 1296 | ||
| @@ -1600,7 +1600,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, | |||
| 1600 | { | 1600 | { |
| 1601 | cmp_it.id = -1; | 1601 | cmp_it.id = -1; |
| 1602 | composition_compute_stop_pos (&cmp_it, pos, pos_byte, to, | 1602 | composition_compute_stop_pos (&cmp_it, pos, pos_byte, to, |
| 1603 | Qnil); | 1603 | Qnil, true); |
| 1604 | } | 1604 | } |
| 1605 | else | 1605 | else |
| 1606 | cmp_it.from = cmp_it.to; | 1606 | 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) | |||
| 4056 | { | 4056 | { |
| 4057 | register INTERVAL iv, next_iv; | 4057 | register INTERVAL iv, next_iv; |
| 4058 | Lisp_Object object, limit, position; | 4058 | Lisp_Object object, limit, position; |
| 4059 | ptrdiff_t charpos, bytepos; | 4059 | ptrdiff_t charpos, bytepos, cmp_limit_pos = -1; |
| 4060 | 4060 | ||
| 4061 | if (STRINGP (it->string)) | 4061 | if (STRINGP (it->string)) |
| 4062 | { | 4062 | { |
| @@ -4126,7 +4126,10 @@ compute_stop_pos (struct it *it) | |||
| 4126 | } | 4126 | } |
| 4127 | } | 4127 | } |
| 4128 | if (found) | 4128 | if (found) |
| 4129 | pos--; | 4129 | { |
| 4130 | pos--; | ||
| 4131 | cmp_limit_pos = pos; | ||
| 4132 | } | ||
| 4130 | else if (it->stop_charpos < endpos) | 4133 | else if (it->stop_charpos < endpos) |
| 4131 | pos = it->stop_charpos; | 4134 | pos = it->stop_charpos; |
| 4132 | else | 4135 | else |
| @@ -4184,14 +4187,25 @@ compute_stop_pos (struct it *it) | |||
| 4184 | } | 4187 | } |
| 4185 | } | 4188 | } |
| 4186 | 4189 | ||
| 4187 | if (it->cmp_it.id < 0) | 4190 | if (it->cmp_it.id < 0 |
| 4191 | && (STRINGP (it->string) | ||
| 4192 | || ((!it->bidi_p || it->bidi_it.scan_dir >= 0) | ||
| 4193 | && it->cmp_it.stop_pos <= IT_CHARPOS (*it)))) | ||
| 4188 | { | 4194 | { |
| 4189 | ptrdiff_t stoppos = it->end_charpos; | 4195 | ptrdiff_t stoppos = it->end_charpos; |
| 4190 | 4196 | ||
| 4197 | /* If we found, above, a buffer position that cannot be part of | ||
| 4198 | an automatic composition, limit the search of composable | ||
| 4199 | characters to that position. */ | ||
| 4191 | if (it->bidi_p && it->bidi_it.scan_dir < 0) | 4200 | if (it->bidi_p && it->bidi_it.scan_dir < 0) |
| 4192 | stoppos = -1; | 4201 | stoppos = -1; |
| 4202 | else if (cmp_limit_pos > 0) | ||
| 4203 | stoppos = cmp_limit_pos; | ||
| 4204 | /* Force composition_compute_stop_pos avoid the costly search | ||
| 4205 | for static compositions, since those were already found by | ||
| 4206 | looking at text properties, above. */ | ||
| 4193 | composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, | 4207 | composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, |
| 4194 | stoppos, it->string); | 4208 | stoppos, it->string, false); |
| 4195 | } | 4209 | } |
| 4196 | 4210 | ||
| 4197 | eassert (STRINGP (it->string) | 4211 | eassert (STRINGP (it->string) |
| @@ -7716,7 +7730,7 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string, | |||
| 7716 | if (endpos > it->end_charpos) | 7730 | if (endpos > it->end_charpos) |
| 7717 | endpos = it->end_charpos; | 7731 | endpos = it->end_charpos; |
| 7718 | composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos, | 7732 | composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos, |
| 7719 | it->string); | 7733 | it->string, true); |
| 7720 | } | 7734 | } |
| 7721 | CHECK_IT (it); | 7735 | CHECK_IT (it); |
| 7722 | } | 7736 | } |
| @@ -8404,7 +8418,7 @@ set_iterator_to_next (struct it *it, bool reseat_p) | |||
| 8404 | where to stop. */ | 8418 | where to stop. */ |
| 8405 | stop = -1; | 8419 | stop = -1; |
| 8406 | composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), | 8420 | composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), |
| 8407 | IT_BYTEPOS (*it), stop, Qnil); | 8421 | IT_BYTEPOS (*it), stop, Qnil, true); |
| 8408 | } | 8422 | } |
| 8409 | } | 8423 | } |
| 8410 | else | 8424 | else |
| @@ -8435,7 +8449,8 @@ set_iterator_to_next (struct it *it, bool reseat_p) | |||
| 8435 | if (it->bidi_it.scan_dir < 0) | 8449 | if (it->bidi_it.scan_dir < 0) |
| 8436 | stop = -1; | 8450 | stop = -1; |
| 8437 | composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), | 8451 | composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), |
| 8438 | IT_BYTEPOS (*it), stop, Qnil); | 8452 | IT_BYTEPOS (*it), stop, Qnil, |
| 8453 | true); | ||
| 8439 | } | 8454 | } |
| 8440 | } | 8455 | } |
| 8441 | eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it))); | 8456 | eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it))); |
| @@ -8591,7 +8606,7 @@ set_iterator_to_next (struct it *it, bool reseat_p) | |||
| 8591 | composition_compute_stop_pos (&it->cmp_it, | 8606 | composition_compute_stop_pos (&it->cmp_it, |
| 8592 | IT_STRING_CHARPOS (*it), | 8607 | IT_STRING_CHARPOS (*it), |
| 8593 | IT_STRING_BYTEPOS (*it), stop, | 8608 | IT_STRING_BYTEPOS (*it), stop, |
| 8594 | it->string); | 8609 | it->string, true); |
| 8595 | } | 8610 | } |
| 8596 | } | 8611 | } |
| 8597 | else | 8612 | else |
| @@ -8628,7 +8643,7 @@ set_iterator_to_next (struct it *it, bool reseat_p) | |||
| 8628 | composition_compute_stop_pos (&it->cmp_it, | 8643 | composition_compute_stop_pos (&it->cmp_it, |
| 8629 | IT_STRING_CHARPOS (*it), | 8644 | IT_STRING_CHARPOS (*it), |
| 8630 | IT_STRING_BYTEPOS (*it), stop, | 8645 | IT_STRING_BYTEPOS (*it), stop, |
| 8631 | it->string); | 8646 | it->string, true); |
| 8632 | } | 8647 | } |
| 8633 | } | 8648 | } |
| 8634 | } | 8649 | } |
| @@ -8879,7 +8894,7 @@ get_visually_first_element (struct it *it) | |||
| 8879 | if (it->bidi_it.scan_dir < 0) | 8894 | if (it->bidi_it.scan_dir < 0) |
| 8880 | stop = -1; | 8895 | stop = -1; |
| 8881 | composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop, | 8896 | composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop, |
| 8882 | it->string); | 8897 | it->string, true); |
| 8883 | } | 8898 | } |
| 8884 | } | 8899 | } |
| 8885 | 8900 | ||