From: Brendan McGrath Subject: [PATCH v2 2/3] tools/make_unicode: Implement canonical composition for use in normalization. Message-Id: <20181202023511.31914-2-brendan@redmandi.com> Date: Sun, 2 Dec 2018 13:35:10 +1100 In-Reply-To: <20181202023511.31914-1-brendan@redmandi.com> References: <20181202023511.31914-1-brendan@redmandi.com> From: Sergio Gómez Del Real Signed-off-by: Sergio Gómez Del Real --- libs/port/compose.c | 55 +++ libs/port/decompose.c | 969 ++++++++++++++++++++++++++++++++++++++++++ tools/make_unicode | 302 ++++++++++++- 3 files changed, 1325 insertions(+), 1 deletion(-) diff --git a/libs/port/compose.c b/libs/port/compose.c index 06f6062d247b..3168ab5e0fad 100644 --- a/libs/port/compose.c +++ b/libs/port/compose.c @@ -380,6 +380,8 @@ static const WCHAR table[0x85e] = 0x30d8, 0x30da, 0x30db, 0x30dd }; +#include "decompose.c" + static inline int binary_search( WCHAR ch, int low, int high ) { while (low <= high) @@ -403,3 +405,56 @@ WCHAR DECLSPEC_HIDDEN wine_compose( const WCHAR *str ) count = table[2 * pos + 3]; } } + +static inline int is_blocked(WCHAR *ptr1, WCHAR *ptr2) +{ + if (ptr1 >= ptr2) return -1; + + while (++ptr1 < ptr2) + { + const WCHAR *map1, *map2; + map1 = unicode_table_lookup( *ptr1, 0, idx1_comb, 8, idx2_comb, 4, + offsets_comb, 4, data_comb, 0 ); + map2 = unicode_table_lookup( *ptr2, 0, idx1_comb, 8, idx2_comb, 4, + offsets_comb, 4, data_comb, 0 ); + if (*map1 == 0 || *map2 <= *map1) return 1; + } + return 0; +} + +static inline int is_fullexcl(WCHAR ch) +{ + const WCHAR *map = unicode_table_lookup( ch, 0, idx1_fullcomp, 8, idx2_fullcomp, + 4, offsets_fullcomp, 4, data_fullcomp, 0 ); + return (int)*map; +} + +int unicode_canonical_composition( WCHAR *str, int strlen ) +{ + int i, j; + WCHAR dum[3] = {0}; + + if (strlen == 0) strlen = strlenW( str ); + + for (i = 1; i < strlen; i++) + { + WCHAR *ptr_comp = str+i-1, comp; + if (str[i] == 0) break; + while (ptr_comp - str > 0) + { + if (is_starter( *ptr_comp )) break; + --ptr_comp; + } + if (!is_starter( *ptr_comp ) || is_blocked( ptr_comp, str+i )) continue; + dum[0] = *ptr_comp; + dum[1] = str[i]; + comp = wine_compose( dum ); + if (!comp || is_fullexcl( comp )) continue; + *ptr_comp = comp; + for (j = i; j < strlen-1; j++) str[j] = str[j+1]; + strlen--; + i--; + } + + return strlen; +} diff --git a/libs/port/decompose.c b/libs/port/decompose.c index 311b706901e7..e9dca86fecec 100644 --- a/libs/port/decompose.c +++ b/libs/port/decompose.c @@ -2994,6 +2994,926 @@ static const USHORT offsets_decomp[11040] = 0x0000, 0x21c9, 0x0000, 0x21cb, 0x0000, 0x21cd, 0x0000, 0x0000 }; +static const WCHAR data_comb[670] = +{ + 0x0000, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0232, 0x0220, + 0x0220, 0x0220, 0x0220, 0x0232, 0x0216, 0x0220, 0x0220, 0x0220, + 0x0220, 0x0220, 0x0202, 0x0202, 0x0220, 0x0220, 0x0220, 0x0220, + 0x0202, 0x0202, 0x0220, 0x0220, 0x0220, 0x0220, 0x0220, 0x0220, + 0x0220, 0x0220, 0x0220, 0x0220, 0x0220, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0220, 0x0220, 0x0220, 0x0220, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0240, 0x0230, + 0x0220, 0x0220, 0x0220, 0x0230, 0x0230, 0x0230, 0x0220, 0x0220, + 0x0230, 0x0230, 0x0230, 0x0220, 0x0220, 0x0220, 0x0220, 0x0230, + 0x0232, 0x0220, 0x0220, 0x0230, 0x0233, 0x0234, 0x0234, 0x0233, + 0x0234, 0x0234, 0x0233, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0220, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0220, 0x0230, 0x0230, 0x0230, 0x0222, 0x0220, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0220, 0x0220, + 0x0220, 0x0220, 0x0220, 0x0220, 0x0230, 0x0230, 0x0220, 0x0230, + 0x0230, 0x0222, 0x0228, 0x0230, 0x0010, 0x0011, 0x0012, 0x0013, + 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x0019, 0x0020, + 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0230, 0x0220, 0x0018, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0030, 0x0031, 0x0032, 0x0027, 0x0028, 0x0029, 0x0030, 0x0031, + 0x0032, 0x0033, 0x0034, 0x0230, 0x0230, 0x0220, 0x0220, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0220, 0x0230, 0x0230, 0x0220, + 0x0035, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0220, 0x0230, 0x0230, 0x0230, + 0x0220, 0x0230, 0x0230, 0x0220, 0x0036, 0x0230, 0x0220, 0x0230, + 0x0230, 0x0220, 0x0230, 0x0230, 0x0220, 0x0220, 0x0220, 0x0230, + 0x0220, 0x0220, 0x0230, 0x0220, 0x0230, 0x0230, 0x0230, 0x0220, + 0x0230, 0x0220, 0x0230, 0x0220, 0x0230, 0x0220, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0220, + 0x0230, 0x0220, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0220, + 0x0220, 0x0220, 0x0220, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0220, 0x0230, 0x0230, 0x0220, 0x0230, 0x0230, 0x0220, + 0x0230, 0x0230, 0x0230, 0x0220, 0x0220, 0x0220, 0x0027, 0x0028, + 0x0029, 0x0230, 0x0230, 0x0230, 0x0220, 0x0230, 0x0230, 0x0220, + 0x0220, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0007, 0x0009, + 0x0230, 0x0220, 0x0230, 0x0230, 0x0007, 0x0009, 0x0230, 0x0007, + 0x0009, 0x0007, 0x0009, 0x0007, 0x0009, 0x0009, 0x0009, 0x0084, + 0x0091, 0x0007, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0103, + 0x0103, 0x0009, 0x0107, 0x0107, 0x0107, 0x0107, 0x0118, 0x0118, + 0x0122, 0x0122, 0x0122, 0x0122, 0x0220, 0x0220, 0x0220, 0x0220, + 0x0216, 0x0129, 0x0130, 0x0132, 0x0130, 0x0130, 0x0130, 0x0130, + 0x0130, 0x0230, 0x0230, 0x0009, 0x0230, 0x0230, 0x0220, 0x0007, + 0x0009, 0x0009, 0x0220, 0x0230, 0x0230, 0x0230, 0x0009, 0x0009, + 0x0009, 0x0230, 0x0228, 0x0222, 0x0230, 0x0220, 0x0230, 0x0220, + 0x0009, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0220, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0220, + 0x0220, 0x0220, 0x0220, 0x0220, 0x0220, 0x0230, 0x0230, 0x0220, + 0x0007, 0x0009, 0x0230, 0x0220, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0009, 0x0009, 0x0007, 0x0009, 0x0009, + 0x0007, 0x0230, 0x0230, 0x0230, 0x0001, 0x0220, 0x0220, 0x0220, + 0x0220, 0x0220, 0x0230, 0x0230, 0x0220, 0x0220, 0x0220, 0x0220, + 0x0230, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0220, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0220, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0220, 0x0230, + 0x0230, 0x0234, 0x0214, 0x0220, 0x0202, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0232, 0x0228, 0x0228, 0x0220, 0x0230, 0x0233, + 0x0220, 0x0230, 0x0220, 0x0230, 0x0230, 0x0001, 0x0001, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0001, 0x0001, 0x0001, 0x0230, 0x0230, + 0x0230, 0x0001, 0x0001, 0x0230, 0x0220, 0x0230, 0x0001, 0x0001, + 0x0220, 0x0220, 0x0220, 0x0220, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0009, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0218, 0x0228, 0x0232, 0x0222, 0x0224, 0x0224, 0x0008, + 0x0008, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0009, 0x0009, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0220, 0x0220, 0x0220, 0x0009, + 0x0007, 0x0009, 0x0230, 0x0230, 0x0230, 0x0220, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0009, 0x0009, 0x0026, 0x0230, 0x0230, + 0x0230, 0x0230, 0x0230, 0x0230, 0x0230, 0x0220, 0x0220, 0x0220, + 0x0220, 0x0220, 0x0220, 0x0220, 0x0230, 0x0230 +}; + +static const BYTE idx1_comb[255] = +{ + 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x19, 0x00, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, + 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x21 +}; + +static const USHORT idx2_comb[544] = +{ + /* all-zero 256-char blocks get mapped to here */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x01 */ + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x02 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x03 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0009, 0x000a, 0x000b, 0x000c, 0x0000, 0x0000, 0x0000, + /* sub-index 0x04 */ + 0x0000, 0x000d, 0x0000, 0x0000, 0x000e, 0x000f, 0x0000, 0x0010, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0011, 0x0012, 0x0000, + /* sub-index 0x05 */ + 0x0000, 0x0013, 0x0000, 0x0014, 0x0015, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0016, 0x0017, + /* sub-index 0x06 */ + 0x0000, 0x0018, 0x0019, 0x0000, 0x0000, 0x001a, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x001b, 0x001c, 0x001d, + /* sub-index 0x07 */ + 0x0000, 0x0000, 0x0000, 0x001e, 0x001f, 0x0020, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0021, 0x0022, 0x0000, 0x0000, 0x0023, + /* sub-index 0x08 */ + 0x0000, 0x0000, 0x0000, 0x0024, 0x0025, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0026, 0x0027, 0x0000, 0x0000, 0x0000, + /* sub-index 0x09 */ + 0x0000, 0x0000, 0x0000, 0x0028, 0x0029, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x002a, 0x0000, 0x0000, 0x0000, + /* sub-index 0x0a */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x002b, 0x002c, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x002d, 0x002e, 0x0000, 0x0000, 0x0000, + /* sub-index 0x0b */ + 0x0000, 0x0000, 0x0000, 0x002f, 0x0030, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0031, 0x0000, 0x0000, 0x0000, + /* sub-index 0x0c */ + 0x0000, 0x0000, 0x0000, 0x0032, 0x0033, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0034, 0x0035, 0x0000, 0x0000, 0x0000, + /* sub-index 0x0d */ + 0x0000, 0x0036, 0x0000, 0x0037, 0x0000, 0x0000, 0x0000, 0x0038, + 0x0039, 0x0000, 0x0000, 0x0000, 0x003a, 0x0000, 0x0000, 0x0000, + /* sub-index 0x0e */ + 0x0000, 0x0000, 0x0000, 0x003b, 0x0000, 0x0000, 0x0000, 0x0000, + 0x003c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x0f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x003d, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x10 */ + 0x0000, 0x003e, 0x0000, 0x003f, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0040, 0x0000, 0x0000, + /* sub-index 0x11 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0041, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x12 */ + 0x0000, 0x0000, 0x0000, 0x0042, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x13 */ + 0x0000, 0x0043, 0x0000, 0x0000, 0x0000, 0x0000, 0x0044, 0x0045, + 0x0000, 0x0000, 0x0000, 0x0046, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x14 */ + 0x0000, 0x0000, 0x0000, 0x0047, 0x0048, 0x0000, 0x0049, 0x004a, + 0x0000, 0x0000, 0x004b, 0x0000, 0x0000, 0x0000, 0x004c, 0x004d, + /* sub-index 0x15 */ + 0x0000, 0x0000, 0x0000, 0x004e, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x004f, 0x0050, 0x0051, + /* sub-index 0x16 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0052, 0x0053, 0x0054, 0x0055, + /* sub-index 0x17 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0056, 0x0057, 0x0058, + /* sub-index 0x18 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0059, 0x005a, + /* sub-index 0x19 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x005b, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x005c, 0x005d, + /* sub-index 0x1a */ + 0x0000, 0x0000, 0x005e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x005f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x1b */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0060, 0x0061, + 0x0000, 0x0062, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0063, + /* sub-index 0x1c */ + 0x0064, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0065, 0x0000, 0x0066, 0x0067, + /* sub-index 0x1d */ + 0x0000, 0x0000, 0x0068, 0x0000, 0x0000, 0x0069, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x006a, 0x006b, 0x0000, 0x0000, 0x0000, + /* sub-index 0x1e */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x006c, 0x006d, 0x0000, 0x0000, 0x006e, + /* sub-index 0x1f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x006f, 0x0000, + /* sub-index 0x20 */ + 0x0000, 0x0070, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x21 */ + 0x0000, 0x0000, 0x0071, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static const USHORT offsets_comb[1824] = +{ + /* all-zero 16-char blocks get mapped to here */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0300 .. 0x030f */ + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, + /* 0x0310 .. 0x031f */ + 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, + 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, + /* 0x0320 .. 0x032f */ + 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, + 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, + /* 0x0330 .. 0x033f */ + 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, + 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, + /* 0x0340 .. 0x034f */ + 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, + 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0000, + /* 0x0350 .. 0x035f */ + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + /* 0x0360 .. 0x036f */ + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + /* 0x0480 .. 0x048f */ + 0x0000, 0x0000, 0x0000, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0590 .. 0x059f */ + 0x0000, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x007e, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, + /* 0x05a0 .. 0x05af */ + 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092, 0x0093, + /* 0x05b0 .. 0x05bf */ + 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, + 0x009c, 0x009d, 0x009e, 0x009f, 0x00a0, 0x00a1, 0x0000, 0x00a2, + /* 0x05c0 .. 0x05cf */ + 0x0000, 0x00a3, 0x00a4, 0x0000, 0x00a5, 0x00a6, 0x0000, 0x00a7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0610 .. 0x061f */ + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0640 .. 0x064f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + /* 0x0650 .. 0x065f */ + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + /* 0x0670 .. 0x067f */ + 0x00c8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x06d0 .. 0x06df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00c9, 0x00ca, + 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x0000, 0x0000, 0x00d0, + /* 0x06e0 .. 0x06ef */ + 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x0000, 0x0000, 0x00d6, + 0x00d7, 0x0000, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x0000, 0x0000, + /* 0x0710 .. 0x071f */ + 0x0000, 0x00dc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0730 .. 0x073f */ + 0x00dd, 0x00de, 0x00df, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, + 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, + /* 0x0740 .. 0x074f */ + 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, + 0x00f5, 0x00f6, 0x00f7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x07e0 .. 0x07ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, + /* 0x07f0 .. 0x07ff */ + 0x00fd, 0x00fe, 0x00ff, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0101, 0x0000, 0x0000, + /* 0x0810 .. 0x081f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0102, 0x0103, + 0x0104, 0x0105, 0x0000, 0x0106, 0x0107, 0x0108, 0x0109, 0x010a, + /* 0x0820 .. 0x082f */ + 0x010b, 0x010c, 0x010d, 0x010e, 0x0000, 0x010f, 0x0110, 0x0111, + 0x0000, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, 0x0000, 0x0000, + /* 0x0850 .. 0x085f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0117, 0x0118, 0x0119, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x08d0 .. 0x08df */ + 0x0000, 0x0000, 0x0000, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + /* 0x08e0 .. 0x08ef */ + 0x0127, 0x0128, 0x0000, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, + 0x012e, 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, + /* 0x08f0 .. 0x08ff */ + 0x0136, 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, + 0x013e, 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, + /* 0x0930 .. 0x093f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0146, 0x0000, 0x0000, 0x0000, + /* 0x0940 .. 0x094f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0147, 0x0000, 0x0000, + /* 0x0950 .. 0x095f */ + 0x0000, 0x0148, 0x0149, 0x014a, 0x014b, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x09b0 .. 0x09bf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x014c, 0x0000, 0x0000, 0x0000, + /* 0x09c0 .. 0x09cf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x014d, 0x0000, 0x0000, + /* 0x09f0 .. 0x09ff */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x014e, 0x0000, + /* 0x0a30 .. 0x0a3f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x014f, 0x0000, 0x0000, 0x0000, + /* 0x0a40 .. 0x0a4f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0150, 0x0000, 0x0000, + /* 0x0ab0 .. 0x0abf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0151, 0x0000, 0x0000, 0x0000, + /* 0x0ac0 .. 0x0acf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0152, 0x0000, 0x0000, + /* 0x0b30 .. 0x0b3f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0153, 0x0000, 0x0000, 0x0000, + /* 0x0b40 .. 0x0b4f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0154, 0x0000, 0x0000, + /* 0x0bc0 .. 0x0bcf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0155, 0x0000, 0x0000, + /* 0x0c40 .. 0x0c4f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0156, 0x0000, 0x0000, + /* 0x0c50 .. 0x0c5f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0157, 0x0158, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0cb0 .. 0x0cbf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0159, 0x0000, 0x0000, 0x0000, + /* 0x0cc0 .. 0x0ccf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x015a, 0x0000, 0x0000, + /* 0x0d30 .. 0x0d3f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x015b, 0x015c, 0x0000, 0x0000, 0x0000, + /* 0x0d40 .. 0x0d4f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x015d, 0x0000, 0x0000, + /* 0x0dc0 .. 0x0dcf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x015e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0e30 .. 0x0e3f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x015f, 0x0160, 0x0161, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0e40 .. 0x0e4f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0162, 0x0163, 0x0164, 0x0165, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0eb0 .. 0x0ebf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0166, 0x0167, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0ec0 .. 0x0ecf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0168, 0x0169, 0x016a, 0x016b, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0f10 .. 0x0f1f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x016c, 0x016d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0f30 .. 0x0f3f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016e, 0x0000, 0x016f, + 0x0000, 0x0170, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0f70 .. 0x0f7f */ + 0x0000, 0x0171, 0x0172, 0x0000, 0x0173, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0174, 0x0175, 0x0176, 0x0177, 0x0000, 0x0000, + /* 0x0f80 .. 0x0f8f */ + 0x0178, 0x0000, 0x0179, 0x017a, 0x017b, 0x0000, 0x017c, 0x017d, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0fc0 .. 0x0fcf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x017e, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1030 .. 0x103f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x017f, + 0x0000, 0x0180, 0x0181, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1080 .. 0x108f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0182, 0x0000, 0x0000, + /* 0x1350 .. 0x135f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0183, 0x0184, 0x0185, + /* 0x1710 .. 0x171f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0186, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1730 .. 0x173f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0187, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x17d0 .. 0x17df */ + 0x0000, 0x0000, 0x0188, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0189, 0x0000, 0x0000, + /* 0x18a0 .. 0x18af */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x018a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1930 .. 0x193f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x018b, 0x018c, 0x018d, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1a10 .. 0x1a1f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x018e, + 0x018f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1a60 .. 0x1a6f */ + 0x0190, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1a70 .. 0x1a7f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0191, 0x0192, 0x0193, + 0x0194, 0x0195, 0x0196, 0x0197, 0x0198, 0x0000, 0x0000, 0x0199, + /* 0x1ab0 .. 0x1abf */ + 0x019a, 0x019b, 0x019c, 0x019d, 0x019e, 0x019f, 0x01a0, 0x01a1, + 0x01a2, 0x01a3, 0x01a4, 0x01a5, 0x01a6, 0x01a7, 0x0000, 0x0000, + /* 0x1b30 .. 0x1b3f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x01a8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1b40 .. 0x1b4f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x01a9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1b60 .. 0x1b6f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x01aa, 0x01ab, 0x01ac, 0x01ad, 0x01ae, + /* 0x1b70 .. 0x1b7f */ + 0x01af, 0x01b0, 0x01b1, 0x01b2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1ba0 .. 0x1baf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x01b3, 0x01b4, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1be0 .. 0x1bef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01b5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1bf0 .. 0x1bff */ + 0x0000, 0x0000, 0x01b6, 0x01b7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1c30 .. 0x1c3f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01b8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1cd0 .. 0x1cdf */ + 0x01b9, 0x01ba, 0x01bb, 0x0000, 0x01bc, 0x01bd, 0x01be, 0x01bf, + 0x01c0, 0x01c1, 0x01c2, 0x01c3, 0x01c4, 0x01c5, 0x01c6, 0x01c7, + /* 0x1ce0 .. 0x1cef */ + 0x01c8, 0x0000, 0x01c9, 0x01ca, 0x01cb, 0x01cc, 0x01cd, 0x01ce, + 0x01cf, 0x0000, 0x0000, 0x0000, 0x0000, 0x01d0, 0x0000, 0x0000, + /* 0x1cf0 .. 0x1cff */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x01d1, 0x0000, 0x0000, 0x0000, + 0x01d2, 0x01d3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1dc0 .. 0x1dcf */ + 0x01d4, 0x01d5, 0x01d6, 0x01d7, 0x01d8, 0x01d9, 0x01da, 0x01db, + 0x01dc, 0x01dd, 0x01de, 0x01df, 0x01e0, 0x01e1, 0x01e2, 0x01e3, + /* 0x1dd0 .. 0x1ddf */ + 0x01e4, 0x01e5, 0x01e6, 0x01e7, 0x01e8, 0x01e9, 0x01ea, 0x01eb, + 0x01ec, 0x01ed, 0x01ee, 0x01ef, 0x01f0, 0x01f1, 0x01f2, 0x01f3, + /* 0x1de0 .. 0x1def */ + 0x01f4, 0x01f5, 0x01f6, 0x01f7, 0x01f8, 0x01f9, 0x01fa, 0x01fb, + 0x01fc, 0x01fd, 0x01fe, 0x01ff, 0x0200, 0x0201, 0x0202, 0x0203, + /* 0x1df0 .. 0x1dff */ + 0x0204, 0x0205, 0x0206, 0x0207, 0x0208, 0x0209, 0x020a, 0x020b, + 0x020c, 0x020d, 0x0000, 0x020e, 0x020f, 0x0210, 0x0211, 0x0212, + /* 0x20d0 .. 0x20df */ + 0x0213, 0x0214, 0x0215, 0x0216, 0x0217, 0x0218, 0x0219, 0x021a, + 0x021b, 0x021c, 0x021d, 0x021e, 0x021f, 0x0000, 0x0000, 0x0000, + /* 0x20e0 .. 0x20ef */ + 0x0000, 0x0220, 0x0000, 0x0000, 0x0000, 0x0221, 0x0222, 0x0223, + 0x0224, 0x0225, 0x0226, 0x0227, 0x0228, 0x0229, 0x022a, 0x022b, + /* 0x20f0 .. 0x20ff */ + 0x022c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x2ce0 .. 0x2cef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x022d, + /* 0x2cf0 .. 0x2cff */ + 0x022e, 0x022f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x2d70 .. 0x2d7f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0230, + /* 0x2de0 .. 0x2def */ + 0x0231, 0x0232, 0x0233, 0x0234, 0x0235, 0x0236, 0x0237, 0x0238, + 0x0239, 0x023a, 0x023b, 0x023c, 0x023d, 0x023e, 0x023f, 0x0240, + /* 0x2df0 .. 0x2dff */ + 0x0241, 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247, 0x0248, + 0x0249, 0x024a, 0x024b, 0x024c, 0x024d, 0x024e, 0x024f, 0x0250, + /* 0x3020 .. 0x302f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, + /* 0x3090 .. 0x309f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0257, 0x0258, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0xa660 .. 0xa66f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0259, + /* 0xa670 .. 0xa67f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x025a, 0x025b, 0x025c, 0x025d, + 0x025e, 0x025f, 0x0260, 0x0261, 0x0262, 0x0263, 0x0000, 0x0000, + /* 0xa690 .. 0xa69f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0264, 0x0265, + /* 0xa6f0 .. 0xa6ff */ + 0x0266, 0x0267, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0xa800 .. 0xa80f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0268, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0xa8c0 .. 0xa8cf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0269, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0xa8e0 .. 0xa8ef */ + 0x026a, 0x026b, 0x026c, 0x026d, 0x026e, 0x026f, 0x0270, 0x0271, + 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277, 0x0278, 0x0279, + /* 0xa8f0 .. 0xa8ff */ + 0x027a, 0x027b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0xa920 .. 0xa92f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x027c, 0x027d, 0x027e, 0x0000, 0x0000, + /* 0xa950 .. 0xa95f */ + 0x0000, 0x0000, 0x0000, 0x027f, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0xa9b0 .. 0xa9bf */ + 0x0000, 0x0000, 0x0000, 0x0280, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0xa9c0 .. 0xa9cf */ + 0x0281, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0xaab0 .. 0xaabf */ + 0x0282, 0x0000, 0x0283, 0x0284, 0x0285, 0x0000, 0x0000, 0x0286, + 0x0287, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0288, 0x0289, + /* 0xaac0 .. 0xaacf */ + 0x0000, 0x028a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0xaaf0 .. 0xaaff */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x028b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0xabe0 .. 0xabef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x028c, 0x0000, 0x0000, + /* 0xfb10 .. 0xfb1f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x028d, 0x0000, + /* 0xfe20 .. 0xfe2f */ + 0x028e, 0x028f, 0x0290, 0x0291, 0x0292, 0x0293, 0x0294, 0x0295, + 0x0296, 0x0297, 0x0298, 0x0299, 0x029a, 0x029b, 0x029c, 0x029d +}; + +const WCHAR data_fullcomp[566] = +{ + 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001 +}; + +const BYTE idx1_fullcomp[252] = +{ + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x07, 0x08, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0b, 0x0c, 0x0d +}; + +const USHORT idx2_fullcomp[224] = +{ + /* all-zero 256-char blocks get mapped to here */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x01 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0002, + 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x02 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0004, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0005, 0x0000, 0x0000, + /* sub-index 0x03 */ + 0x0000, 0x0000, 0x0000, 0x0006, 0x0000, 0x0007, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x04 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x05 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0009, 0x000a, 0x000b, 0x000c, + 0x000d, 0x000e, 0x000f, 0x0010, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x06 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0011, + 0x0000, 0x0000, 0x0000, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, + /* sub-index 0x07 */ + 0x0017, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x08 */ + 0x0000, 0x0000, 0x0018, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x09 */ + 0x0000, 0x0000, 0x0019, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* sub-index 0x0a */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x001a, 0x0000, 0x0000, + /* sub-index 0x0b */ + 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, + 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + /* sub-index 0x0c */ + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0000, 0x0000, + /* sub-index 0x0d */ + 0x0000, 0x0039, 0x003a, 0x003b, 0x003c, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 +}; + +const USHORT offsets_fullcomp[976] = +{ + /* all-zero 16-char blocks get mapped to here */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0340 .. 0x034f */ + 0x0001, 0x0002, 0x0000, 0x0003, 0x0004, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0370 .. 0x037f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0005, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x0000, + /* 0x0380 .. 0x038f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0007, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0950 .. 0x095f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + /* 0x09d0 .. 0x09df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0011, 0x0000, 0x0012, + /* 0x0a30 .. 0x0a3f */ + 0x0000, 0x0000, 0x0000, 0x0013, 0x0000, 0x0000, 0x0014, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0a50 .. 0x0a5f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0015, 0x0016, 0x0017, 0x0000, 0x0000, 0x0018, 0x0000, + /* 0x0b50 .. 0x0b5f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0019, 0x001a, 0x0000, 0x0000, + /* 0x0f40 .. 0x0f4f */ + 0x0000, 0x0000, 0x0000, 0x001b, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x001c, 0x0000, 0x0000, + /* 0x0f50 .. 0x0f5f */ + 0x0000, 0x0000, 0x001d, 0x0000, 0x0000, 0x0000, 0x0000, 0x001e, + 0x0000, 0x0000, 0x0000, 0x0000, 0x001f, 0x0000, 0x0000, 0x0000, + /* 0x0f60 .. 0x0f6f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0020, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0f70 .. 0x0f7f */ + 0x0000, 0x0000, 0x0000, 0x0021, 0x0000, 0x0022, 0x0023, 0x0000, + 0x0024, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0f80 .. 0x0f8f */ + 0x0000, 0x0025, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x0f90 .. 0x0f9f */ + 0x0000, 0x0000, 0x0000, 0x0026, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0027, 0x0000, 0x0000, + /* 0x0fa0 .. 0x0faf */ + 0x0000, 0x0000, 0x0028, 0x0000, 0x0000, 0x0000, 0x0000, 0x0029, + 0x0000, 0x0000, 0x0000, 0x0000, 0x002a, 0x0000, 0x0000, 0x0000, + /* 0x0fb0 .. 0x0fbf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x002b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1f70 .. 0x1f7f */ + 0x0000, 0x002c, 0x0000, 0x002d, 0x0000, 0x002e, 0x0000, 0x002f, + 0x0000, 0x0030, 0x0000, 0x0031, 0x0000, 0x0032, 0x0000, 0x0000, + /* 0x1fb0 .. 0x1fbf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0033, 0x0000, 0x0000, 0x0034, 0x0000, + /* 0x1fc0 .. 0x1fcf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0035, 0x0000, 0x0036, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1fd0 .. 0x1fdf */ + 0x0000, 0x0000, 0x0000, 0x0037, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0038, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x1fe0 .. 0x1fef */ + 0x0000, 0x0000, 0x0000, 0x0039, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x003a, 0x0000, 0x0000, 0x003b, 0x003c, + /* 0x1ff0 .. 0x1fff */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x003d, 0x0000, 0x003e, 0x0000, 0x003f, 0x0000, 0x0000, + /* 0x2000 .. 0x200f */ + 0x0040, 0x0041, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x2120 .. 0x212f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0042, 0x0000, + 0x0000, 0x0000, 0x0043, 0x0044, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x2320 .. 0x232f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0045, 0x0046, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0x2ad0 .. 0x2adf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0047, 0x0000, 0x0000, 0x0000, + /* 0xf900 .. 0xf90f */ + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + /* 0xf910 .. 0xf91f */ + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + /* 0xf920 .. 0xf92f */ + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + /* 0xf930 .. 0xf93f */ + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + /* 0xf940 .. 0xf94f */ + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + /* 0xf950 .. 0xf95f */ + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + /* 0xf960 .. 0xf96f */ + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + /* 0xf970 .. 0xf97f */ + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + /* 0xf980 .. 0xf98f */ + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + /* 0xf990 .. 0xf99f */ + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + /* 0xf9a0 .. 0xf9af */ + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + /* 0xf9b0 .. 0xf9bf */ + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff, + 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, + /* 0xf9c0 .. 0xf9cf */ + 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, 0x010f, + 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, 0x0117, + /* 0xf9d0 .. 0xf9df */ + 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, 0x011f, + 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, 0x0127, + /* 0xf9e0 .. 0xf9ef */ + 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, 0x012f, + 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137, + /* 0xf9f0 .. 0xf9ff */ + 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, 0x013f, + 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0146, 0x0147, + /* 0xfa00 .. 0xfa0f */ + 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, 0x014e, 0x014f, + 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, 0x0000, 0x0000, + /* 0xfa10 .. 0xfa1f */ + 0x0156, 0x0000, 0x0157, 0x0000, 0x0000, 0x0158, 0x0159, 0x015a, + 0x015b, 0x015c, 0x015d, 0x015e, 0x015f, 0x0160, 0x0161, 0x0000, + /* 0xfa20 .. 0xfa2f */ + 0x0162, 0x0000, 0x0163, 0x0000, 0x0000, 0x0164, 0x0165, 0x0000, + 0x0000, 0x0000, 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, + /* 0xfa30 .. 0xfa3f */ + 0x016c, 0x016d, 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, + 0x0174, 0x0175, 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, + /* 0xfa40 .. 0xfa4f */ + 0x017c, 0x017d, 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, + 0x0184, 0x0185, 0x0186, 0x0187, 0x0188, 0x0189, 0x018a, 0x018b, + /* 0xfa50 .. 0xfa5f */ + 0x018c, 0x018d, 0x018e, 0x018f, 0x0190, 0x0191, 0x0192, 0x0193, + 0x0194, 0x0195, 0x0196, 0x0197, 0x0198, 0x0199, 0x019a, 0x019b, + /* 0xfa60 .. 0xfa6f */ + 0x019c, 0x019d, 0x019e, 0x019f, 0x01a0, 0x01a1, 0x01a2, 0x01a3, + 0x01a4, 0x01a5, 0x01a6, 0x01a7, 0x01a8, 0x01a9, 0x0000, 0x0000, + /* 0xfa70 .. 0xfa7f */ + 0x01aa, 0x01ab, 0x01ac, 0x01ad, 0x01ae, 0x01af, 0x01b0, 0x01b1, + 0x01b2, 0x01b3, 0x01b4, 0x01b5, 0x01b6, 0x01b7, 0x01b8, 0x01b9, + /* 0xfa80 .. 0xfa8f */ + 0x01ba, 0x01bb, 0x01bc, 0x01bd, 0x01be, 0x01bf, 0x01c0, 0x01c1, + 0x01c2, 0x01c3, 0x01c4, 0x01c5, 0x01c6, 0x01c7, 0x01c8, 0x01c9, + /* 0xfa90 .. 0xfa9f */ + 0x01ca, 0x01cb, 0x01cc, 0x01cd, 0x01ce, 0x01cf, 0x01d0, 0x01d1, + 0x01d2, 0x01d3, 0x01d4, 0x01d5, 0x01d6, 0x01d7, 0x01d8, 0x01d9, + /* 0xfaa0 .. 0xfaaf */ + 0x01da, 0x01db, 0x01dc, 0x01dd, 0x01de, 0x01df, 0x01e0, 0x01e1, + 0x01e2, 0x01e3, 0x01e4, 0x01e5, 0x01e6, 0x01e7, 0x01e8, 0x01e9, + /* 0xfab0 .. 0xfabf */ + 0x01ea, 0x01eb, 0x01ec, 0x01ed, 0x01ee, 0x01ef, 0x01f0, 0x01f1, + 0x01f2, 0x01f3, 0x01f4, 0x01f5, 0x01f6, 0x01f7, 0x01f8, 0x01f9, + /* 0xfac0 .. 0xfacf */ + 0x01fa, 0x01fb, 0x01fc, 0x01fd, 0x01fe, 0x01ff, 0x0200, 0x0201, + 0x0202, 0x0203, 0x0204, 0x0205, 0x0206, 0x0207, 0x0208, 0x0209, + /* 0xfad0 .. 0xfadf */ + 0x020a, 0x020b, 0x020c, 0x020d, 0x020e, 0x020f, 0x0210, 0x0211, + 0x0212, 0x0213, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 0xfb10 .. 0xfb1f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0214, 0x0000, 0x0215, + /* 0xfb20 .. 0xfb2f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0216, 0x0217, 0x0218, 0x0219, 0x021a, 0x021b, + /* 0xfb30 .. 0xfb3f */ + 0x021c, 0x021d, 0x021e, 0x021f, 0x0220, 0x0221, 0x0222, 0x0000, + 0x0223, 0x0224, 0x0225, 0x0226, 0x0227, 0x0000, 0x0228, 0x0000, + /* 0xfb40 .. 0xfb4f */ + 0x0229, 0x022a, 0x0000, 0x022b, 0x022c, 0x0000, 0x022d, 0x022e, + 0x022f, 0x0230, 0x0231, 0x0232, 0x0233, 0x0234, 0x0235, 0x0000 +}; + static const WCHAR *unicode_table_lookup( UINT cp, int compat, const BYTE *idx1, UINT scale_idx1, const USHORT *idx2, UINT scale_idx2, const USHORT *offsets, UINT scale_off, const WCHAR *data, UINT scale_data ) @@ -3009,6 +3929,20 @@ static const WCHAR *unicode_table_lookup( UINT cp, int compat, const BYTE *idx1, return &data[d]; } +static inline int reorderable_pair( WCHAR ch1, WCHAR ch2 ) +{ + const WCHAR *cc1, *cc2; + + if (ch1 == 0 || ch2 == 0) return 0; + + cc1 = unicode_table_lookup( ch1, 0, idx1_comb, 8, idx2_comb, 4, + offsets_comb, 4, data_comb, 0 ); + cc2 = unicode_table_lookup( ch2, 0, idx1_comb, 8, idx2_comb, 4, + offsets_comb, 4, data_comb, 0 ); + if (*cc2 < *cc1) return 1; + else return 0; +} + static int decompose_char_recursive( int compat, UINT ch, WCHAR *dst, int dstlen ) { int total_decomp = 0; @@ -3072,3 +4006,38 @@ int wine_unicode_decompose_string( int compat, const WCHAR *src, return dstpos; } + +int is_starter( WCHAR ch ) +{ + const WCHAR *map = unicode_table_lookup( ch, 0, idx1_comb, 8, idx2_comb, 4, + offsets_comb, 4, data_comb, 0 ); + return (*map == 0) ? 1 : 0; +} + +void unicode_canon_order( WCHAR *str, int strlen ) +{ + int i, j, m; + int sublen = 0, tot_sublen = 0; + WCHAR *substr = str; + + for (m = 1; m <= strlen; m++) + { + if (m == strlen || is_starter( str[m] )) sublen = m - tot_sublen; + else continue; + + for (i = 0; i < sublen; i++) + { + for (j = 1; j < sublen; j++) + { + if (reorderable_pair( substr[j-1], substr[j] )) + { + WCHAR swp = substr[j-1]; + substr[j-1] = substr[j]; + substr[j] = swp; + } + } + } + tot_sublen += m; + substr = str+m; + } +} diff --git a/tools/make_unicode b/tools/make_unicode index 2aa063bff624..4b1c46fde23c 100755 --- a/tools/make_unicode +++ b/tools/make_unicode @@ -360,6 +360,8 @@ my @joining_table = (); my @direction_table = (); my @decomp_table = (); my @compose_table = (); +my @comb_class_table = (); +my @full_comp_table = (); my $default_char; my $default_wchar; @@ -470,6 +472,11 @@ sub READ_DEFAULTS($) } } + if ($comb != 0) + { + $comb_class_table[$src] = (hex $comb); + } + next if $decomp eq ""; # no decomposition, skip it # store decomposition table @@ -562,6 +569,25 @@ sub READ_DEFAULTS($) my $flag = $ctype{$cat}; foreach my $i (@{$special_categories{$cat}}) { $category_table[$i] |= $flag; } } + + my $UNICODE_DERIVED = open_data_file( $UNIDATA, "DerivedNormalizationProps.txt" ); + while (<$UNICODE_DERIVED>) + { + next unless (/^([0-9a-fA-F.]+)\s+;\s+Full_Composition_Exclusion/); + my ($first, $last) = split /\.\./,$1; + $first = hex $first; + if (defined $last) + { + $last = hex $last; + while ($last gt $first) + { + $full_comp_table[$last] = 1; + $last--; + } + } + $full_comp_table[$first] = 1; + } + close $UNICODE_DERIVED; } @@ -2255,6 +2281,8 @@ sub dump_compose_table($) } print OUTPUT "\n};\n\n"; print OUTPUT <<"EOF"; +#include "decompose.c" + static inline int binary_search( WCHAR ch, int low, int high ) { while (low <= high) @@ -2278,6 +2306,59 @@ WCHAR DECLSPEC_HIDDEN wine_compose( const WCHAR *str ) count = table[2 * pos + 3]; } } + +static inline int is_blocked(WCHAR *ptr1, WCHAR *ptr2) +{ + if (ptr1 >= ptr2) return -1; + + while (++ptr1 < ptr2) + { + const WCHAR *map1, *map2; + map1 = unicode_table_lookup( *ptr1, 0, idx1_comb, 8, idx2_comb, 4, + offsets_comb, 4, data_comb, 0 ); + map2 = unicode_table_lookup( *ptr2, 0, idx1_comb, 8, idx2_comb, 4, + offsets_comb, 4, data_comb, 0 ); + if (*map1 == 0 || *map2 <= *map1) return 1; + } + return 0; +} + +static inline int is_fullexcl(WCHAR ch) +{ + const WCHAR *map = unicode_table_lookup( ch, 0, idx1_fullcomp, 8, idx2_fullcomp, + 4, offsets_fullcomp, 4, data_fullcomp, 0 ); + return (int)*map; +} + +int unicode_canonical_composition( WCHAR *str, int strlen ) +{ + int i, j; + WCHAR dum[3] = {0}; + + if (strlen == 0) strlen = strlenW( str ); + + for (i = 1; i < strlen; i++) + { + WCHAR *ptr_comp = str+i-1, comp; + if (str[i] == 0) break; + while (ptr_comp - str > 0) + { + if (is_starter( *ptr_comp )) break; + --ptr_comp; + } + if (!is_starter( *ptr_comp ) || is_blocked( ptr_comp, str+i )) continue; + dum[0] = *ptr_comp; + dum[1] = str[i]; + comp = wine_compose( dum ); + if (!comp || is_fullexcl( comp )) continue; + *ptr_comp = comp; + for (j = i; j < strlen-1; j++) str[j] = str[j+1]; + strlen--; + i--; + } + + return strlen; +} EOF close OUTPUT; save_file($filename); @@ -2346,13 +2427,21 @@ sub dump_decompose_table($) my %nfd_lookup = (); my %nfkd_lookup = (); my %decomp_lookup = (); + my %comb_lookup = (); + my %fullcomp_lookup = (); my @decomp_data = (0); + my @comb_data = (0); + my @full_comp_data = (0); my $pos = 1; + my $pos_comb = 1; + my $pos_fullcomp = 1; my $lastchar_decomp; + my $lastchar_comb; + my $lastchar_fullcomp; for (my $i = 0; $i < $utflim; $i++) { - next unless defined $decomp_table[$i]; + next unless defined $decomp_table[$i] || defined $comb_class_table[$i] || defined $full_comp_table[$i]; if (defined $decomp_table[$i]) { @@ -2406,6 +2495,20 @@ sub dump_decompose_table($) $pos += @nfkd; } } + if (defined $comb_class_table[$i]) + { + push @comb_data, $comb_class_table[$i]; + $lastchar_comb = $i; + $comb_lookup{$i} = $pos_comb; + $pos_comb++; + } + if (defined $full_comp_table[$i]) + { + push @full_comp_data, $full_comp_table[$i]; + $lastchar_fullcomp = $i; + $fullcomp_lookup{$i} = $pos_fullcomp; + $pos_fullcomp++; + } } printf OUTPUT "static const UINT last_decomposable = 0x%x;\n\n", $lastchar_decomp; @@ -2497,6 +2600,154 @@ sub dump_decompose_table($) } print OUTPUT "\n};\n\n"; + # now for Compatibility Class + + printf OUTPUT "static const WCHAR data_comb[%d] =\n", $pos_comb; + print OUTPUT "{\n"; + printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, @comb_data ); + print OUTPUT "\n};\n\n"; + + my $comb_pos = 1; + my $comb_lim = ($lastchar_comb >> 8) + 1; + my @comb_filled = (0) x $comb_lim; + for (my $i = 0; $i < $utflim; $i++) + { + last if $i > $lastchar_comb; + next unless defined $comb_class_table[$i]; + $comb_filled[$i >> 8] = $comb_pos++; + $i |= 255; + } + printf OUTPUT "static const BYTE idx1_comb[%d] =\n", $comb_lim; + print OUTPUT "{\n"; + printf OUTPUT "%s", DUMP_ARRAY( "0x%02x", 0, @comb_filled ); + print OUTPUT "\n};\n\n"; + + my $sub_comb_filled_pos = 1; + my %sub_comb_filled = (); + for (my $i = 0; $i < $comb_lim; $i++) + { + next unless $comb_filled[$i]; + for (my $j = 0; $j < 256; $j++) + { + my $idx = ($i << 8) | $j; + next unless defined $comb_class_table[$idx]; + $sub_comb_filled{$idx >> 4} = $sub_comb_filled_pos++; + $j |= 15; + } + } + + printf OUTPUT "static const USHORT idx2_comb[%d] =\n", $comb_pos * 16; + print OUTPUT "{\n"; + @null_idx = (0) x 16; + print OUTPUT " /* all-zero 256-char blocks get mapped to here */\n"; + printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, @null_idx ); + for (my $i = 0; $i < $comb_lim; $i++) + { + next unless $comb_filled[$i]; + printf OUTPUT ",\n /* sub-index 0x%02x */\n", $comb_filled[$i]; + + my @sub_idx; + for (my $j = 0; $j < 16; $j++) + { + my $idx = ($i << 4) | $j; + $sub_idx[$j] = $sub_comb_filled{$idx} || 0; + } + printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, @sub_idx ); + } + print OUTPUT "\n};\n\n"; + + printf OUTPUT "static const USHORT offsets_comb[%d] =\n", 16 * $sub_comb_filled_pos; + print OUTPUT "{\n"; + @null_table = (0) x 16; + print OUTPUT " /* all-zero 16-char blocks get mapped to here */\n"; + printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, @null_table ); + for my $key (sort {$a <=> $b} keys %sub_comb_filled) + { + printf OUTPUT ",\n /* 0x%03x0 .. 0x%03xf */\n", $key, $key; + my @sub_table; + for (my $j = 0; $j < 16; $j++) + { + my $idx = ($key << 4) | $j; + $sub_table[$j] = $comb_lookup{$idx} || 0; + } + printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, @sub_table ); + } + print OUTPUT "\n};\n\n"; + + # now for Full Composition Exclusion + + printf OUTPUT "const WCHAR data_fullcomp[%d] =\n", $pos_fullcomp; + print OUTPUT "{\n"; + printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, @full_comp_data ); + print OUTPUT "\n};\n\n"; + + my $fullcomp_pos = 1; + my $fullcomp_lim = ($lastchar_fullcomp >> 8) + 1; + my @fullcomp_filled = (0) x $fullcomp_lim; + for (my $i = 0; $i < $utflim; $i++) + { + last if $i > $lastchar_fullcomp; + next unless defined $full_comp_table[$i]; + $fullcomp_filled[$i >> 8] = $fullcomp_pos++; + $i |= 255; + } + printf OUTPUT "const BYTE idx1_fullcomp[%d] =\n", $fullcomp_lim; + print OUTPUT "{\n"; + printf OUTPUT "%s", DUMP_ARRAY( "0x%02x", 0, @fullcomp_filled ); + print OUTPUT "\n};\n\n"; + + my $sub_fullcomp_filled_pos = 1; + my %sub_fullcomp_filled = (); + for (my $i = 0; $i < $fullcomp_lim; $i++) + { + next unless $fullcomp_filled[$i]; + for (my $j = 0; $j < 256; $j++) + { + my $idx = ($i << 8) | $j; + next unless defined $full_comp_table[$idx]; + $sub_fullcomp_filled{$idx >> 4} = $sub_fullcomp_filled_pos++; + $j |= 15; + } + } + + printf OUTPUT "const USHORT idx2_fullcomp[%d] =\n", $fullcomp_pos * 16; + print OUTPUT "{\n"; + @null_idx = (0) x 16; + print OUTPUT " /* all-zero 256-char blocks get mapped to here */\n"; + printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, @null_idx ); + for (my $i = 0; $i < $fullcomp_lim; $i++) + { + next unless $fullcomp_filled[$i]; + printf OUTPUT ",\n /* sub-index 0x%02x */\n", $fullcomp_filled[$i]; + + my @sub_idx; + for (my $j = 0; $j < 16; $j++) + { + my $idx = ($i << 4) | $j; + $sub_idx[$j] = $sub_fullcomp_filled{$idx} || 0; + } + printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, @sub_idx ); + } + print OUTPUT "\n};\n\n"; + + printf OUTPUT "const USHORT offsets_fullcomp[%d] =\n", 16 * $sub_fullcomp_filled_pos; + print OUTPUT "{\n"; + @null_table = (0) x 16; + print OUTPUT " /* all-zero 16-char blocks get mapped to here */\n"; + printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, @null_table ); + for my $key (sort {$a <=> $b} keys %sub_fullcomp_filled) + { + printf OUTPUT ",\n /* 0x%03x0 .. 0x%03xf */\n", $key, $key; + my @sub_table; + for (my $j = 0; $j < 16; $j++) + { + my $idx = ($key << 4) | $j; + $sub_table[$j] = $fullcomp_lookup{$idx} || 0; + } + printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, @sub_table ); + } + print OUTPUT "\n};\n\n"; + print OUTPUT <<"EOF"; static const WCHAR *unicode_table_lookup( UINT cp, int compat, const BYTE *idx1, UINT scale_idx1, const USHORT *idx2, UINT scale_idx2, const USHORT *offsets, @@ -2513,6 +2764,20 @@ static const WCHAR *unicode_table_lookup( UINT cp, int compat, const BYTE *idx1, return &data[d]; } +static inline int reorderable_pair( WCHAR ch1, WCHAR ch2 ) +{ + const WCHAR *cc1, *cc2; + + if (ch1 == 0 || ch2 == 0) return 0; + + cc1 = unicode_table_lookup( ch1, 0, idx1_comb, 8, idx2_comb, 4, + offsets_comb, 4, data_comb, 0 ); + cc2 = unicode_table_lookup( ch2, 0, idx1_comb, 8, idx2_comb, 4, + offsets_comb, 4, data_comb, 0 ); + if (*cc2 < *cc1) return 1; + else return 0; +} + static int decompose_char_recursive( int compat, UINT ch, WCHAR *dst, int dstlen ) { int total_decomp = 0; @@ -2576,6 +2841,41 @@ int wine_unicode_decompose_string( int compat, const WCHAR *src, return dstpos; } + +int is_starter( WCHAR ch ) +{ + const WCHAR *map = unicode_table_lookup( ch, 0, idx1_comb, 8, idx2_comb, 4, + offsets_comb, 4, data_comb, 0 ); + return (*map == 0) ? 1 : 0; +} + +void unicode_canon_order( WCHAR *str, int strlen ) +{ + int i, j, m; + int sublen = 0, tot_sublen = 0; + WCHAR *substr = str; + + for (m = 1; m <= strlen; m++) + { + if (m == strlen || is_starter( str[m] )) sublen = m - tot_sublen; + else continue; + + for (i = 0; i < sublen; i++) + { + for (j = 1; j < sublen; j++) + { + if (reorderable_pair( substr[j-1], substr[j] )) + { + WCHAR swp = substr[j-1]; + substr[j-1] = substr[j]; + substr[j] = swp; + } + } + } + tot_sublen += m; + substr = str+m; + } +} EOF close OUTPUT; save_file($filename); -- 2.17.1