diff --git a/libs/wine/compose.c b/libs/wine/compose.c index 8ae6b56f219..da49b448c72 100644 --- a/libs/wine/compose.c +++ b/libs/wine/compose.c @@ -4,7 +4,7 @@ #include "wine/unicode.h" -const WCHAR unicode_compose_table[0x85e] = +static const WCHAR table[0x85e] = { /* second chars + offsets */ 0x0300, 0x0047, 0x0301, 0x009b, 0x0302, 0x0111, 0x0303, 0x0131, @@ -380,4 +380,26 @@ const WCHAR unicode_compose_table[0x85e] = 0x30d8, 0x30da, 0x30db, 0x30dd }; -const unsigned int unicode_compose_table_size = 70; +static inline int binary_search( WCHAR ch, int low, int high ) +{ + while (low <= high) + { + int pos = (low + high) / 2; + if (table[2 * pos] < ch) low = pos + 1; + else if (table[2 * pos] > ch) high = pos - 1; + else return pos; + } + return -1; +} + +WCHAR wine_compose( const WCHAR *str ) +{ + int pos, idx = 1, start = 0, count = 70; + for (;;) + { + if ((pos = binary_search( str[idx], start, count - 1 )) == -1) return 0; + if (!idx--) return table[2 * pos + 1]; + start = table[2 * pos + 1]; + count = table[2 * pos + 3]; + } +} diff --git a/libs/wine/decompose.c b/libs/wine/decompose.c index ef9c35dd25d..3e4a28b038a 100644 --- a/libs/wine/decompose.c +++ b/libs/wine/decompose.c @@ -4,7 +4,7 @@ #include "wine/unicode.h" -const WCHAR unicode_decompose_table[4704] = +static const WCHAR table[4704] = { /* index */ 0x0110, 0x0120, 0x0130, 0x0140, 0x0150, 0x0100, 0x0160, 0x0100, @@ -746,3 +746,16 @@ const WCHAR unicode_decompose_table[4704] = 0x05e8, 0x05bc, 0x05e9, 0x05bc, 0x05ea, 0x05bc, 0x05d5, 0x05b9, 0x05d1, 0x05bf, 0x05db, 0x05bf, 0x05e4, 0x05bf, 0x0000, 0x0000 }; + +unsigned int wine_decompose( WCHAR ch, WCHAR *dst, unsigned int dstlen ) +{ + const WCHAR *ptr = table + table[table[ch >> 8] + ((ch >> 4) & 0x0f)] + 2 * (ch & 0xf); + unsigned int res; + + *dst = ch; + if (!*ptr) return 1; + if (dstlen <= 1) return 0; + /* apply the decomposition recursively to the first char */ + if ((res = wine_decompose( *ptr, dst, dstlen-1 ))) dst[res++] = ptr[1]; + return res; +} diff --git a/libs/wine/mbtowc.c b/libs/wine/mbtowc.c index 9267d9de9b9..9a4bc2381f1 100644 --- a/libs/wine/mbtowc.c +++ b/libs/wine/mbtowc.c @@ -22,22 +22,7 @@ #include "wine/unicode.h" -/* get the decomposition of a Unicode char */ -static int get_decomposition( WCHAR src, WCHAR *dst, unsigned int dstlen ) -{ - extern const WCHAR unicode_decompose_table[]; - const WCHAR *ptr = unicode_decompose_table; - int res; - - *dst = src; - ptr = unicode_decompose_table + ptr[src >> 8]; - ptr = unicode_decompose_table + ptr[(src >> 4) & 0x0f] + 2 * (src & 0x0f); - if (!*ptr) return 1; - if (dstlen <= 1) return 0; - /* apply the decomposition recursively to the first char */ - if ((res = get_decomposition( *ptr, dst, dstlen-1 ))) dst[res++] = ptr[1]; - return res; -} +extern unsigned int wine_decompose( WCHAR ch, WCHAR *dst, unsigned int dstlen ); /* check the code whether it is in Unicode Private Use Area (PUA). */ /* MB_ERR_INVALID_CHARS raises an error converting from 1-byte character to PUA. */ @@ -122,13 +107,13 @@ static int mbstowcs_sbcs_decompose( const struct sbcs_table *table, int flags, { WCHAR dummy[4]; /* no decomposition is larger than 4 chars */ for (len = 0; srclen; srclen--, src++) - len += get_decomposition( cp2uni[*src], dummy, 4 ); + len += wine_decompose( cp2uni[*src], dummy, 4 ); return len; } for (len = dstlen; srclen && len; srclen--, src++) { - int res = get_decomposition( cp2uni[*src], dst, len ); + unsigned int res = wine_decompose( cp2uni[*src], dst, len ); if (!res) break; len -= res; dst += res; @@ -218,9 +203,8 @@ static int mbstowcs_dbcs_decompose( const struct dbcs_table *table, { const WCHAR * const cp2uni = table->cp2uni; const unsigned char * const cp2uni_lb = table->cp2uni_leadbytes; - unsigned int len; + unsigned int len, res; WCHAR ch; - int res; if (!dstlen) /* compute length */ { @@ -235,7 +219,7 @@ static int mbstowcs_dbcs_decompose( const struct dbcs_table *table, ch = cp2uni[(off << 8) + *src]; } else ch = cp2uni[*src]; - len += get_decomposition( ch, dummy, 4 ); + len += wine_decompose( ch, dummy, 4 ); } return len; } @@ -250,7 +234,7 @@ static int mbstowcs_dbcs_decompose( const struct dbcs_table *table, ch = cp2uni[(off << 8) + *src]; } else ch = cp2uni[*src]; - if (!(res = get_decomposition( ch, dst, len ))) break; + if (!(res = wine_decompose( ch, dst, len ))) break; dst += res; len -= res; } diff --git a/libs/wine/sortkey.c b/libs/wine/sortkey.c index 7280501dceb..634e910d4c3 100644 --- a/libs/wine/sortkey.c +++ b/libs/wine/sortkey.c @@ -19,7 +19,7 @@ */ #include "wine/unicode.h" -extern int get_decomposition(WCHAR src, WCHAR *dst, unsigned int dstlen); +extern unsigned int wine_decompose( WCHAR ch, WCHAR *dst, unsigned int dstlen ); extern const unsigned int collation_table[]; /* @@ -38,11 +38,10 @@ int wine_get_sortkey(int flags, const WCHAR *src, int srclen, char *dst, int dst key_len[0] = key_len[1] = key_len[2] = key_len[3] = 0; for (; srclen; srclen--, src++) { - int decomposed_len = 1;/*get_decomposition(*src, dummy, 4);*/ + unsigned int i, decomposed_len = 1;/*wine_decompose(*src, dummy, 4);*/ dummy[0] = *src; if (decomposed_len) { - int i; for (i = 0; i < decomposed_len; i++) { WCHAR wch = dummy[i]; @@ -96,11 +95,10 @@ int wine_get_sortkey(int flags, const WCHAR *src, int srclen, char *dst, int dst for (; srclen; srclen--, src++) { - int decomposed_len = 1;/*get_decomposition(*src, dummy, 4);*/ + unsigned int i, decomposed_len = 1;/*wine_decompose(*src, dummy, 4);*/ dummy[0] = *src; if (decomposed_len) { - int i; for (i = 0; i < decomposed_len; i++) { WCHAR wch = dummy[i]; diff --git a/libs/wine/utf8.c b/libs/wine/utf8.c index c95bc519155..5943ddadd72 100644 --- a/libs/wine/utf8.c +++ b/libs/wine/utf8.c @@ -22,7 +22,7 @@ #include "wine/unicode.h" -extern WCHAR compose( const WCHAR *str ); +extern WCHAR wine_compose( const WCHAR *str ); /* number of following bytes in sequence based on first byte value (for bytes above 0x7f) */ static const char utf8_length[128] = @@ -208,7 +208,7 @@ static inline int get_length_mbs_utf8_compose( int flags, const char *src, int s if (composed[0]) { composed[1] = res; - if ((composed[0] = compose( composed ))) continue; + if ((composed[0] = wine_compose( composed ))) continue; } composed[0] = res; ret++; @@ -250,7 +250,7 @@ static int utf8_mbstowcs_compose( int flags, const char *src, int srclen, WCHAR if (composed[0]) { composed[1] = res; - if ((composed[0] = compose( composed ))) + if ((composed[0] = wine_compose( composed ))) { dst[-1] = composed[0]; continue; diff --git a/libs/wine/wctomb.c b/libs/wine/wctomb.c index 62c0fc29d40..e7f35e5980e 100644 --- a/libs/wine/wctomb.c +++ b/libs/wine/wctomb.c @@ -22,45 +22,7 @@ #include "wine/unicode.h" -/* search for a character in the unicode_compose_table; helper for compose() */ -static inline int binary_search( WCHAR ch, int low, int high ) -{ - extern const WCHAR unicode_compose_table[]; - while (low <= high) - { - int pos = (low + high) / 2; - if (unicode_compose_table[2*pos] < ch) - { - low = pos + 1; - continue; - } - if (unicode_compose_table[2*pos] > ch) - { - high = pos - 1; - continue; - } - return pos; - } - return -1; -} - -/* return the result of the composition of two Unicode chars, or 0 if none */ -WCHAR compose( const WCHAR *str ) -{ - extern const WCHAR unicode_compose_table[]; - extern const unsigned int unicode_compose_table_size; - - int idx = 1, low = 0, high = unicode_compose_table_size - 1; - for (;;) - { - int pos = binary_search( str[idx], low, high ); - if (pos == -1) return 0; - if (!idx--) return unicode_compose_table[2*pos+1]; - low = unicode_compose_table[2*pos+1]; - high = unicode_compose_table[2*pos+3] - 1; - } -} - +extern WCHAR wine_compose( const WCHAR *str ); /****************************************************************/ /* sbcs support */ @@ -91,7 +53,7 @@ static int get_length_sbcs( const struct sbcs_table *table, int flags, WCHAR wch = *src; unsigned char ch; - if ((flags & WC_COMPOSITECHECK) && (srclen > 1) && (composed = compose(src))) + if ((flags & WC_COMPOSITECHECK) && (srclen > 1) && (composed = wine_compose(src))) { /* now check if we can use the composed char */ ch = uni2cp_low[uni2cp_high[composed >> 8] + (composed & 0xff)]; @@ -215,7 +177,7 @@ static int wcstombs_sbcs_slow( const struct sbcs_table *table, int flags, { WCHAR wch = *src; - if ((flags & WC_COMPOSITECHECK) && (srclen > 1) && (composed = compose(src))) + if ((flags & WC_COMPOSITECHECK) && (srclen > 1) && (composed = wine_compose(src))) { /* now check if we can use the composed char */ *dst = uni2cp_low[uni2cp_high[composed >> 8] + (composed & 0xff)]; @@ -310,7 +272,7 @@ static int get_length_dbcs( const struct dbcs_table *table, int flags, unsigned short res; WCHAR wch = *src; - if ((flags & WC_COMPOSITECHECK) && (srclen > 1) && (composed = compose(src))) + if ((flags & WC_COMPOSITECHECK) && (srclen > 1) && (composed = wine_compose(src))) { /* now check if we can use the composed char */ res = uni2cp_low[uni2cp_high[composed >> 8] + (composed & 0xff)]; @@ -395,7 +357,7 @@ static int wcstombs_dbcs_slow( const struct dbcs_table *table, int flags, unsigned short res; WCHAR wch = *src; - if ((flags & WC_COMPOSITECHECK) && (srclen > 1) && (composed = compose(src))) + if ((flags & WC_COMPOSITECHECK) && (srclen > 1) && (composed = wine_compose(src))) { /* now check if we can use the composed char */ res = uni2cp_low[uni2cp_high[composed >> 8] + (composed & 0xff)]; diff --git a/tools/make_unicode b/tools/make_unicode index 5d1bbebb7dd..de008fc948e 100755 --- a/tools/make_unicode +++ b/tools/make_unicode @@ -2083,7 +2083,7 @@ sub dump_compose_table($) } # terminator with last position push @table, 0, $pos; - printf OUTPUT "const WCHAR unicode_compose_table[0x%x] =\n{\n", 2*$pos; + printf OUTPUT "static const WCHAR table[0x%x] =\n{\n", 2*$pos; printf OUTPUT " /* second chars + offsets */\n%s", DUMP_ARRAY( "0x%04x", 0, @table ); # build the table of first chars and mappings @@ -2099,7 +2099,32 @@ sub dump_compose_table($) } printf OUTPUT ",\n /* 0x%04x */\n%s", $i, DUMP_ARRAY( "0x%04x", 0, @table ); } - printf OUTPUT "\n};\n\nconst unsigned int unicode_compose_table_size = %d;\n", $count; + print OUTPUT "\n};\n\n"; + print OUTPUT <<"EOF"; +static inline int binary_search( WCHAR ch, int low, int high ) +{ + while (low <= high) + { + int pos = (low + high) / 2; + if (table[2 * pos] < ch) low = pos + 1; + else if (table[2 * pos] > ch) high = pos - 1; + else return pos; + } + return -1; +} + +WCHAR wine_compose( const WCHAR *str ) +{ + int pos, idx = 1, start = 0, count = $count; + for (;;) + { + if ((pos = binary_search( str[idx], start, count - 1 )) == -1) return 0; + if (!idx--) return table[2 * pos + 1]; + start = table[2 * pos + 1]; + count = table[2 * pos + 3]; + } +} +EOF close OUTPUT; save_file($filename); } @@ -2154,7 +2179,7 @@ sub dump_decompose_table($) # dump the main index - printf OUTPUT "const WCHAR unicode_decompose_table[%d] =\n", $total; + printf OUTPUT "static const WCHAR table[%d] =\n", $total; printf OUTPUT "{\n /* index */\n"; printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, @filled_idx ); printf OUTPUT ",\n /* null sub-index */\n%s", DUMP_ARRAY( "0x%04x", 0, ($null_offset) x 16 ); @@ -2191,7 +2216,21 @@ sub dump_decompose_table($) printf OUTPUT "%s", DUMP_ARRAY( "0x%04x", 0, @table ); } - printf OUTPUT "\n};\n"; + printf OUTPUT "\n};\n\n"; + print OUTPUT <<"EOF"; +unsigned int wine_decompose( WCHAR ch, WCHAR *dst, unsigned int dstlen ) +{ + const WCHAR *ptr = table + table[table[ch >> 8] + ((ch >> 4) & 0x0f)] + 2 * (ch & 0xf); + unsigned int res; + + *dst = ch; + if (!*ptr) return 1; + if (dstlen <= 1) return 0; + /* apply the decomposition recursively to the first char */ + if ((res = wine_decompose( *ptr, dst, dstlen-1 ))) dst[res++] = ptr[1]; + return res; +} +EOF close OUTPUT; save_file($filename); }