diff options
| author | Eli Zaretskii | 2011-10-20 14:39:52 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2011-10-20 14:39:52 +0200 |
| commit | 7b5d6677eca241b608f32b1de8d60e03758ec157 (patch) | |
| tree | acb4c67188e9ca5e819c44350a3907812638a904 /src | |
| parent | 1ebc9c872623dab285842f273a18937223f4d3c6 (diff) | |
| download | emacs-7b5d6677eca241b608f32b1de8d60e03758ec157.tar.gz emacs-7b5d6677eca241b608f32b1de8d60e03758ec157.zip | |
Improve the speedup of bidi display introduced in 2011-10-18T16:56:09Z!eliz@gnu.org for bug#9771.
src/dispextern.h (struct bidi_it): New member next_en_type.
src/bidi.c (bidi_line_init): Initialize the next_en_type member.
(bidi_resolve_explicit_1): When next_en_pos is valid for the
current character, check also for next_en_type being WEAK_EN.
(bidi_resolve_weak): Don't enter the expensive loop if the current
position is before next_en_pos. Record the bidi type of the first
non-ET, non-BN character we find, in addition to its position.
(bidi_level_of_next_char): Invalidate next_en_type when
next_en_pos is over-stepped.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 13 | ||||
| -rw-r--r-- | src/bidi.c | 42 | ||||
| -rw-r--r-- | src/dispextern.h | 3 |
3 files changed, 43 insertions, 15 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 36b205a120d..3f9b5beeab6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2011-10-20 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * dispextern.h (struct bidi_it): New member next_en_type. | ||
| 4 | |||
| 5 | * bidi.c (bidi_line_init): Initialize the next_en_type member. | ||
| 6 | (bidi_resolve_explicit_1): When next_en_pos is valid for the | ||
| 7 | current character, check also for next_en_type being WEAK_EN. | ||
| 8 | (bidi_resolve_weak): Don't enter the expensive loop if the current | ||
| 9 | position is before next_en_pos. Record the bidi type of the first | ||
| 10 | non-ET, non-BN character we find, in addition to its position. | ||
| 11 | (bidi_level_of_next_char): Invalidate next_en_type when | ||
| 12 | next_en_pos is over-stepped. | ||
| 13 | |||
| 1 | 2011-10-20 Paul Eggert <eggert@cs.ucla.edu> | 14 | 2011-10-20 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 15 | ||
| 3 | Time zone name fixes for non-ASCII locales (Bug#641, Bug#9794) | 16 | Time zone name fixes for non-ASCII locales (Bug#641, Bug#9794) |
diff --git a/src/bidi.c b/src/bidi.c index 29e3c817318..d13baed63ed 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -849,6 +849,7 @@ bidi_line_init (struct bidi_it *bidi_it) | |||
| 849 | /* Setting this to zero will force its recomputation the first time | 849 | /* Setting this to zero will force its recomputation the first time |
| 850 | we need it for W5. */ | 850 | we need it for W5. */ |
| 851 | bidi_it->next_en_pos = 0; | 851 | bidi_it->next_en_pos = 0; |
| 852 | bidi_it->next_en_type = UNKNOWN_BT; | ||
| 852 | bidi_it->next_for_ws.type = UNKNOWN_BT; | 853 | bidi_it->next_for_ws.type = UNKNOWN_BT; |
| 853 | bidi_set_sor_type (bidi_it, | 854 | bidi_set_sor_type (bidi_it, |
| 854 | (bidi_it->paragraph_dir == R2L ? 1 : 0), | 855 | (bidi_it->paragraph_dir == R2L ? 1 : 0), |
| @@ -1437,7 +1438,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1437 | } | 1438 | } |
| 1438 | } | 1439 | } |
| 1439 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ | 1440 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ |
| 1440 | || bidi_it->next_en_pos > bidi_it->charpos) | 1441 | || (bidi_it->next_en_pos > bidi_it->charpos |
| 1442 | && bidi_it->next_en_type == WEAK_EN)) | ||
| 1441 | type = WEAK_EN; | 1443 | type = WEAK_EN; |
| 1442 | break; | 1444 | break; |
| 1443 | case LRE: /* X3 */ | 1445 | case LRE: /* X3 */ |
| @@ -1473,7 +1475,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1473 | } | 1475 | } |
| 1474 | } | 1476 | } |
| 1475 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ | 1477 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ |
| 1476 | || bidi_it->next_en_pos > bidi_it->charpos) | 1478 | || (bidi_it->next_en_pos > bidi_it->charpos |
| 1479 | && bidi_it->next_en_type == WEAK_EN)) | ||
| 1477 | type = WEAK_EN; | 1480 | type = WEAK_EN; |
| 1478 | break; | 1481 | break; |
| 1479 | case PDF: /* X7 */ | 1482 | case PDF: /* X7 */ |
| @@ -1499,7 +1502,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1499 | } | 1502 | } |
| 1500 | } | 1503 | } |
| 1501 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ | 1504 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ |
| 1502 | || bidi_it->next_en_pos > bidi_it->charpos) | 1505 | || (bidi_it->next_en_pos > bidi_it->charpos |
| 1506 | && bidi_it->next_en_type == WEAK_EN)) | ||
| 1503 | type = WEAK_EN; | 1507 | type = WEAK_EN; |
| 1504 | break; | 1508 | break; |
| 1505 | default: | 1509 | default: |
| @@ -1731,10 +1735,15 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1731 | else if (type == WEAK_ET /* W5: ET with EN before or after it */ | 1735 | else if (type == WEAK_ET /* W5: ET with EN before or after it */ |
| 1732 | || type == WEAK_BN) /* W5/Retaining */ | 1736 | || type == WEAK_BN) /* W5/Retaining */ |
| 1733 | { | 1737 | { |
| 1734 | if (bidi_it->prev.type_after_w1 == WEAK_EN /* ET/BN w/EN before it */ | 1738 | if (bidi_it->prev.type_after_w1 == WEAK_EN) /* ET/BN w/EN before it */ |
| 1735 | || bidi_it->next_en_pos > bidi_it->charpos) | ||
| 1736 | type = WEAK_EN; | 1739 | type = WEAK_EN; |
| 1737 | else if (bidi_it->next_en_pos >=0) /* W5: ET/BN with EN after it. */ | 1740 | else if (bidi_it->next_en_pos > bidi_it->charpos |
| 1741 | && bidi_it->next_en_type != WEAK_BN) | ||
| 1742 | { | ||
| 1743 | if (bidi_it->next_en_type == WEAK_EN) /* ET/BN with EN after it */ | ||
| 1744 | type = WEAK_EN; | ||
| 1745 | } | ||
| 1746 | else if (bidi_it->next_en_pos >=0) | ||
| 1738 | { | 1747 | { |
| 1739 | EMACS_INT en_pos = bidi_it->charpos + bidi_it->nchars; | 1748 | EMACS_INT en_pos = bidi_it->charpos + bidi_it->nchars; |
| 1740 | const unsigned char *s = (STRINGP (bidi_it->string.lstring) | 1749 | const unsigned char *s = (STRINGP (bidi_it->string.lstring) |
| @@ -1763,25 +1772,27 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1763 | en_pos = bidi_it->charpos; | 1772 | en_pos = bidi_it->charpos; |
| 1764 | bidi_copy_it (bidi_it, &saved_it); | 1773 | bidi_copy_it (bidi_it, &saved_it); |
| 1765 | } | 1774 | } |
| 1775 | /* Remember this position, to speed up processing of the | ||
| 1776 | next ETs. */ | ||
| 1777 | bidi_it->next_en_pos = en_pos; | ||
| 1766 | if (type_of_next == WEAK_EN) | 1778 | if (type_of_next == WEAK_EN) |
| 1767 | { | 1779 | { |
| 1768 | /* If the last strong character is AL, the EN we've | 1780 | /* If the last strong character is AL, the EN we've |
| 1769 | found will become AN when we get to it (W2). */ | 1781 | found will become AN when we get to it (W2). */ |
| 1770 | if (bidi_it->last_strong.type_after_w1 != STRONG_AL) | 1782 | if (bidi_it->last_strong.type_after_w1 == STRONG_AL) |
| 1771 | { | 1783 | type_of_next = WEAK_AN; |
| 1772 | type = WEAK_EN; | ||
| 1773 | /* Remember this EN position, to speed up processing | ||
| 1774 | of the next ETs. */ | ||
| 1775 | bidi_it->next_en_pos = en_pos; | ||
| 1776 | } | ||
| 1777 | else if (type == WEAK_BN) | 1784 | else if (type == WEAK_BN) |
| 1778 | type = NEUTRAL_ON; /* W6/Retaining */ | 1785 | type = NEUTRAL_ON; /* W6/Retaining */ |
| 1786 | else | ||
| 1787 | type = WEAK_EN; | ||
| 1779 | } | 1788 | } |
| 1780 | else if (type_of_next == NEUTRAL_B) | 1789 | else if (type_of_next == NEUTRAL_B) |
| 1781 | /* Record the fact that there are no more ENs from | 1790 | /* Record the fact that there are no more ENs from |
| 1782 | here to the end of paragraph, to avoid entering the | 1791 | here to the end of paragraph, to avoid entering the |
| 1783 | loop above ever again in this paragraph. */ | 1792 | loop above ever again in this paragraph. */ |
| 1784 | bidi_it->next_en_pos = -1; | 1793 | bidi_it->next_en_pos = -1; |
| 1794 | /* Record the type of the character where we ended our search. */ | ||
| 1795 | bidi_it->next_en_type = type_of_next; | ||
| 1785 | } | 1796 | } |
| 1786 | } | 1797 | } |
| 1787 | } | 1798 | } |
| @@ -2053,7 +2064,10 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2053 | bidi_it->next_for_neutral.type = UNKNOWN_BT; | 2064 | bidi_it->next_for_neutral.type = UNKNOWN_BT; |
| 2054 | if (bidi_it->next_en_pos >= 0 | 2065 | if (bidi_it->next_en_pos >= 0 |
| 2055 | && bidi_it->charpos >= bidi_it->next_en_pos) | 2066 | && bidi_it->charpos >= bidi_it->next_en_pos) |
| 2056 | bidi_it->next_en_pos = 0; | 2067 | { |
| 2068 | bidi_it->next_en_pos = 0; | ||
| 2069 | bidi_it->next_en_type = UNKNOWN_BT; | ||
| 2070 | } | ||
| 2057 | if (bidi_it->next_for_ws.type != UNKNOWN_BT | 2071 | if (bidi_it->next_for_ws.type != UNKNOWN_BT |
| 2058 | && bidi_it->charpos >= bidi_it->next_for_ws.charpos) | 2072 | && bidi_it->charpos >= bidi_it->next_for_ws.charpos) |
| 2059 | bidi_it->next_for_ws.type = UNKNOWN_BT; | 2073 | bidi_it->next_for_ws.type = UNKNOWN_BT; |
diff --git a/src/dispextern.h b/src/dispextern.h index 3c157371ef3..dd5f67d2d10 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1856,7 +1856,8 @@ struct bidi_it { | |||
| 1856 | struct bidi_saved_info next_for_neutral; /* surrounding characters for... */ | 1856 | struct bidi_saved_info next_for_neutral; /* surrounding characters for... */ |
| 1857 | struct bidi_saved_info prev_for_neutral; /* ...resolving neutrals */ | 1857 | struct bidi_saved_info prev_for_neutral; /* ...resolving neutrals */ |
| 1858 | struct bidi_saved_info next_for_ws; /* character after sequence of ws */ | 1858 | struct bidi_saved_info next_for_ws; /* character after sequence of ws */ |
| 1859 | EMACS_INT next_en_pos; /* position of next EN char for ET */ | 1859 | EMACS_INT next_en_pos; /* pos. of next char for determining ET type */ |
| 1860 | bidi_type_t next_en_type; /* type of char at next_en_pos */ | ||
| 1860 | EMACS_INT ignore_bn_limit; /* position until which to ignore BNs */ | 1861 | EMACS_INT ignore_bn_limit; /* position until which to ignore BNs */ |
| 1861 | bidi_dir_t sor; /* direction of start-of-run in effect */ | 1862 | bidi_dir_t sor; /* direction of start-of-run in effect */ |
| 1862 | int scan_dir; /* direction of text scan, 1: forw, -1: back */ | 1863 | int scan_dir; /* direction of text scan, 1: forw, -1: back */ |