ntdll: Add support for Hangul Unicode normalization.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
64e6d72284
commit
fdc89e02e6
|
@ -269,6 +269,16 @@ static void canonical_order_string( WCHAR *str, unsigned int len )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define HANGUL_SBASE 0xac00
|
||||||
|
#define HANGUL_LBASE 0x1100
|
||||||
|
#define HANGUL_VBASE 0x1161
|
||||||
|
#define HANGUL_TBASE 0x11a7
|
||||||
|
#define HANGUL_LCOUNT 19
|
||||||
|
#define HANGUL_VCOUNT 21
|
||||||
|
#define HANGUL_TCOUNT 28
|
||||||
|
#define HANGUL_NCOUNT (HANGUL_VCOUNT * HANGUL_TCOUNT)
|
||||||
|
#define HANGUL_SCOUNT (HANGUL_LCOUNT * HANGUL_NCOUNT)
|
||||||
|
|
||||||
static NTSTATUS decompose_string( int compat, const WCHAR *src, int src_len, WCHAR *dst, int *dst_len )
|
static NTSTATUS decompose_string( int compat, const WCHAR *src, int src_len, WCHAR *dst, int *dst_len )
|
||||||
{
|
{
|
||||||
const unsigned short *table = compat ? nfkd_table : nfd_table;
|
const unsigned short *table = compat ? nfkd_table : nfd_table;
|
||||||
|
@ -276,8 +286,19 @@ static NTSTATUS decompose_string( int compat, const WCHAR *src, int src_len, WCH
|
||||||
unsigned int ch, len, decomp_len;
|
unsigned int ch, len, decomp_len;
|
||||||
const WCHAR *decomp;
|
const WCHAR *decomp;
|
||||||
|
|
||||||
for (src_pos = dst_pos = 0; src_pos < src_len; src_pos += len, dst_pos += decomp_len)
|
for (src_pos = dst_pos = 0; src_pos < src_len; src_pos += len)
|
||||||
{
|
{
|
||||||
|
if (src[src_pos] >= HANGUL_SBASE && src[src_pos] < HANGUL_SBASE + HANGUL_SCOUNT)
|
||||||
|
{
|
||||||
|
unsigned short sindex = src[src_pos] - HANGUL_SBASE;
|
||||||
|
unsigned short tindex = sindex % HANGUL_TCOUNT;
|
||||||
|
if (dst_pos + 2 + !!tindex > *dst_len) break;
|
||||||
|
dst[dst_pos++] = HANGUL_LBASE + sindex / HANGUL_NCOUNT;
|
||||||
|
dst[dst_pos++] = HANGUL_VBASE + (sindex % HANGUL_NCOUNT) / HANGUL_TCOUNT;
|
||||||
|
if (tindex) dst[dst_pos++] = HANGUL_TBASE + tindex;
|
||||||
|
len = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!(len = get_utf16( src + src_pos, src_len - src_pos, &ch )) ||
|
if (!(len = get_utf16( src + src_pos, src_len - src_pos, &ch )) ||
|
||||||
(ch >= 0xfdd0 && ch <= 0xfdef) || ((ch & 0xffff) >= 0xfffe))
|
(ch >= 0xfdd0 && ch <= 0xfdef) || ((ch & 0xffff) >= 0xfffe))
|
||||||
{
|
{
|
||||||
|
@ -288,6 +309,7 @@ static NTSTATUS decompose_string( int compat, const WCHAR *src, int src_len, WCH
|
||||||
if (dst_pos + decomp_len > *dst_len) break;
|
if (dst_pos + decomp_len > *dst_len) break;
|
||||||
if (decomp) memcpy( dst + dst_pos, decomp, decomp_len * sizeof(WCHAR) );
|
if (decomp) memcpy( dst + dst_pos, decomp, decomp_len * sizeof(WCHAR) );
|
||||||
else put_utf16( dst + dst_pos, ch );
|
else put_utf16( dst + dst_pos, ch );
|
||||||
|
dst_pos += decomp_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src_pos < src_len)
|
if (src_pos < src_len)
|
||||||
|
@ -301,6 +323,28 @@ static NTSTATUS decompose_string( int compat, const WCHAR *src, int src_len, WCH
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned int compose_hangul( unsigned int ch1, unsigned int ch2 )
|
||||||
|
{
|
||||||
|
if (ch1 >= HANGUL_LBASE && ch1 < HANGUL_LBASE + HANGUL_LCOUNT)
|
||||||
|
{
|
||||||
|
int lindex = ch1 - HANGUL_LBASE;
|
||||||
|
int vindex = ch2 - HANGUL_VBASE;
|
||||||
|
if (vindex >= 0 && vindex < HANGUL_VCOUNT)
|
||||||
|
return HANGUL_SBASE + (lindex * HANGUL_VCOUNT + vindex) * HANGUL_TCOUNT;
|
||||||
|
}
|
||||||
|
if (ch1 >= HANGUL_SBASE && ch1 < HANGUL_SBASE + HANGUL_SCOUNT)
|
||||||
|
{
|
||||||
|
int sindex = ch1 - HANGUL_SBASE;
|
||||||
|
if (!(sindex % HANGUL_TCOUNT))
|
||||||
|
{
|
||||||
|
int tindex = ch2 - HANGUL_TBASE;
|
||||||
|
if (tindex > 0 && tindex < HANGUL_TCOUNT) return ch1 + tindex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned int compose_string( WCHAR *str, unsigned int srclen )
|
static unsigned int compose_string( WCHAR *str, unsigned int srclen )
|
||||||
{
|
{
|
||||||
unsigned int i, ch, comp, len, start_ch = 0, last_starter = srclen;
|
unsigned int i, ch, comp, len, start_ch = 0, last_starter = srclen;
|
||||||
|
@ -311,7 +355,7 @@ static unsigned int compose_string( WCHAR *str, unsigned int srclen )
|
||||||
if (!(len = get_utf16( str + i, srclen - i, &ch ))) return 0;
|
if (!(len = get_utf16( str + i, srclen - i, &ch ))) return 0;
|
||||||
class = get_combining_class( ch );
|
class = get_combining_class( ch );
|
||||||
if (last_starter == srclen || (prev_class && prev_class >= class) ||
|
if (last_starter == srclen || (prev_class && prev_class >= class) ||
|
||||||
!(comp = wine_compose( start_ch, ch )))
|
(!(comp = compose_hangul( start_ch, ch )) && !(comp = wine_compose( start_ch, ch ))))
|
||||||
{
|
{
|
||||||
if (!class)
|
if (!class)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue