diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/composite.c | 6 | ||||
| -rw-r--r-- | src/dispextern.h | 17 | ||||
| -rw-r--r-- | src/window.c | 2 | ||||
| -rw-r--r-- | src/window.h | 1 | ||||
| -rw-r--r-- | src/xdisp.c | 31 |
5 files changed, 50 insertions, 7 deletions
diff --git a/src/composite.c b/src/composite.c index 4d69702171f..d8998b5a1f3 100644 --- a/src/composite.c +++ b/src/composite.c | |||
| @@ -1576,6 +1576,7 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, ptrdiff_t backlim, | |||
| 1576 | Lisp_Object window; | 1576 | Lisp_Object window; |
| 1577 | struct window *w; | 1577 | struct window *w; |
| 1578 | bool need_adjustment = 0; | 1578 | bool need_adjustment = 0; |
| 1579 | ptrdiff_t narrowed_begv; | ||
| 1579 | 1580 | ||
| 1580 | window = Fget_buffer_window (Fcurrent_buffer (), Qnil); | 1581 | window = Fget_buffer_window (Fcurrent_buffer (), Qnil); |
| 1581 | if (NILP (window)) | 1582 | if (NILP (window)) |
| @@ -1586,6 +1587,11 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, ptrdiff_t backlim, | |||
| 1586 | if (NILP (string)) | 1587 | if (NILP (string)) |
| 1587 | { | 1588 | { |
| 1588 | head = backlim < 0 ? BEGV : backlim, tail = ZV, stop = GPT; | 1589 | head = backlim < 0 ? BEGV : backlim, tail = ZV, stop = GPT; |
| 1590 | /* In buffers with very long lines, this function becomes very | ||
| 1591 | slow. Pretend that the buffer is narrowed to make it fast. */ | ||
| 1592 | narrowed_begv = get_narrowed_begv (w); | ||
| 1593 | if (pos > narrowed_begv) | ||
| 1594 | head = narrowed_begv; | ||
| 1589 | cur.pos_byte = CHAR_TO_BYTE (cur.pos); | 1595 | cur.pos_byte = CHAR_TO_BYTE (cur.pos); |
| 1590 | cur.p = BYTE_POS_ADDR (cur.pos_byte); | 1596 | cur.p = BYTE_POS_ADDR (cur.pos_byte); |
| 1591 | } | 1597 | } |
diff --git a/src/dispextern.h b/src/dispextern.h index ca7834dec55..2edf4b73f81 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -2332,6 +2332,10 @@ struct it | |||
| 2332 | with which display_string was called. */ | 2332 | with which display_string was called. */ |
| 2333 | ptrdiff_t end_charpos; | 2333 | ptrdiff_t end_charpos; |
| 2334 | 2334 | ||
| 2335 | /* Alternate begin position of the buffer, which is used to optimize | ||
| 2336 | display (see the WITH_NARROWED_BEGV macro below). */ | ||
| 2337 | ptrdiff_t narrowed_begv; | ||
| 2338 | |||
| 2335 | /* C string to iterate over. Non-null means get characters from | 2339 | /* C string to iterate over. Non-null means get characters from |
| 2336 | this string, otherwise characters are read from current_buffer | 2340 | this string, otherwise characters are read from current_buffer |
| 2337 | or it->string. */ | 2341 | or it->string. */ |
| @@ -2813,6 +2817,18 @@ struct it | |||
| 2813 | reset_box_start_end_flags ((IT)); \ | 2817 | reset_box_start_end_flags ((IT)); \ |
| 2814 | } while (false) | 2818 | } while (false) |
| 2815 | 2819 | ||
| 2820 | /* Execute STATEMENT with a temporarily narrowed buffer. */ | ||
| 2821 | |||
| 2822 | #define WITH_NARROWED_BEGV(STATEMENT) \ | ||
| 2823 | do { \ | ||
| 2824 | ptrdiff_t obegv = BEGV; \ | ||
| 2825 | if (it->narrowed_begv) \ | ||
| 2826 | SET_BUF_BEGV (current_buffer, it->narrowed_begv); \ | ||
| 2827 | STATEMENT; \ | ||
| 2828 | if (it->narrowed_begv) \ | ||
| 2829 | SET_BUF_BEGV (current_buffer, obegv); \ | ||
| 2830 | } while (0) | ||
| 2831 | |||
| 2816 | /* Bit-flags indicating what operation move_it_to should perform. */ | 2832 | /* Bit-flags indicating what operation move_it_to should perform. */ |
| 2817 | 2833 | ||
| 2818 | enum move_operation_enum | 2834 | enum move_operation_enum |
| @@ -3396,6 +3412,7 @@ void mark_window_display_accurate (Lisp_Object, bool); | |||
| 3396 | void redisplay_preserve_echo_area (int); | 3412 | void redisplay_preserve_echo_area (int); |
| 3397 | void init_iterator (struct it *, struct window *, ptrdiff_t, | 3413 | void init_iterator (struct it *, struct window *, ptrdiff_t, |
| 3398 | ptrdiff_t, struct glyph_row *, enum face_id); | 3414 | ptrdiff_t, struct glyph_row *, enum face_id); |
| 3415 | ptrdiff_t get_narrowed_begv (struct window *w); | ||
| 3399 | void init_iterator_to_row_start (struct it *, struct window *, | 3416 | void init_iterator_to_row_start (struct it *, struct window *, |
| 3400 | struct glyph_row *); | 3417 | struct glyph_row *); |
| 3401 | void start_display (struct it *, struct window *, struct text_pos); | 3418 | void start_display (struct it *, struct window *, struct text_pos); |
diff --git a/src/window.c b/src/window.c index af463b90ce6..61ca9feb64d 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -1028,7 +1028,7 @@ window_body_unit_from_symbol (Lisp_Object unit) | |||
| 1028 | /* Return the number of lines/pixels of W's body. Don't count any mode | 1028 | /* Return the number of lines/pixels of W's body. Don't count any mode |
| 1029 | or header line or horizontal divider of W. Rounds down to nearest | 1029 | or header line or horizontal divider of W. Rounds down to nearest |
| 1030 | integer when not working pixelwise. */ | 1030 | integer when not working pixelwise. */ |
| 1031 | static int | 1031 | int |
| 1032 | window_body_height (struct window *w, enum window_body_unit pixelwise) | 1032 | window_body_height (struct window *w, enum window_body_unit pixelwise) |
| 1033 | { | 1033 | { |
| 1034 | int height = (w->pixel_height | 1034 | int height = (w->pixel_height |
diff --git a/src/window.h b/src/window.h index 298a80a5366..c63b1b24d4f 100644 --- a/src/window.h +++ b/src/window.h | |||
| @@ -1193,6 +1193,7 @@ enum window_body_unit | |||
| 1193 | WINDOW_BODY_IN_REMAPPED_CHARS | 1193 | WINDOW_BODY_IN_REMAPPED_CHARS |
| 1194 | }; | 1194 | }; |
| 1195 | extern int window_body_width (struct window *w, enum window_body_unit); | 1195 | extern int window_body_width (struct window *w, enum window_body_unit); |
| 1196 | extern int window_body_height (struct window *w, enum window_body_unit); | ||
| 1196 | enum margin_unit { MARGIN_IN_LINES, MARGIN_IN_PIXELS }; | 1197 | enum margin_unit { MARGIN_IN_LINES, MARGIN_IN_PIXELS }; |
| 1197 | extern int window_scroll_margin (struct window *, enum margin_unit); | 1198 | extern int window_scroll_margin (struct window *, enum margin_unit); |
| 1198 | extern void temp_output_buffer_show (Lisp_Object); | 1199 | extern void temp_output_buffer_show (Lisp_Object); |
diff --git a/src/xdisp.c b/src/xdisp.c index 4089525e10f..e130b23d9a1 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -3425,6 +3425,8 @@ init_iterator (struct it *it, struct window *w, | |||
| 3425 | } | 3425 | } |
| 3426 | } | 3426 | } |
| 3427 | 3427 | ||
| 3428 | it->narrowed_begv = get_narrowed_begv (w); | ||
| 3429 | |||
| 3428 | /* If a buffer position was specified, set the iterator there, | 3430 | /* If a buffer position was specified, set the iterator there, |
| 3429 | getting overlays and face properties from that position. */ | 3431 | getting overlays and face properties from that position. */ |
| 3430 | if (charpos >= BUF_BEG (current_buffer)) | 3432 | if (charpos >= BUF_BEG (current_buffer)) |
| @@ -3491,6 +3493,19 @@ init_iterator (struct it *it, struct window *w, | |||
| 3491 | CHECK_IT (it); | 3493 | CHECK_IT (it); |
| 3492 | } | 3494 | } |
| 3493 | 3495 | ||
| 3496 | /* Compute a suitable value for BEGV that can be used temporarily, to | ||
| 3497 | optimize display, for the buffer in window W. */ | ||
| 3498 | |||
| 3499 | ptrdiff_t | ||
| 3500 | get_narrowed_begv (struct window *w) | ||
| 3501 | { | ||
| 3502 | int len, begv; | ||
| 3503 | len = (1 + ((window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS) * | ||
| 3504 | window_body_height (w, WINDOW_BODY_IN_CANONICAL_CHARS)) / | ||
| 3505 | 10000)) * 10000; | ||
| 3506 | begv = max ((PT / len - 2) * len, BEGV); | ||
| 3507 | return begv == BEGV ? 0 : begv; | ||
| 3508 | } | ||
| 3494 | 3509 | ||
| 3495 | /* Initialize IT for the display of window W with window start POS. */ | 3510 | /* Initialize IT for the display of window W with window start POS. */ |
| 3496 | 3511 | ||
| @@ -6992,7 +7007,8 @@ back_to_previous_line_start (struct it *it) | |||
| 6992 | ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it); | 7007 | ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it); |
| 6993 | 7008 | ||
| 6994 | dec_both (&cp, &bp); | 7009 | dec_both (&cp, &bp); |
| 6995 | IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it)); | 7010 | WITH_NARROWED_BEGV (IT_CHARPOS (*it) = |
| 7011 | find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it))); | ||
| 6996 | } | 7012 | } |
| 6997 | 7013 | ||
| 6998 | 7014 | ||
| @@ -8623,7 +8639,9 @@ get_visually_first_element (struct it *it) | |||
| 8623 | { | 8639 | { |
| 8624 | bool string_p = STRINGP (it->string) || it->s; | 8640 | bool string_p = STRINGP (it->string) || it->s; |
| 8625 | ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV); | 8641 | ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV); |
| 8626 | ptrdiff_t bob = (string_p ? 0 : BEGV); | 8642 | ptrdiff_t bob; |
| 8643 | |||
| 8644 | WITH_NARROWED_BEGV (bob = (string_p ? 0 : BEGV)); | ||
| 8627 | 8645 | ||
| 8628 | if (STRINGP (it->string)) | 8646 | if (STRINGP (it->string)) |
| 8629 | { | 8647 | { |
| @@ -8663,9 +8681,10 @@ get_visually_first_element (struct it *it) | |||
| 8663 | if (string_p) | 8681 | if (string_p) |
| 8664 | it->bidi_it.charpos = it->bidi_it.bytepos = 0; | 8682 | it->bidi_it.charpos = it->bidi_it.bytepos = 0; |
| 8665 | else | 8683 | else |
| 8666 | it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it), | 8684 | WITH_NARROWED_BEGV (it->bidi_it.charpos = |
| 8667 | IT_BYTEPOS (*it), -1, | 8685 | find_newline_no_quit (IT_CHARPOS (*it), |
| 8668 | &it->bidi_it.bytepos); | 8686 | IT_BYTEPOS (*it), -1, |
| 8687 | &it->bidi_it.bytepos)); | ||
| 8669 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true); | 8688 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true); |
| 8670 | do | 8689 | do |
| 8671 | { | 8690 | { |
| @@ -10583,7 +10602,7 @@ move_it_vertically_backward (struct it *it, int dy) | |||
| 10583 | ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it); | 10602 | ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it); |
| 10584 | 10603 | ||
| 10585 | dec_both (&cp, &bp); | 10604 | dec_both (&cp, &bp); |
| 10586 | cp = find_newline_no_quit (cp, bp, -1, NULL); | 10605 | WITH_NARROWED_BEGV (cp = find_newline_no_quit (cp, bp, -1, NULL)); |
| 10587 | move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS); | 10606 | move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS); |
| 10588 | } | 10607 | } |
| 10589 | bidi_unshelve_cache (it3data, true); | 10608 | bidi_unshelve_cache (it3data, true); |