Alexandre Julliard : ntdll: Add support for Hangul Unicode normalization.
Alexandre Julliard
julliard at winehq.org
Mon Feb 17 15:42:15 CST 2020
Module: wine
Branch: master
Commit: fdc89e02e65adc4c0f2b28147154291fb9aa8bc6
URL: https://source.winehq.org/git/wine.git/?a=commit;h=fdc89e02e65adc4c0f2b28147154291fb9aa8bc6
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Feb 17 11:08:45 2020 +0100
ntdll: Add support for Hangul Unicode normalization.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/locale.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 46 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/locale.c b/dlls/ntdll/locale.c
index 90800c92bb..27dceaf8e7 100644
--- a/dlls/ntdll/locale.c
+++ b/dlls/ntdll/locale.c
@@ -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 )
{
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;
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 )) ||
(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 (decomp) memcpy( dst + dst_pos, decomp, decomp_len * sizeof(WCHAR) );
else put_utf16( dst + dst_pos, ch );
+ dst_pos += decomp_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 )
{
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;
class = get_combining_class( ch );
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)
{
More information about the wine-cvs
mailing list