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