[KERNEL32] LCMapString: Convert Chinese characters (#5316)

* [KERNEL32] LCMAP_SIMPLIFIED_CHINESE and LCMAP_TRADITIONAL_CHINESE

* fix

* improve

* reduce data

* improve
This commit is contained in:
Katayama Hirofumi MZ 2023-06-04 21:46:01 +09:00 committed by GitHub
parent 51279c3e44
commit 13b1eadebb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 4883 additions and 2 deletions

View file

@ -2127,6 +2127,73 @@ static int map_to_uppercase(DWORD flags, const WCHAR *src, int srclen, WCHAR *ds
return pos;
}
typedef struct tagWCHAR_PAIR
{
WCHAR from, to;
} WCHAR_PAIR, *PWCHAR_PAIR;
/* The table to convert Simplified Chinese to Traditional Chinese */
static const WCHAR_PAIR s_sim2tra[] =
{
#define DEFINE_SIM2TRA(from, to) { from, to },
#include "sim2tra.h"
#undef DEFINE_SIM2TRA
};
/* The table to convert Traditional Chinese to Simplified Chinese */
static const WCHAR_PAIR s_tra2sim[] =
{
#define DEFINE_TRA2SIM(from, to) { from, to },
#include "tra2sim.h"
#undef DEFINE_TRA2SIM
};
/* The comparison function to do bsearch */
static int compare_wchar_pair(const void *x, const void *y)
{
const WCHAR_PAIR *a = x;
const WCHAR_PAIR *b = y;
if (a->from < b->from)
return -1;
if (a->from > b->from)
return +1;
return 0;
}
static WCHAR find_wchar_pair(const WCHAR_PAIR *pairs, size_t count, WCHAR ch)
{
PWCHAR_PAIR found = bsearch(&ch, pairs, count, sizeof(WCHAR_PAIR), compare_wchar_pair);
if (found)
return found->to;
return ch;
}
static int map_to_simplified_chinese(DWORD flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
{
int pos;
for (pos = 0; srclen; src++, srclen--)
{
WCHAR wch = *src;
if (pos < dstlen)
dst[pos] = find_wchar_pair(s_tra2sim, ARRAY_SIZE(s_tra2sim), wch);
pos++;
}
return pos;
}
static int map_to_traditional_chinese(DWORD flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
{
int pos;
for (pos = 0; srclen; src++, srclen--)
{
WCHAR wch = *src;
if (pos < dstlen)
dst[pos] = find_wchar_pair(s_sim2tra, ARRAY_SIZE(s_sim2tra), wch);
pos++;
}
return pos;
}
static int map_remove_ignored(DWORD flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen)
{
int pos;
@ -2195,10 +2262,10 @@ static int lcmap_string(DWORD flags, const WCHAR *src, int srclen, WCHAR *dst, i
map_to_katakana(dst, ret, dst, dstlen);
break;
case LCMAP_SIMPLIFIED_CHINESE:
FIXME("LCMAP_SIMPLIFIED_CHINESE\n");
ret = map_to_simplified_chinese(flags, src, srclen, dst, dstlen);
break;
case LCMAP_TRADITIONAL_CHINESE:
FIXME("LCMAP_TRADITIONAL_CHINESE\n");
ret = map_to_traditional_chinese(flags, src, srclen, dst, dstlen);
break;
case NORM_IGNORENONSPACE:
case NORM_IGNORESYMBOLS:

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff