diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog.bidi | 16 | ||||
| -rw-r--r-- | src/bidi.c | 515 | ||||
| -rw-r--r-- | src/dispextern.h | 19 | ||||
| -rw-r--r-- | src/xdisp.c | 40 |
4 files changed, 137 insertions, 453 deletions
diff --git a/src/ChangeLog.bidi b/src/ChangeLog.bidi index 0a362bb8f00..1cd44eff453 100644 --- a/src/ChangeLog.bidi +++ b/src/ChangeLog.bidi | |||
| @@ -1,3 +1,19 @@ | |||
| 1 | 2009-09-19 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (init_iterator): Call bidi_init_it. Set | ||
| 4 | bidi_it->bytepos if buffer position specified. | ||
| 5 | (reseat_1): Don't call bidi_init_it. Call bidi_paragraph_init | ||
| 6 | instead. Move back to preceding character before the call to | ||
| 7 | bidi_get_next_char_visually. | ||
| 8 | |||
| 9 | * bidi.c: Remove all STANDALONE parts. | ||
| 10 | (bidi_init_it): Init bidi_it->charpos and bidi_it->bytepos to -1. | ||
| 11 | Don't call bidi_paragraph_init. Change arguments. | ||
| 12 | (bidi_paragraph_init): Remove code for negative pos. | ||
| 13 | |||
| 14 | * dispextern.h <bidi_it>: Rename orig_type to type_after_w1 and | ||
| 15 | pristine_type to orig_type. | ||
| 16 | |||
| 1 | 2009-09-12 Eli Zaretskii <eliz@gnu.org> | 17 | 2009-09-12 Eli Zaretskii <eliz@gnu.org> |
| 2 | 18 | ||
| 3 | * dispnew.c (direct_output_for_insert): Give up if we are | 19 | * dispnew.c (direct_output_for_insert): Give up if we are |
diff --git a/src/bidi.c b/src/bidi.c index e558b732f40..a7c905239c7 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -36,6 +36,10 @@ Boston, MA 02110-1301, USA. */ | |||
| 36 | more details about its algorithm that finds the next visual-order | 36 | more details about its algorithm that finds the next visual-order |
| 37 | character by resolving their levels on the fly. | 37 | character by resolving their levels on the fly. |
| 38 | 38 | ||
| 39 | If you want to understand the code, you will have to read it | ||
| 40 | together with the relevant portions of UAX#9. The comments include | ||
| 41 | references to UAX#9 rules, for that very reason. | ||
| 42 | |||
| 39 | A note about references to UAX#9 rules: if the reference says | 43 | A note about references to UAX#9 rules: if the reference says |
| 40 | something like "X9/Retaining", it means that you need to refer to | 44 | something like "X9/Retaining", it means that you need to refer to |
| 41 | rule X9 and to its modifications decribed in the "Implementation | 45 | rule X9 and to its modifications decribed in the "Implementation |
| @@ -78,63 +82,6 @@ static Lisp_Object bidi_type_table; | |||
| 78 | #define BIDI_EOB -1 | 82 | #define BIDI_EOB -1 |
| 79 | #define BIDI_BOB -2 | 83 | #define BIDI_BOB -2 |
| 80 | 84 | ||
| 81 | #ifdef TEST_STANDALONE | ||
| 82 | /* Testing. */ | ||
| 83 | |||
| 84 | static unsigned char *input_buf; | ||
| 85 | static size_t input_buf_size; | ||
| 86 | |||
| 87 | int _fetch_multibyte_char_len, _c_c_; | ||
| 88 | |||
| 89 | #undef FETCH_CHAR_ADVANCE | ||
| 90 | #define FETCH_CHAR_ADVANCE(ch, cp, bp) \ | ||
| 91 | do { \ | ||
| 92 | ch = input_buf[cp]; \ | ||
| 93 | (cp)++; \ | ||
| 94 | (bp)++; \ | ||
| 95 | if (ch == '\0') \ | ||
| 96 | ch = BIDI_EOB; \ | ||
| 97 | } while (0) | ||
| 98 | |||
| 99 | #undef FETCH_CHAR | ||
| 100 | #define FETCH_CHAR(n) ((_c_c_ = input_buf[n]) ? _c_c_ : BIDI_EOB) | ||
| 101 | |||
| 102 | #undef CHAR_CHARSET | ||
| 103 | #define CHAR_CHARSET(c) \ | ||
| 104 | (((c) >= 128 || ((c) < 8 && (c)) || ((c) >= 'A' && (c) < 'X')) \ | ||
| 105 | ? CHARSET_HEBREW \ | ||
| 106 | : ((((c) >= 'X' && (c) <= 'Z') || ((c) >= '6' && (c) <= '9')) \ | ||
| 107 | ? CHARSET_ARABIC \ | ||
| 108 | : CHARSET_ASCII)) | ||
| 109 | |||
| 110 | #undef CHAR_TO_BYTE | ||
| 111 | #define CHAR_TO_BYTE(pos) (pos) | ||
| 112 | |||
| 113 | #define char_bytes(ch) 1 | ||
| 114 | |||
| 115 | #undef LRE_CHAR | ||
| 116 | #undef LRO_CHAR | ||
| 117 | #undef RLE_CHAR | ||
| 118 | #undef RLO_CHAR | ||
| 119 | #undef PDF_CHAR | ||
| 120 | #undef RLM_CHAR | ||
| 121 | #undef LRM_CHAR | ||
| 122 | |||
| 123 | #define LRE_CHAR 1 | ||
| 124 | #define LRO_CHAR 2 | ||
| 125 | #define RLE_CHAR 3 | ||
| 126 | #define RLO_CHAR 4 | ||
| 127 | #define PDF_CHAR 5 | ||
| 128 | #define RLM_CHAR 6 | ||
| 129 | #define LRM_CHAR 7 | ||
| 130 | |||
| 131 | static const char *bidi_name[] = | ||
| 132 | { | ||
| 133 | "[???]", "[LRE]", "[LRO]", "[RLE]", "[RLO]", "[PDF]", "[RLM]", "[LRM]" | ||
| 134 | }; | ||
| 135 | |||
| 136 | #endif /* TEST_STANDALONE */ | ||
| 137 | |||
| 138 | /* Local data structures. (Look in dispextern.h for the rest.) */ | 85 | /* Local data structures. (Look in dispextern.h for the rest.) */ |
| 139 | 86 | ||
| 140 | /* What we need to know about the current paragraph. */ | 87 | /* What we need to know about the current paragraph. */ |
| @@ -462,11 +409,7 @@ bidi_initialize () | |||
| 462 | static int | 409 | static int |
| 463 | bidi_is_arabic_number (int ch) | 410 | bidi_is_arabic_number (int ch) |
| 464 | { | 411 | { |
| 465 | #ifdef TEST_STANDALONE | ||
| 466 | return ch >= '6' && ch <= '9'; | ||
| 467 | #else | ||
| 468 | return 0; /* FIXME! */ | 412 | return 0; /* FIXME! */ |
| 469 | #endif | ||
| 470 | } | 413 | } |
| 471 | 414 | ||
| 472 | /* Return the bidi type of a character CH. */ | 415 | /* Return the bidi type of a character CH. */ |
| @@ -700,8 +643,8 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) | |||
| 700 | costly copying of the entire struct. */ | 643 | costly copying of the entire struct. */ |
| 701 | bidi_cache[idx].type = bidi_it->type; | 644 | bidi_cache[idx].type = bidi_it->type; |
| 702 | bidi_check_type (bidi_it->type); | 645 | bidi_check_type (bidi_it->type); |
| 703 | bidi_cache[idx].orig_type = bidi_it->orig_type; | 646 | bidi_cache[idx].type_after_w1 = bidi_it->type_after_w1; |
| 704 | bidi_check_type (bidi_it->orig_type); | 647 | bidi_check_type (bidi_it->type_after_w1); |
| 705 | if (resolved) | 648 | if (resolved) |
| 706 | bidi_cache[idx].resolved_level = bidi_it->resolved_level; | 649 | bidi_cache[idx].resolved_level = bidi_it->resolved_level; |
| 707 | else | 650 | else |
| @@ -782,13 +725,13 @@ bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after) | |||
| 782 | bidi_it->prev_was_pdf = 1; | 725 | bidi_it->prev_was_pdf = 1; |
| 783 | 726 | ||
| 784 | bidi_it->prev.type = UNKNOWN_BT; | 727 | bidi_it->prev.type = UNKNOWN_BT; |
| 785 | bidi_it->last_strong.type = bidi_it->last_strong.orig_type = | 728 | bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 = |
| 786 | bidi_it->last_strong.pristine_type = UNKNOWN_BT; | 729 | bidi_it->last_strong.orig_type = UNKNOWN_BT; |
| 787 | bidi_it->prev_for_neutral.type = bidi_it->sor == R2L ? STRONG_R : STRONG_L; | 730 | bidi_it->prev_for_neutral.type = bidi_it->sor == R2L ? STRONG_R : STRONG_L; |
| 788 | bidi_it->prev_for_neutral.charpos = bidi_it->charpos; | 731 | bidi_it->prev_for_neutral.charpos = bidi_it->charpos; |
| 789 | bidi_it->prev_for_neutral.bytepos = bidi_it->bytepos; | 732 | bidi_it->prev_for_neutral.bytepos = bidi_it->bytepos; |
| 790 | bidi_it->next_for_neutral.type = bidi_it->next_for_neutral.orig_type = | 733 | bidi_it->next_for_neutral.type = bidi_it->next_for_neutral.type_after_w1 = |
| 791 | bidi_it->next_for_neutral.pristine_type = UNKNOWN_BT; | 734 | bidi_it->next_for_neutral.orig_type = UNKNOWN_BT; |
| 792 | bidi_it->ignore_bn_limit = 0; /* meaning it's unknown */ | 735 | bidi_it->ignore_bn_limit = 0; /* meaning it's unknown */ |
| 793 | } | 736 | } |
| 794 | 737 | ||
| @@ -804,14 +747,6 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it) | |||
| 804 | int pos = bidi_it->charpos, bytepos = bidi_it->bytepos; | 747 | int pos = bidi_it->charpos, bytepos = bidi_it->bytepos; |
| 805 | int ch; | 748 | int ch; |
| 806 | 749 | ||
| 807 | if (pos < 0) | ||
| 808 | pos = bytepos = 0; | ||
| 809 | else if (bidi_it->ch != BIDI_EOB) | ||
| 810 | { | ||
| 811 | pos++; | ||
| 812 | bytepos += bidi_it->ch_len; | ||
| 813 | } | ||
| 814 | |||
| 815 | ch = FETCH_CHAR (bytepos); | 750 | ch = FETCH_CHAR (bytepos); |
| 816 | pos++; | 751 | pos++; |
| 817 | bytepos += CHAR_BYTES (ch); | 752 | bytepos += CHAR_BYTES (ch); |
| @@ -863,45 +798,32 @@ bidi_set_paragraph_end (struct bidi_it *bidi_it) | |||
| 863 | bidi_it->new_paragraph = 1; | 798 | bidi_it->new_paragraph = 1; |
| 864 | } | 799 | } |
| 865 | 800 | ||
| 866 | /* Initialize the bidi iterator from buffer position POS for paragraph | 801 | /* Initialize the bidi iterator from buffer position CHARPOS. */ |
| 867 | direction DIR. Return the embedding level at POS. */ | ||
| 868 | void | 802 | void |
| 869 | bidi_init_it (int pos, bidi_dir_t dir, struct bidi_it *bidi_it) | 803 | bidi_init_it (int charpos, int bytepos, struct bidi_it *bidi_it) |
| 870 | { | 804 | { |
| 871 | if (! bidi_initialized) | 805 | if (! bidi_initialized) |
| 872 | bidi_initialize (); | 806 | bidi_initialize (); |
| 873 | bidi_set_paragraph_end (bidi_it); | 807 | bidi_set_paragraph_end (bidi_it); |
| 874 | bidi_it->charpos = pos; | 808 | bidi_it->charpos = charpos; |
| 875 | if (pos <= 0) | 809 | bidi_it->bytepos = bytepos; |
| 876 | { | 810 | bidi_it->ch_len = 1; |
| 877 | bidi_it->bytepos = bidi_it->charpos; | ||
| 878 | bidi_it->ch_len = 1; /* so that incrementing bytepos works */ | ||
| 879 | } | ||
| 880 | else | ||
| 881 | { | ||
| 882 | bidi_it->bytepos = CHAR_TO_BYTE (pos); | ||
| 883 | bidi_it->ch_len | ||
| 884 | = MULTIBYTE_FORM_LENGTH (BYTE_POS_ADDR (bidi_it->bytepos), | ||
| 885 | MAX_MULTIBYTE_LENGTH); | ||
| 886 | } | ||
| 887 | bidi_it->ch = '\x1d'; /* FIXME: should be U+2029 */ | ||
| 888 | bidi_it->type = NEUTRAL_B; | 811 | bidi_it->type = NEUTRAL_B; |
| 812 | bidi_it->type_after_w1 = UNKNOWN_BT; | ||
| 889 | bidi_it->orig_type = UNKNOWN_BT; | 813 | bidi_it->orig_type = UNKNOWN_BT; |
| 890 | bidi_it->pristine_type = UNKNOWN_BT; | ||
| 891 | bidi_it->prev_was_pdf = 0; | 814 | bidi_it->prev_was_pdf = 0; |
| 892 | bidi_it->prev.type = bidi_it->prev.orig_type = UNKNOWN_BT; | 815 | bidi_it->prev.type = bidi_it->prev.type_after_w1 = UNKNOWN_BT; |
| 893 | bidi_it->last_strong.type = bidi_it->last_strong.orig_type = | 816 | bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 = |
| 894 | bidi_it->last_strong.pristine_type = UNKNOWN_BT; | 817 | bidi_it->last_strong.orig_type = UNKNOWN_BT; |
| 895 | bidi_it->next_for_neutral.charpos = -1; | 818 | bidi_it->next_for_neutral.charpos = -1; |
| 896 | bidi_it->next_for_neutral.type = | 819 | bidi_it->next_for_neutral.type = |
| 897 | bidi_it->next_for_neutral.orig_type = | 820 | bidi_it->next_for_neutral.type_after_w1 = |
| 898 | bidi_it->next_for_neutral.pristine_type = UNKNOWN_BT; | 821 | bidi_it->next_for_neutral.orig_type = UNKNOWN_BT; |
| 899 | bidi_it->prev_for_neutral.charpos = -1; | 822 | bidi_it->prev_for_neutral.charpos = -1; |
| 900 | bidi_it->prev_for_neutral.type = | 823 | bidi_it->prev_for_neutral.type = |
| 901 | bidi_it->prev_for_neutral.orig_type = | 824 | bidi_it->prev_for_neutral.type_after_w1 = |
| 902 | bidi_it->prev_for_neutral.pristine_type = UNKNOWN_BT; | 825 | bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT; |
| 903 | bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */ | 826 | bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */ |
| 904 | bidi_paragraph_init (dir, bidi_it); | ||
| 905 | } | 827 | } |
| 906 | 828 | ||
| 907 | /* Push the current embedding level and override status; reset the | 829 | /* Push the current embedding level and override status; reset the |
| @@ -937,10 +859,10 @@ bidi_remember_char (struct bidi_saved_info *saved_info, | |||
| 937 | saved_info->bytepos = bidi_it->bytepos; | 859 | saved_info->bytepos = bidi_it->bytepos; |
| 938 | saved_info->type = bidi_it->type; | 860 | saved_info->type = bidi_it->type; |
| 939 | bidi_check_type (bidi_it->type); | 861 | bidi_check_type (bidi_it->type); |
| 862 | saved_info->type_after_w1 = bidi_it->type_after_w1; | ||
| 863 | bidi_check_type (bidi_it->type_after_w1); | ||
| 940 | saved_info->orig_type = bidi_it->orig_type; | 864 | saved_info->orig_type = bidi_it->orig_type; |
| 941 | bidi_check_type (bidi_it->orig_type); | 865 | bidi_check_type (bidi_it->orig_type); |
| 942 | saved_info->pristine_type = bidi_it->pristine_type; | ||
| 943 | bidi_check_type (bidi_it->pristine_type); | ||
| 944 | } | 866 | } |
| 945 | 867 | ||
| 946 | /* Resolve the type of a neutral character according to the type of | 868 | /* Resolve the type of a neutral character according to the type of |
| @@ -1003,20 +925,20 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1003 | bidi_it->ch_len = CHAR_BYTES (curchar); | 925 | bidi_it->ch_len = CHAR_BYTES (curchar); |
| 1004 | 926 | ||
| 1005 | type = bidi_get_type (curchar); | 927 | type = bidi_get_type (curchar); |
| 1006 | bidi_it->pristine_type = type; | 928 | bidi_it->orig_type = type; |
| 1007 | bidi_check_type (bidi_it->pristine_type); | 929 | bidi_check_type (bidi_it->orig_type); |
| 1008 | 930 | ||
| 1009 | if (type != PDF) | 931 | if (type != PDF) |
| 1010 | bidi_it->prev_was_pdf = 0; | 932 | bidi_it->prev_was_pdf = 0; |
| 1011 | 933 | ||
| 1012 | bidi_it->orig_type = UNKNOWN_BT; | 934 | bidi_it->type_after_w1 = UNKNOWN_BT; |
| 1013 | 935 | ||
| 1014 | switch (type) | 936 | switch (type) |
| 1015 | { | 937 | { |
| 1016 | case RLE: /* X2 */ | 938 | case RLE: /* X2 */ |
| 1017 | case RLO: /* X4 */ | 939 | case RLO: /* X4 */ |
| 1018 | bidi_it->orig_type = type; | 940 | bidi_it->type_after_w1 = type; |
| 1019 | bidi_check_type (bidi_it->orig_type); | 941 | bidi_check_type (bidi_it->type_after_w1); |
| 1020 | type = WEAK_BN; /* X9/Retaining */ | 942 | type = WEAK_BN; /* X9/Retaining */ |
| 1021 | if (bidi_it->ignore_bn_limit <= 0) | 943 | if (bidi_it->ignore_bn_limit <= 0) |
| 1022 | { | 944 | { |
| @@ -1025,7 +947,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1025 | /* Compute the least odd embedding level greater than | 947 | /* Compute the least odd embedding level greater than |
| 1026 | the current level. */ | 948 | the current level. */ |
| 1027 | new_level = ((current_level + 1) & ~1) + 1; | 949 | new_level = ((current_level + 1) & ~1) + 1; |
| 1028 | if (bidi_it->orig_type == RLE) | 950 | if (bidi_it->type_after_w1 == RLE) |
| 1029 | override = NEUTRAL_DIR; | 951 | override = NEUTRAL_DIR; |
| 1030 | else | 952 | else |
| 1031 | override = R2L; | 953 | override = R2L; |
| @@ -1042,14 +964,14 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1042 | bidi_it->invalid_rl_levels++; | 964 | bidi_it->invalid_rl_levels++; |
| 1043 | } | 965 | } |
| 1044 | } | 966 | } |
| 1045 | else if (bidi_it->prev.orig_type == WEAK_EN /* W5/Retaining */ | 967 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ |
| 1046 | || bidi_it->next_en_pos > bidi_it->charpos) | 968 | || bidi_it->next_en_pos > bidi_it->charpos) |
| 1047 | type = WEAK_EN; | 969 | type = WEAK_EN; |
| 1048 | break; | 970 | break; |
| 1049 | case LRE: /* X3 */ | 971 | case LRE: /* X3 */ |
| 1050 | case LRO: /* X5 */ | 972 | case LRO: /* X5 */ |
| 1051 | bidi_it->orig_type = type; | 973 | bidi_it->type_after_w1 = type; |
| 1052 | bidi_check_type (bidi_it->orig_type); | 974 | bidi_check_type (bidi_it->type_after_w1); |
| 1053 | type = WEAK_BN; /* X9/Retaining */ | 975 | type = WEAK_BN; /* X9/Retaining */ |
| 1054 | if (bidi_it->ignore_bn_limit <= 0) | 976 | if (bidi_it->ignore_bn_limit <= 0) |
| 1055 | { | 977 | { |
| @@ -1058,7 +980,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1058 | /* Compute the least even embedding level greater than | 980 | /* Compute the least even embedding level greater than |
| 1059 | the current level. */ | 981 | the current level. */ |
| 1060 | new_level = ((current_level + 2) & ~1); | 982 | new_level = ((current_level + 2) & ~1); |
| 1061 | if (bidi_it->orig_type == LRE) | 983 | if (bidi_it->type_after_w1 == LRE) |
| 1062 | override = NEUTRAL_DIR; | 984 | override = NEUTRAL_DIR; |
| 1063 | else | 985 | else |
| 1064 | override = L2R; | 986 | override = L2R; |
| @@ -1078,13 +1000,13 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1078 | bidi_it->invalid_rl_levels++; | 1000 | bidi_it->invalid_rl_levels++; |
| 1079 | } | 1001 | } |
| 1080 | } | 1002 | } |
| 1081 | else if (bidi_it->prev.orig_type == WEAK_EN /* W5/Retaining */ | 1003 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ |
| 1082 | || bidi_it->next_en_pos > bidi_it->charpos) | 1004 | || bidi_it->next_en_pos > bidi_it->charpos) |
| 1083 | type = WEAK_EN; | 1005 | type = WEAK_EN; |
| 1084 | break; | 1006 | break; |
| 1085 | case PDF: /* X7 */ | 1007 | case PDF: /* X7 */ |
| 1086 | bidi_it->orig_type = type; | 1008 | bidi_it->type_after_w1 = type; |
| 1087 | bidi_check_type (bidi_it->orig_type); | 1009 | bidi_check_type (bidi_it->type_after_w1); |
| 1088 | type = WEAK_BN; /* X9/Retaining */ | 1010 | type = WEAK_BN; /* X9/Retaining */ |
| 1089 | if (bidi_it->ignore_bn_limit <= 0) | 1011 | if (bidi_it->ignore_bn_limit <= 0) |
| 1090 | { | 1012 | { |
| @@ -1104,7 +1026,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1104 | bidi_it->invalid_rl_levels--; | 1026 | bidi_it->invalid_rl_levels--; |
| 1105 | } | 1027 | } |
| 1106 | } | 1028 | } |
| 1107 | else if (bidi_it->prev.orig_type == WEAK_EN /* W5/Retaining */ | 1029 | else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ |
| 1108 | || bidi_it->next_en_pos > bidi_it->charpos) | 1030 | || bidi_it->next_en_pos > bidi_it->charpos) |
| 1109 | type = WEAK_EN; | 1031 | type = WEAK_EN; |
| 1110 | break; | 1032 | break; |
| @@ -1188,8 +1110,8 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1188 | if (bidi_it->type == NEUTRAL_B) /* X8 */ | 1110 | if (bidi_it->type == NEUTRAL_B) /* X8 */ |
| 1189 | { | 1111 | { |
| 1190 | bidi_set_paragraph_end (bidi_it); | 1112 | bidi_set_paragraph_end (bidi_it); |
| 1191 | bidi_it->orig_type = bidi_it->type; /* needed below and in L1 */ | 1113 | bidi_it->type_after_w1 = bidi_it->type; /* needed below and in L1 */ |
| 1192 | bidi_check_type (bidi_it->orig_type); | 1114 | bidi_check_type (bidi_it->type_after_w1); |
| 1193 | } | 1115 | } |
| 1194 | 1116 | ||
| 1195 | return new_level; | 1117 | return new_level; |
| @@ -1229,8 +1151,8 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1229 | } | 1151 | } |
| 1230 | else if (type == NEUTRAL_S || type == NEUTRAL_WS | 1152 | else if (type == NEUTRAL_S || type == NEUTRAL_WS |
| 1231 | || type == WEAK_BN || type == STRONG_AL) | 1153 | || type == WEAK_BN || type == STRONG_AL) |
| 1232 | bidi_it->orig_type = type; /* needed in L1 */ | 1154 | bidi_it->type_after_w1 = type; /* needed in L1 */ |
| 1233 | bidi_check_type (bidi_it->orig_type); | 1155 | bidi_check_type (bidi_it->type_after_w1); |
| 1234 | 1156 | ||
| 1235 | /* Level and directional override status are already recorded in | 1157 | /* Level and directional override status are already recorded in |
| 1236 | bidi_it, and do not need any change; see X6. */ | 1158 | bidi_it, and do not need any change; see X6. */ |
| @@ -1245,10 +1167,10 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1245 | /* Note that we don't need to consider the case where the prev | 1167 | /* Note that we don't need to consider the case where the prev |
| 1246 | character has its type overridden by an RLO or LRO: such | 1168 | character has its type overridden by an RLO or LRO: such |
| 1247 | characters are outside the current level run, and thus not | 1169 | characters are outside the current level run, and thus not |
| 1248 | relevant to this NSM. Thus, NSM gets the pristine_type of | 1170 | relevant to this NSM. Thus, NSM gets the orig_type of the |
| 1249 | the previous character. */ | 1171 | previous character. */ |
| 1250 | if (bidi_it->prev.type != UNKNOWN_BT) | 1172 | if (bidi_it->prev.type != UNKNOWN_BT) |
| 1251 | type = bidi_it->prev.pristine_type; | 1173 | type = bidi_it->prev.orig_type; |
| 1252 | else if (bidi_it->sor == R2L) | 1174 | else if (bidi_it->sor == R2L) |
| 1253 | type = STRONG_R; | 1175 | type = STRONG_R; |
| 1254 | else if (bidi_it->sor == L2R) | 1176 | else if (bidi_it->sor == L2R) |
| @@ -1256,21 +1178,21 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1256 | else /* shouldn't happen! */ | 1178 | else /* shouldn't happen! */ |
| 1257 | abort (); | 1179 | abort (); |
| 1258 | if (type == WEAK_EN /* W2 after W1 */ | 1180 | if (type == WEAK_EN /* W2 after W1 */ |
| 1259 | && bidi_it->last_strong.orig_type == STRONG_AL) | 1181 | && bidi_it->last_strong.type_after_w1 == STRONG_AL) |
| 1260 | type = WEAK_AN; | 1182 | type = WEAK_AN; |
| 1261 | } | 1183 | } |
| 1262 | else if (type == WEAK_EN /* W2 */ | 1184 | else if (type == WEAK_EN /* W2 */ |
| 1263 | && bidi_it->last_strong.orig_type == STRONG_AL) | 1185 | && bidi_it->last_strong.type_after_w1 == STRONG_AL) |
| 1264 | type = WEAK_AN; | 1186 | type = WEAK_AN; |
| 1265 | else if ((type == WEAK_ES | 1187 | else if ((type == WEAK_ES |
| 1266 | && (bidi_it->prev.orig_type == WEAK_EN /* W4 */ | 1188 | && (bidi_it->prev.type_after_w1 == WEAK_EN /* W4 */ |
| 1267 | && (bidi_it->prev.pristine_type == WEAK_EN | 1189 | && (bidi_it->prev.orig_type == WEAK_EN |
| 1268 | || bidi_it->prev.pristine_type == WEAK_NSM))) /* aft W1 */ | 1190 | || bidi_it->prev.orig_type == WEAK_NSM))) /* aft W1 */ |
| 1269 | || (type == WEAK_CS | 1191 | || (type == WEAK_CS |
| 1270 | && ((bidi_it->prev.orig_type == WEAK_EN | 1192 | && ((bidi_it->prev.type_after_w1 == WEAK_EN |
| 1271 | && (bidi_it->prev.pristine_type == WEAK_EN /* W4 */ | 1193 | && (bidi_it->prev.orig_type == WEAK_EN /* W4 */ |
| 1272 | || bidi_it->prev.pristine_type == WEAK_NSM)) /* a/W1 */ | 1194 | || bidi_it->prev.orig_type == WEAK_NSM)) /* a/W1 */ |
| 1273 | || bidi_it->prev.orig_type == WEAK_AN))) /* W4 */ | 1195 | || bidi_it->prev.type_after_w1 == WEAK_AN))) /* W4 */ |
| 1274 | { | 1196 | { |
| 1275 | next_char = FETCH_CHAR (bidi_it->bytepos + bidi_it->ch_len); | 1197 | next_char = FETCH_CHAR (bidi_it->bytepos + bidi_it->ch_len); |
| 1276 | type_of_next = bidi_get_type (next_char); | 1198 | type_of_next = bidi_get_type (next_char); |
| @@ -1292,11 +1214,11 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1292 | be changed into EN. */ | 1214 | be changed into EN. */ |
| 1293 | if (type == WEAK_ES | 1215 | if (type == WEAK_ES |
| 1294 | && type_of_next == WEAK_EN | 1216 | && type_of_next == WEAK_EN |
| 1295 | && bidi_it->last_strong.orig_type != STRONG_AL) | 1217 | && bidi_it->last_strong.type_after_w1 != STRONG_AL) |
| 1296 | type = WEAK_EN; | 1218 | type = WEAK_EN; |
| 1297 | else if (type == WEAK_CS) | 1219 | else if (type == WEAK_CS) |
| 1298 | { | 1220 | { |
| 1299 | if (bidi_it->prev.orig_type == WEAK_AN | 1221 | if (bidi_it->prev.type_after_w1 == WEAK_AN |
| 1300 | && (type_of_next == WEAK_AN | 1222 | && (type_of_next == WEAK_AN |
| 1301 | /* If the next character is EN, but the last | 1223 | /* If the next character is EN, but the last |
| 1302 | strong-type character is AL, EN will be later | 1224 | strong-type character is AL, EN will be later |
| @@ -1304,18 +1226,18 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1304 | in that case, this ES should not be changed into | 1226 | in that case, this ES should not be changed into |
| 1305 | EN. */ | 1227 | EN. */ |
| 1306 | || (type_of_next == WEAK_EN | 1228 | || (type_of_next == WEAK_EN |
| 1307 | && bidi_it->last_strong.orig_type == STRONG_AL))) | 1229 | && bidi_it->last_strong.type_after_w1 == STRONG_AL))) |
| 1308 | type = WEAK_AN; | 1230 | type = WEAK_AN; |
| 1309 | else if (bidi_it->prev.orig_type == WEAK_EN | 1231 | else if (bidi_it->prev.type_after_w1 == WEAK_EN |
| 1310 | && type_of_next == WEAK_EN | 1232 | && type_of_next == WEAK_EN |
| 1311 | && bidi_it->last_strong.orig_type != STRONG_AL) | 1233 | && bidi_it->last_strong.type_after_w1 != STRONG_AL) |
| 1312 | type = WEAK_EN; | 1234 | type = WEAK_EN; |
| 1313 | } | 1235 | } |
| 1314 | } | 1236 | } |
| 1315 | else if (type == WEAK_ET /* W5: ET with EN before or after it */ | 1237 | else if (type == WEAK_ET /* W5: ET with EN before or after it */ |
| 1316 | || type == WEAK_BN) /* W5/Retaining */ | 1238 | || type == WEAK_BN) /* W5/Retaining */ |
| 1317 | { | 1239 | { |
| 1318 | if (bidi_it->prev.orig_type == WEAK_EN /* ET/BN with EN before it */ | 1240 | if (bidi_it->prev.type_after_w1 == WEAK_EN /* ET/BN with EN before it */ |
| 1319 | || bidi_it->next_en_pos > bidi_it->charpos) | 1241 | || bidi_it->next_en_pos > bidi_it->charpos) |
| 1320 | type = WEAK_EN; | 1242 | type = WEAK_EN; |
| 1321 | /* W5: ET with EN after it. */ | 1243 | /* W5: ET with EN after it. */ |
| @@ -1342,7 +1264,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1342 | { | 1264 | { |
| 1343 | /* If the last strong character is AL, the EN we've | 1265 | /* If the last strong character is AL, the EN we've |
| 1344 | found will become AN when we get to it (W2). */ | 1266 | found will become AN when we get to it (W2). */ |
| 1345 | if (bidi_it->last_strong.orig_type != STRONG_AL) | 1267 | if (bidi_it->last_strong.type_after_w1 != STRONG_AL) |
| 1346 | { | 1268 | { |
| 1347 | type = WEAK_EN; | 1269 | type = WEAK_EN; |
| 1348 | /* Remember this EN position, to speed up processing | 1270 | /* Remember this EN position, to speed up processing |
| @@ -1356,22 +1278,23 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1356 | } | 1278 | } |
| 1357 | 1279 | ||
| 1358 | if (type == WEAK_ES || type == WEAK_ET || type == WEAK_CS /* W6 */ | 1280 | if (type == WEAK_ES || type == WEAK_ET || type == WEAK_CS /* W6 */ |
| 1359 | || (type == WEAK_BN && (bidi_it->prev.orig_type == WEAK_CS /* W6/Ret. */ | 1281 | || (type == WEAK_BN |
| 1360 | || bidi_it->prev.orig_type == WEAK_ES | 1282 | && (bidi_it->prev.type_after_w1 == WEAK_CS /* W6/Retaining */ |
| 1361 | || bidi_it->prev.orig_type == WEAK_ET))) | 1283 | || bidi_it->prev.type_after_w1 == WEAK_ES |
| 1284 | || bidi_it->prev.type_after_w1 == WEAK_ET))) | ||
| 1362 | type = NEUTRAL_ON; | 1285 | type = NEUTRAL_ON; |
| 1363 | 1286 | ||
| 1364 | /* Store the type we've got so far, before we clobber it with strong | 1287 | /* Store the type we've got so far, before we clobber it with strong |
| 1365 | types in W7 and while resolving neutral types. But leave alone | 1288 | types in W7 and while resolving neutral types. But leave alone |
| 1366 | the original types that were recorded above, because we will need | 1289 | the original types that were recorded above, because we will need |
| 1367 | them for the L1 clause. */ | 1290 | them for the L1 clause. */ |
| 1368 | if (bidi_it->orig_type == UNKNOWN_BT) | 1291 | if (bidi_it->type_after_w1 == UNKNOWN_BT) |
| 1369 | bidi_it->orig_type = type; | 1292 | bidi_it->type_after_w1 = type; |
| 1370 | bidi_check_type (bidi_it->orig_type); | 1293 | bidi_check_type (bidi_it->type_after_w1); |
| 1371 | 1294 | ||
| 1372 | if (type == WEAK_EN) /* W7 */ | 1295 | if (type == WEAK_EN) /* W7 */ |
| 1373 | { | 1296 | { |
| 1374 | if ((bidi_it->last_strong.orig_type == STRONG_L) | 1297 | if ((bidi_it->last_strong.type_after_w1 == STRONG_L) |
| 1375 | || (bidi_it->last_strong.type == UNKNOWN_BT && bidi_it->sor == L2R)) | 1298 | || (bidi_it->last_strong.type == UNKNOWN_BT && bidi_it->sor == L2R)) |
| 1376 | type = STRONG_L; | 1299 | type = STRONG_L; |
| 1377 | } | 1300 | } |
| @@ -1431,7 +1354,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 1431 | do { | 1354 | do { |
| 1432 | /* Record the info about the previous character, so that | 1355 | /* Record the info about the previous character, so that |
| 1433 | it will be cached below with this state. */ | 1356 | it will be cached below with this state. */ |
| 1434 | if (bidi_it->orig_type != WEAK_BN /* W1/Retaining */ | 1357 | if (bidi_it->type_after_w1 != WEAK_BN /* W1/Retaining */ |
| 1435 | && bidi_it->type != WEAK_BN) | 1358 | && bidi_it->type != WEAK_BN) |
| 1436 | bidi_remember_char (&bidi_it->prev, bidi_it); | 1359 | bidi_remember_char (&bidi_it->prev, bidi_it); |
| 1437 | type = bidi_resolve_weak (bidi_it); | 1360 | type = bidi_resolve_weak (bidi_it); |
| @@ -1475,7 +1398,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 1475 | stored by bidi_set_sor_type in the prev_for_neutral | 1398 | stored by bidi_set_sor_type in the prev_for_neutral |
| 1476 | member. */ | 1399 | member. */ |
| 1477 | if (saved_it.type != WEAK_BN | 1400 | if (saved_it.type != WEAK_BN |
| 1478 | || bidi_get_category (bidi_it->prev.orig_type) == NEUTRAL) | 1401 | || bidi_get_category (bidi_it->prev.type_after_w1) == NEUTRAL) |
| 1479 | { | 1402 | { |
| 1480 | next_type = bidi_it->prev_for_neutral.type; | 1403 | next_type = bidi_it->prev_for_neutral.type; |
| 1481 | saved_it.next_for_neutral.type = next_type; | 1404 | saved_it.next_for_neutral.type = next_type; |
| @@ -1545,11 +1468,12 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 1545 | return bidi_it->resolved_level; | 1468 | return bidi_it->resolved_level; |
| 1546 | 1469 | ||
| 1547 | /* Record the info about the previous character. */ | 1470 | /* Record the info about the previous character. */ |
| 1548 | if (bidi_it->orig_type != WEAK_BN /* W1/Retaining */ | 1471 | if (bidi_it->type_after_w1 != WEAK_BN /* W1/Retaining */ |
| 1549 | && bidi_it->type != WEAK_BN) | 1472 | && bidi_it->type != WEAK_BN) |
| 1550 | bidi_remember_char (&bidi_it->prev, bidi_it); | 1473 | bidi_remember_char (&bidi_it->prev, bidi_it); |
| 1551 | if (bidi_it->orig_type == STRONG_R || bidi_it->orig_type == STRONG_L | 1474 | if (bidi_it->type_after_w1 == STRONG_R |
| 1552 | || bidi_it->orig_type == STRONG_AL) | 1475 | || bidi_it->type_after_w1 == STRONG_L |
| 1476 | || bidi_it->type_after_w1 == STRONG_AL) | ||
| 1553 | bidi_remember_char (&bidi_it->last_strong, bidi_it); | 1477 | bidi_remember_char (&bidi_it->last_strong, bidi_it); |
| 1554 | /* FIXME: it sounds like we don't need both prev and | 1478 | /* FIXME: it sounds like we don't need both prev and |
| 1555 | prev_for_neutral members, but I'm leaving them both for now. */ | 1479 | prev_for_neutral members, but I'm leaving them both for now. */ |
| @@ -1633,7 +1557,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 1633 | /* For L1 below, we need to know, for each WS character, whether | 1557 | /* For L1 below, we need to know, for each WS character, whether |
| 1634 | it belongs to a sequence of WS characters preceeding a newline | 1558 | it belongs to a sequence of WS characters preceeding a newline |
| 1635 | or a TAB or a paragraph separator. */ | 1559 | or a TAB or a paragraph separator. */ |
| 1636 | if (bidi_it->pristine_type == NEUTRAL_WS | 1560 | if (bidi_it->orig_type == NEUTRAL_WS |
| 1637 | && bidi_it->next_for_ws.type == UNKNOWN_BT) | 1561 | && bidi_it->next_for_ws.type == UNKNOWN_BT) |
| 1638 | { | 1562 | { |
| 1639 | int ch; | 1563 | int ch; |
| @@ -1663,7 +1587,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 1663 | /* Resolve implicit levels, with a twist: PDFs get the embedding | 1587 | /* Resolve implicit levels, with a twist: PDFs get the embedding |
| 1664 | level of the enbedding they terminate. See below for the | 1588 | level of the enbedding they terminate. See below for the |
| 1665 | reason. */ | 1589 | reason. */ |
| 1666 | if (bidi_it->pristine_type == PDF | 1590 | if (bidi_it->orig_type == PDF |
| 1667 | /* Don't do this if this formatting code didn't change the | 1591 | /* Don't do this if this formatting code didn't change the |
| 1668 | embedding level due to invalid or empty embeddings. */ | 1592 | embedding level due to invalid or empty embeddings. */ |
| 1669 | && prev_level != level) | 1593 | && prev_level != level) |
| @@ -1695,10 +1619,10 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 1695 | user wants to.) */ | 1619 | user wants to.) */ |
| 1696 | level = prev_level; | 1620 | level = prev_level; |
| 1697 | } | 1621 | } |
| 1698 | else if (bidi_it->pristine_type == NEUTRAL_B /* L1 */ | 1622 | else if (bidi_it->orig_type == NEUTRAL_B /* L1 */ |
| 1699 | || bidi_it->pristine_type == NEUTRAL_S | 1623 | || bidi_it->orig_type == NEUTRAL_S |
| 1700 | || bidi_it->ch == '\n' /* || bidi_it->ch == LINESEP_CHAR */ | 1624 | || bidi_it->ch == '\n' /* || bidi_it->ch == LINESEP_CHAR */ |
| 1701 | || (bidi_it->pristine_type == NEUTRAL_WS | 1625 | || (bidi_it->orig_type == NEUTRAL_WS |
| 1702 | && (bidi_it->next_for_ws.type == NEUTRAL_B | 1626 | && (bidi_it->next_for_ws.type == NEUTRAL_B |
| 1703 | || bidi_it->next_for_ws.type == NEUTRAL_S))) | 1627 | || bidi_it->next_for_ws.type == NEUTRAL_S))) |
| 1704 | level = bidi_it->level_stack[0].level; | 1628 | level = bidi_it->level_stack[0].level; |
| @@ -1886,280 +1810,3 @@ bidi_dump_cached_states (void) | |||
| 1886 | fprintf (stderr, "%*d", ndigits, bidi_cache[i].charpos); | 1810 | fprintf (stderr, "%*d", ndigits, bidi_cache[i].charpos); |
| 1887 | fputs ("\n", stderr); | 1811 | fputs ("\n", stderr); |
| 1888 | } | 1812 | } |
| 1889 | |||
| 1890 | #ifdef TEST_STANDALONE | ||
| 1891 | |||
| 1892 | #include <sys/stat.h> | ||
| 1893 | #include <signal.h> | ||
| 1894 | |||
| 1895 | static char display_line[80]; | ||
| 1896 | static int simulate_display; | ||
| 1897 | static int incr = 1; | ||
| 1898 | |||
| 1899 | void | ||
| 1900 | signal_catcher (int sig) | ||
| 1901 | { | ||
| 1902 | if (simulate_display) | ||
| 1903 | puts (display_line); | ||
| 1904 | else | ||
| 1905 | { | ||
| 1906 | puts ("<"); | ||
| 1907 | fflush (stdout); | ||
| 1908 | } | ||
| 1909 | signal (sig, SIG_DFL); | ||
| 1910 | raise (sig); | ||
| 1911 | } | ||
| 1912 | |||
| 1913 | void | ||
| 1914 | put_line (char *p) | ||
| 1915 | { | ||
| 1916 | if (simulate_display) | ||
| 1917 | { | ||
| 1918 | if (incr == -1) | ||
| 1919 | { | ||
| 1920 | if (p >= display_line) | ||
| 1921 | memset (display_line, ' ', p - display_line + 1); | ||
| 1922 | } | ||
| 1923 | else | ||
| 1924 | *p = '\0'; | ||
| 1925 | fputs (display_line, stdout); | ||
| 1926 | } | ||
| 1927 | fflush (stdout); | ||
| 1928 | } | ||
| 1929 | |||
| 1930 | char * | ||
| 1931 | init_display_direction (bidi_dir_t default_dir, int base_level) | ||
| 1932 | { | ||
| 1933 | char *p; | ||
| 1934 | |||
| 1935 | /* To which display margin should we flush the lines? */ | ||
| 1936 | switch (default_dir) | ||
| 1937 | { | ||
| 1938 | case NEUTRAL_DIR: | ||
| 1939 | if ((base_level & 1) == 0) | ||
| 1940 | { | ||
| 1941 | p = display_line; | ||
| 1942 | incr = 1; | ||
| 1943 | } | ||
| 1944 | else | ||
| 1945 | { | ||
| 1946 | p = display_line + sizeof (display_line) - 1; | ||
| 1947 | *p-- = '\0'; | ||
| 1948 | incr = -1; | ||
| 1949 | } | ||
| 1950 | break; | ||
| 1951 | case L2R: | ||
| 1952 | p = display_line; | ||
| 1953 | incr = 1; | ||
| 1954 | break; | ||
| 1955 | case R2L: | ||
| 1956 | p = display_line + sizeof (display_line) - 1; | ||
| 1957 | *p-- = '\0'; | ||
| 1958 | incr = -1; | ||
| 1959 | break; | ||
| 1960 | default: | ||
| 1961 | abort (); | ||
| 1962 | } | ||
| 1963 | |||
| 1964 | return p; | ||
| 1965 | } | ||
| 1966 | |||
| 1967 | static char * | ||
| 1968 | continuation_line (char *p, int need) | ||
| 1969 | { | ||
| 1970 | if (incr == -1) | ||
| 1971 | { | ||
| 1972 | if (p < display_line + need) | ||
| 1973 | { | ||
| 1974 | *p-- = '/'; | ||
| 1975 | put_line (p); | ||
| 1976 | putc ('\n', stdout); | ||
| 1977 | memset (display_line, '>', sizeof(display_line) - 1); | ||
| 1978 | p = display_line + sizeof (display_line) - 1; | ||
| 1979 | *p-- = '\0'; | ||
| 1980 | } | ||
| 1981 | } | ||
| 1982 | else | ||
| 1983 | { | ||
| 1984 | if (p > display_line + sizeof(display_line) - need - 2) | ||
| 1985 | { | ||
| 1986 | *p++ = '\\'; | ||
| 1987 | put_line (p); | ||
| 1988 | putc ('\n', stdout); | ||
| 1989 | memset (display_line, '<', sizeof(display_line) - 1); | ||
| 1990 | p = display_line; | ||
| 1991 | } | ||
| 1992 | } | ||
| 1993 | |||
| 1994 | return p; | ||
| 1995 | } | ||
| 1996 | |||
| 1997 | int main (int argc, char *argv[]) | ||
| 1998 | { | ||
| 1999 | bidi_dir_t default_dir = NEUTRAL_DIR; | ||
| 2000 | char lots_of_equals[] = "\n===============================================================================\n"; | ||
| 2001 | |||
| 2002 | |||
| 2003 | if (argc > 1 && argv[1][0] == '-') | ||
| 2004 | { | ||
| 2005 | switch (argv[1][1]) | ||
| 2006 | { | ||
| 2007 | case 'R': | ||
| 2008 | default_dir = R2L; | ||
| 2009 | simulate_display = 1; | ||
| 2010 | ++argv; | ||
| 2011 | break; | ||
| 2012 | case 'L': | ||
| 2013 | default_dir = L2R; | ||
| 2014 | simulate_display = 1; | ||
| 2015 | ++argv; | ||
| 2016 | break; | ||
| 2017 | case 'N': | ||
| 2018 | simulate_display = 1; | ||
| 2019 | ++argv; | ||
| 2020 | break; | ||
| 2021 | default: | ||
| 2022 | break; | ||
| 2023 | } | ||
| 2024 | bidi_overriding_paragraph_direction = default_dir; | ||
| 2025 | } | ||
| 2026 | |||
| 2027 | for (argv++; *argv; argv++) | ||
| 2028 | { | ||
| 2029 | FILE *in = fopen (*argv, "rb"); | ||
| 2030 | struct stat stat_buf; | ||
| 2031 | struct bidi_it iterator; | ||
| 2032 | size_t i; | ||
| 2033 | char *p = display_line; | ||
| 2034 | int base_level; | ||
| 2035 | unsigned char *s, *d, *s_end; | ||
| 2036 | |||
| 2037 | if (!in || stat (*argv, &stat_buf)) | ||
| 2038 | { | ||
| 2039 | perror (*argv); | ||
| 2040 | continue; | ||
| 2041 | } | ||
| 2042 | |||
| 2043 | if (stat_buf.st_size > input_buf_size) | ||
| 2044 | { | ||
| 2045 | input_buf = realloc (input_buf, stat_buf.st_size + 1); | ||
| 2046 | if (!input_buf) | ||
| 2047 | { | ||
| 2048 | perror ("realloc input buffer"); | ||
| 2049 | continue; | ||
| 2050 | } | ||
| 2051 | input_buf_size = stat_buf.st_size; | ||
| 2052 | } | ||
| 2053 | if (fread (input_buf, 1, stat_buf.st_size, in) != stat_buf.st_size) | ||
| 2054 | { | ||
| 2055 | perror ("reading input"); | ||
| 2056 | continue; | ||
| 2057 | } | ||
| 2058 | input_buf[stat_buf.st_size] = '\0'; | ||
| 2059 | for (d = s = input_buf, s_end = s + stat_buf.st_size - 1; *s; s++) | ||
| 2060 | { | ||
| 2061 | if (*s != '\r' || s >= s_end || s[1] != '\n') | ||
| 2062 | *d++ = *s; | ||
| 2063 | } | ||
| 2064 | stat_buf.st_size = d - input_buf; | ||
| 2065 | input_buf[stat_buf.st_size] = '\0'; | ||
| 2066 | |||
| 2067 | /* Done with administrivia, now for some real work... */ | ||
| 2068 | signal (SIGABRT, signal_catcher); | ||
| 2069 | signal (SIGINT, signal_catcher); | ||
| 2070 | bidi_init_it (-1, default_dir, &iterator); | ||
| 2071 | if (simulate_display) | ||
| 2072 | { | ||
| 2073 | p = init_display_direction (default_dir, | ||
| 2074 | iterator.level_stack[0].level); | ||
| 2075 | } | ||
| 2076 | |||
| 2077 | memset (display_line, incr == -1 ? '>' : '<', sizeof (display_line) - 1); | ||
| 2078 | display_line[sizeof (display_line) - 1] = '\0'; | ||
| 2079 | base_level = iterator.level_stack[0].level; | ||
| 2080 | |||
| 2081 | for (i = 0; i <= stat_buf.st_size; i++) | ||
| 2082 | { | ||
| 2083 | int c; | ||
| 2084 | |||
| 2085 | bidi_get_next_char_visually (&iterator); | ||
| 2086 | c = iterator.ch; | ||
| 2087 | |||
| 2088 | if (c == '\n' || c == BIDI_EOB) | ||
| 2089 | { | ||
| 2090 | if (simulate_display) | ||
| 2091 | { | ||
| 2092 | put_line (p); | ||
| 2093 | /* FIXME: if -R or -L, need to init paragraph here. */ | ||
| 2094 | } | ||
| 2095 | if (c == BIDI_EOB) | ||
| 2096 | break; | ||
| 2097 | putc (c, stdout); | ||
| 2098 | } | ||
| 2099 | else if (c >= LRE_CHAR && c <= LRM_CHAR) | ||
| 2100 | { | ||
| 2101 | if (simulate_display) | ||
| 2102 | { | ||
| 2103 | p = continuation_line (p, 5); | ||
| 2104 | if (incr == -1) | ||
| 2105 | { | ||
| 2106 | memcpy (p - 4, bidi_name[c], 5); | ||
| 2107 | p -= 5; | ||
| 2108 | } | ||
| 2109 | else | ||
| 2110 | { | ||
| 2111 | memcpy (p, bidi_name[c], 5); | ||
| 2112 | p += 5; | ||
| 2113 | } | ||
| 2114 | } | ||
| 2115 | else | ||
| 2116 | fputs (bidi_name[c], stdout); | ||
| 2117 | } | ||
| 2118 | else if (c < ' ') | ||
| 2119 | { | ||
| 2120 | if (simulate_display) | ||
| 2121 | { | ||
| 2122 | p = continuation_line (p, 2); | ||
| 2123 | if (incr == -1) | ||
| 2124 | { | ||
| 2125 | *p-- = '@' + c; | ||
| 2126 | *p-- = '^'; | ||
| 2127 | } | ||
| 2128 | else | ||
| 2129 | { | ||
| 2130 | *p++ = '^'; | ||
| 2131 | *p++ = '@' + c; | ||
| 2132 | } | ||
| 2133 | } | ||
| 2134 | else | ||
| 2135 | printf ("^%c", (c | 0x40)); | ||
| 2136 | } | ||
| 2137 | else | ||
| 2138 | { | ||
| 2139 | int c1 = (iterator.type == STRONG_R) ? bidi_mirror_char (c) : c; | ||
| 2140 | |||
| 2141 | if (simulate_display) | ||
| 2142 | { | ||
| 2143 | p = continuation_line (p, 1); | ||
| 2144 | *p = c1; | ||
| 2145 | p += incr; | ||
| 2146 | } | ||
| 2147 | else | ||
| 2148 | putc (c1, stdout); | ||
| 2149 | } | ||
| 2150 | |||
| 2151 | if (iterator.ch == '\n') | ||
| 2152 | { | ||
| 2153 | if (base_level != iterator.level_stack[0].level) | ||
| 2154 | base_level = iterator.level_stack[0].level; | ||
| 2155 | p = init_display_direction (default_dir, base_level); | ||
| 2156 | memset (display_line, incr == -1 ? '>' : '<', | ||
| 2157 | sizeof (display_line) - 1); | ||
| 2158 | } | ||
| 2159 | } | ||
| 2160 | fputs (lots_of_equals, stdout); | ||
| 2161 | fclose (in); | ||
| 2162 | } | ||
| 2163 | return 0; | ||
| 2164 | } | ||
| 2165 | #endif | ||
diff --git a/src/dispextern.h b/src/dispextern.h index f601fee7df2..d4f572227a3 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1736,9 +1736,9 @@ typedef enum { NEUTRAL_DIR, L2R, R2L } bidi_dir_t; | |||
| 1736 | remember. */ | 1736 | remember. */ |
| 1737 | struct bidi_saved_info { | 1737 | struct bidi_saved_info { |
| 1738 | int bytepos, charpos; /* character's buffer position */ | 1738 | int bytepos, charpos; /* character's buffer position */ |
| 1739 | bidi_type_t type; /* character bidi type */ | 1739 | bidi_type_t type; /* character's resolved bidi type */ |
| 1740 | bidi_type_t orig_type; /* original type of the character, after W1 */ | 1740 | bidi_type_t type_after_w1; /* original type of the character, after W1 */ |
| 1741 | bidi_type_t pristine_type; /* type as we found it in the buffer */ | 1741 | bidi_type_t orig_type; /* type as we found it in the buffer */ |
| 1742 | }; | 1742 | }; |
| 1743 | 1743 | ||
| 1744 | /* Data type for keeping track of saved embedding levels and override | 1744 | /* Data type for keeping track of saved embedding levels and override |
| @@ -1754,9 +1754,10 @@ struct bidi_it { | |||
| 1754 | int charpos; | 1754 | int charpos; |
| 1755 | int ch; /* the character itself */ | 1755 | int ch; /* the character itself */ |
| 1756 | int ch_len; /* the length of its multibyte sequence */ | 1756 | int ch_len; /* the length of its multibyte sequence */ |
| 1757 | bidi_type_t type; /* type of this character */ | 1757 | bidi_type_t type; /* bidi type of this character, after |
| 1758 | bidi_type_t orig_type; /* original type, after overrides and W1 */ | 1758 | resolving weak and neutral types */ |
| 1759 | bidi_type_t pristine_type; /* original type, as found in the buffer */ | 1759 | bidi_type_t type_after_w1; /* original type, after overrides and W1 */ |
| 1760 | bidi_type_t orig_type; /* original type, as found in the buffer */ | ||
| 1760 | int resolved_level; /* final resolved level of this character */ | 1761 | int resolved_level; /* final resolved level of this character */ |
| 1761 | int invalid_levels; /* how many PDFs should we ignore */ | 1762 | int invalid_levels; /* how many PDFs should we ignore */ |
| 1762 | int invalid_rl_levels; /* how many PDFs from RLE/RLO should ignore */ | 1763 | int invalid_rl_levels; /* how many PDFs from RLE/RLO should ignore */ |
| @@ -2786,9 +2787,9 @@ extern EMACS_INT tool_bar_button_relief; | |||
| 2786 | 2787 | ||
| 2787 | /* Defined in bidi.c */ | 2788 | /* Defined in bidi.c */ |
| 2788 | 2789 | ||
| 2789 | extern void bidi_init_it P_ ((int pos, bidi_dir_t dir, | 2790 | extern void bidi_init_it P_ ((int, int, struct bidi_it *)); |
| 2790 | struct bidi_it *bidi_it)); | 2791 | extern void bidi_get_next_char_visually P_ ((struct bidi_it *)); |
| 2791 | extern void bidi_get_next_char_visually P_ ((struct bidi_it *bidi_it)); | 2792 | extern void bidi_paragraph_init P_ ((bidi_dir_t, struct bidi_it *)); |
| 2792 | 2793 | ||
| 2793 | /* Defined in xdisp.c */ | 2794 | /* Defined in xdisp.c */ |
| 2794 | 2795 | ||
diff --git a/src/xdisp.c b/src/xdisp.c index cbe9b2c5b2b..2744a5565da 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -2806,6 +2806,11 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id) | |||
| 2806 | it->start_of_box_run_p = 1; | 2806 | it->start_of_box_run_p = 1; |
| 2807 | } | 2807 | } |
| 2808 | 2808 | ||
| 2809 | /* If we are to reorder bidirectional text, init the bidi | ||
| 2810 | iterator. */ | ||
| 2811 | if (it->bidi_p) | ||
| 2812 | bidi_init_it (charpos, bytepos, &it->bidi_it); | ||
| 2813 | |||
| 2809 | /* If a buffer position was specified, set the iterator there, | 2814 | /* If a buffer position was specified, set the iterator there, |
| 2810 | getting overlays and face properties from that position. */ | 2815 | getting overlays and face properties from that position. */ |
| 2811 | if (charpos >= BUF_BEG (current_buffer)) | 2816 | if (charpos >= BUF_BEG (current_buffer)) |
| @@ -2816,7 +2821,11 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id) | |||
| 2816 | 2821 | ||
| 2817 | /* Compute byte position if not specified. */ | 2822 | /* Compute byte position if not specified. */ |
| 2818 | if (bytepos < charpos) | 2823 | if (bytepos < charpos) |
| 2819 | IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos); | 2824 | { |
| 2825 | IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos); | ||
| 2826 | if (it->bidi_p) | ||
| 2827 | it->bidi_it.bytepos = IT_BYTEPOS (*it); | ||
| 2828 | } | ||
| 2820 | else | 2829 | else |
| 2821 | IT_BYTEPOS (*it) = bytepos; | 2830 | IT_BYTEPOS (*it) = bytepos; |
| 2822 | 2831 | ||
| @@ -5322,8 +5331,8 @@ back_to_previous_visible_line_start (it) | |||
| 5322 | if (IT_CHARPOS (*it) <= BEGV) | 5331 | if (IT_CHARPOS (*it) <= BEGV) |
| 5323 | break; | 5332 | break; |
| 5324 | 5333 | ||
| 5325 | /* If selective > 0, then lines indented more than that values | 5334 | /* If selective > 0, then lines indented more than its value are |
| 5326 | are invisible. */ | 5335 | invisible. */ |
| 5327 | if (it->selective > 0 | 5336 | if (it->selective > 0 |
| 5328 | && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it), | 5337 | && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it), |
| 5329 | (double) it->selective)) /* iftc */ | 5338 | (double) it->selective)) /* iftc */ |
| @@ -5525,11 +5534,22 @@ reseat_1 (it, pos, set_stop_p) | |||
| 5525 | should be user-definable and/or come from some ``higher | 5534 | should be user-definable and/or come from some ``higher |
| 5526 | protocol''. In the absence of any other guidance, the default | 5535 | protocol''. In the absence of any other guidance, the default |
| 5527 | for this initialization should be NEUTRAL_DIR. */ | 5536 | for this initialization should be NEUTRAL_DIR. */ |
| 5528 | bidi_init_it (pos.charpos - 1, L2R, &it->bidi_it); | 5537 | it->bidi_it.charpos = CHARPOS (pos); |
| 5538 | it->bidi_it.bytepos = BYTEPOS (pos); | ||
| 5539 | bidi_paragraph_init (L2R, &it->bidi_it); | ||
| 5540 | /* With bidi reordering, the first character to display might | ||
| 5541 | not be the character at POS. We need to find the next | ||
| 5542 | character in visual order starting from the preceding | ||
| 5543 | character. */ | ||
| 5544 | if ((it->bidi_it.charpos = CHARPOS (pos) - 1) > 1) | ||
| 5545 | { | ||
| 5546 | it->bidi_it.bytepos = CHAR_TO_BYTE (CHARPOS (pos) - 1); | ||
| 5547 | it->bidi_it.ch_len = CHAR_BYTES (CHARPOS (pos) - 1); | ||
| 5548 | } | ||
| 5549 | else | ||
| 5550 | it->bidi_it.bytepos = 0; | ||
| 5529 | bidi_get_next_char_visually (&it->bidi_it); | 5551 | bidi_get_next_char_visually (&it->bidi_it); |
| 5530 | 5552 | SET_TEXT_POS (pos, it->bidi_it.charpos, it->bidi_it.bytepos); | |
| 5531 | pos.charpos = it->bidi_it.charpos; | ||
| 5532 | pos.bytepos = it->bidi_it.bytepos; | ||
| 5533 | it->current.pos = it->position = pos; | 5553 | it->current.pos = it->position = pos; |
| 5534 | } | 5554 | } |
| 5535 | 5555 | ||
| @@ -6693,9 +6713,9 @@ next_element_from_composition (it) | |||
| 6693 | line on the display without producing glyphs. | 6713 | line on the display without producing glyphs. |
| 6694 | 6714 | ||
| 6695 | OP should be a bit mask including some or all of these bits: | 6715 | OP should be a bit mask including some or all of these bits: |
| 6696 | MOVE_TO_X: Stop on reaching x-position TO_X. | 6716 | MOVE_TO_X: Stop upon reaching x-position TO_X. |
| 6697 | MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS. | 6717 | MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS. |
| 6698 | Regardless of OP's value, stop in reaching the end of the display line. | 6718 | Regardless of OP's value, stop upon reaching the end of the display line. |
| 6699 | 6719 | ||
| 6700 | TO_X is normally a value 0 <= TO_X <= IT->last_visible_x. | 6720 | TO_X is normally a value 0 <= TO_X <= IT->last_visible_x. |
| 6701 | This means, in particular, that TO_X includes window's horizontal | 6721 | This means, in particular, that TO_X includes window's horizontal |