From 1a1e8cf6525de1b2c83cb8206e208e3a428619c5 Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Fri, 18 Jan 2019 12:37:53 +0800 Subject: [PATCH] Add UCharToFullWidth and UCharToFullSizeKana --- include/gdi.h | 16 +++- src/font/charset.c | 217 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 214 insertions(+), 19 deletions(-) diff --git a/include/gdi.h b/include/gdi.h index 23eb1797..ec940363 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -6968,6 +6968,18 @@ MG_EXPORT UChar32 GUIAPI UCharToLower (UChar32 uc); /** Converts a glyph to the titlecase. */ MG_EXPORT UChar32 GUIAPI UCharToTitle (UChar32 uc); +/** Converts a glyph to full-width. */ +MG_EXPORT UChar32 GUIAPI UCharToFullWidth (UChar32 uc); + +/** Converts a glyph to single-width. */ +MG_EXPORT UChar32 GUIAPI UCharToSingleWidth (UChar32 uc); + +/** Converts a glyph to full-size Kana. */ +MG_EXPORT UChar32 GUIAPI UCharToFullSizeKana (UChar32 uc); + +/** Converts a glyph to small Kana. */ +MG_EXPORT UChar32 GUIAPI UCharToSmallKana (UChar32 uc); + /** Determines the canonical combining class of a Unicode character.*/ MG_EXPORT int GUIAPI UCharCombiningClass (UChar32 uc); @@ -9311,8 +9323,8 @@ typedef enum { CT_CAPITALIZE, CT_UPPERCASE, CT_LOWERCASE, - CT_FULL_WIDTH, - CT_FULL_SIZE_KANA, + CT_FULL_WIDTH = 0x10, + CT_FULL_SIZE_KANA = 0x20, } CharTransformRule; /** diff --git a/src/font/charset.c b/src/font/charset.c index c5678dbb..aa9c0e3c 100644 --- a/src/font/charset.c +++ b/src/font/charset.c @@ -4543,28 +4543,25 @@ BOOL GUIAPI IsUCharZeroWidth(UChar32 uc) return FALSE; } -#define G_WIDTH_TABLE_MIDPOINT (TABLESIZE (g_unicode_width_table_wide) / 2) - static inline BOOL g_unichar_iswide_bsearch (UChar32 ch) { - unsigned int lower = 0; - unsigned int upper = TABLESIZE (g_unicode_width_table_wide) - 1; - static int saved_mid = G_WIDTH_TABLE_MIDPOINT; - int mid = saved_mid; + unsigned int lower = 0; + unsigned int upper = TABLESIZE (g_unicode_width_table_wide) - 1; + int mid = TABLESIZE (g_unicode_width_table_wide) / 2; - do { - if (ch < g_unicode_width_table_wide[mid].start) - upper = mid - 1; - else if (ch > g_unicode_width_table_wide[mid].end) - lower = mid + 1; - else - return TRUE; + do { + if (ch < g_unicode_width_table_wide[mid].start) + upper = mid - 1; + else if (ch > g_unicode_width_table_wide[mid].end) + lower = mid + 1; + else + return TRUE; - mid = (lower + upper) / 2; - } - while (lower <= upper); + mid = (lower + upper) / 2; + } + while (lower <= upper); - return FALSE; + return FALSE; } BOOL GUIAPI IsUCharWide(UChar32 uc) @@ -4683,4 +4680,190 @@ UChar32 GUIAPI UCharToTitle (UChar32 uc) return uc; } +/** Converts a glyph to full-width. */ +UChar32 GUIAPI UCharToFullWidth (UChar32 uc) +{ + if (uc == 0x20) + return 0x3000; + + if (uc >= 0x21 && uc <= 0x7E) { + return uc + (0xFF01 - 0x21); + } + + return uc; +} + +/** Converts a glyph to single-width. */ +UChar32 GUIAPI UCharToSingleWidth (UChar32 uc) +{ + if (uc == 0x3000) + return 0x20; + + if (uc >= 0xFF01 && uc <= 0xFF5E) { + return uc - (0xFF01 - 0x21); + } + + return uc; +} + +struct UCharMap { + UChar32 one, other; +}; + +static const struct UCharMap kana_small_to_full_size_table [] = { + { /*ぁ*/ 0x3041, /* あ*/ 0x3042}, + { /*ぃ*/ 0x3043, /* い*/ 0x3044}, + { /*ぅ*/ 0x3045, /* う*/ 0x3046}, + { /*ぇ*/ 0x3047, /* え*/ 0x3048}, + { /*ぉ*/ 0x3049, /* お*/ 0x304A}, + { /*ゕ*/ 0x3095, /* か*/ 0x304B}, + { /*ゖ*/ 0x3096, /* け*/ 0x3051}, + { /*っ*/ 0x3063, /* つ*/ 0x3064}, + { /*ゃ*/ 0x3083, /* や*/ 0x3084}, + { /*ゅ*/ 0x3085, /* ゆ*/ 0x3086}, + { /*ょ*/ 0x3087, /* よ*/ 0x3088}, + { /*ゎ*/ 0x308E, /* わ*/ 0x308F}, + { /*ァ*/ 0x30A1, /* ア*/ 0x30A2}, + { /*ィ*/ 0x30A3, /* イ*/ 0x30A4}, + { /*ゥ*/ 0x30A5, /* ウ*/ 0x30A6}, + { /*ェ*/ 0x30A7, /* エ*/ 0x30A8}, + { /*ォ*/ 0x30A9, /* オ*/ 0x30AA}, + { /*ヵ*/ 0x30F5, /* カ*/ 0x30AB}, + { /*ㇰ*/ 0x31F0, /* ク*/ 0x30AF}, + { /*ヶ*/ 0x30F6, /* ケ*/ 0x30B1}, + { /*ㇱ*/ 0x31F1, /* シ*/ 0x30B7}, + { /*ㇲ*/ 0x31F2, /* ス*/ 0x30B9}, + { /*ッ*/ 0x30C3, /* ツ*/ 0x30C4}, + { /*ㇳ*/ 0x31F3, /* ト*/ 0x30C8}, + { /*ㇴ*/ 0x31F4, /* ヌ*/ 0x30CC}, + { /*ㇵ*/ 0x31F5, /* ハ*/ 0x30CF}, + { /*ㇶ*/ 0x31F6, /* ヒ*/ 0x30D2}, + { /*ㇷ*/ 0x31F7, /* フ*/ 0x30D5}, + { /*ㇸ*/ 0x31F8, /* ヘ*/ 0x30D8}, + { /*ㇹ*/ 0x31F9, /* ホ*/ 0x30DB}, + { /*ㇺ*/ 0x31FA, /* ム*/ 0x30E0}, + { /*ャ*/ 0x30E3, /* ヤ*/ 0x30E4}, + { /*ュ*/ 0x30E5, /* ユ*/ 0x30E6}, + { /*ョ*/ 0x30E7, /* ヨ*/ 0x30E8}, + { /*ㇻ*/ 0x31FB, /* ラ*/ 0x30E9}, + { /*ㇼ*/ 0x31FC, /* リ*/ 0x30EA}, + { /*ㇽ*/ 0x31FD, /* ル*/ 0x30EB}, + { /*ㇾ*/ 0x31FE, /* レ*/ 0x30EC}, + { /*ㇿ*/ 0x31FF, /* ロ*/ 0x30ED}, + { /*ヮ*/ 0x30EE, /* ワ*/ 0x30EF}, + { /*ァ*/ 0xFF67, /* ア*/ 0xFF71}, + { /*ィ*/ 0xFF68, /* イ*/ 0xFF72}, + { /*ゥ*/ 0xFF69, /* ウ*/ 0xFF73}, + { /*ェ*/ 0xFF6A, /* エ*/ 0xFF74}, + { /*ォ*/ 0xFF6B, /* オ*/ 0xFF75}, + { /*ッ*/ 0xFF6F, /* ツ*/ 0xFF82}, + { /*ャ*/ 0xFF6C, /* ヤ*/ 0xFF94}, + { /*ュ*/ 0xFF6D, /* ユ*/ 0xFF95}, + { /*ョ*/ 0xFF6E, /* ヨ*/ 0xFF96}, +}; + +/** Converts a glyph to full-size Kana. */ +UChar32 GUIAPI UCharToFullSizeKana (UChar32 uc) +{ + unsigned int lower = 0; + unsigned int upper = TABLESIZE (kana_small_to_full_size_table) - 1; + int mid = TABLESIZE (kana_small_to_full_size_table) / 2; + + if (uc < kana_small_to_full_size_table[lower].one + || uc < kana_small_to_full_size_table[upper].one) + return uc; + + do { + if (uc < kana_small_to_full_size_table[mid].one) + upper = mid - 1; + else if (uc > kana_small_to_full_size_table[mid].one) + lower = mid + 1; + else + return kana_small_to_full_size_table[mid].other; + + mid = (lower + upper) / 2; + + } while (lower <= upper); + + return uc; +} + +static const struct UCharMap kana_full_size_to_small_table [] = { + { /*あ*/ 0x3041, /* ぁ*/ 0x3041}, + { /*い*/ 0x3043, /* ぃ*/ 0x3043}, + { /*う*/ 0x3045, /* ぅ*/ 0x3045}, + { /*え*/ 0x3047, /* ぇ*/ 0x3047}, + { /*お*/ 0x3049, /* ぉ*/ 0x3049}, + { /*か*/ 0x304A, /* ゕ*/ 0x3095}, + { /*け*/ 0x3050, /* ゖ*/ 0x3096}, + { /*つ*/ 0x3063, /* っ*/ 0x3063}, + { /*や*/ 0x3083, /* ゃ*/ 0x3083}, + { /*ゆ*/ 0x3085, /* ゅ*/ 0x3085}, + { /*よ*/ 0x3087, /* ょ*/ 0x3087}, + { /*わ*/ 0x308E, /* ゎ*/ 0x308E}, + { /*ア*/ 0x30A1, /* ァ*/ 0x30A1}, + { /*イ*/ 0x30A3, /* ィ*/ 0x30A3}, + { /*ウ*/ 0x30A5, /* ゥ*/ 0x30A5}, + { /*エ*/ 0x30A7, /* ェ*/ 0x30A7}, + { /*オ*/ 0x30A9, /* ォ*/ 0x30A9}, + { /*カ*/ 0x30AA, /* ヵ*/ 0x30F5}, + { /*ク*/ 0x30AE, /* ㇰ*/ 0x31F0}, + { /*ケ*/ 0x30B0, /* ヶ*/ 0x30F6}, + { /*シ*/ 0x30B6, /* ㇱ*/ 0x31F1}, + { /*ス*/ 0x30B8, /* ㇲ*/ 0x31F2}, + { /*ツ*/ 0x30C3, /* ッ*/ 0x30C3}, + { /*ト*/ 0x30C7, /* ㇳ*/ 0x31F3}, + { /*ヌ*/ 0x30CB, /* ㇴ*/ 0x31F4}, + { /*ハ*/ 0x30CE, /* ㇵ*/ 0x31F5}, + { /*ヒ*/ 0x30D1, /* ㇶ*/ 0x31F6}, + { /*フ*/ 0x30D4, /* ㇷ*/ 0x31F7}, + { /*ヘ*/ 0x30D7, /* ㇸ*/ 0x31F8}, + { /*ホ*/ 0x30DA, /* ㇹ*/ 0x31F9}, + { /*ム*/ 0x30DF, /* ㇺ*/ 0x31FA}, + { /*ヤ*/ 0x30E3, /* ャ*/ 0x30E3}, + { /*ユ*/ 0x30E5, /* ュ*/ 0x30E5}, + { /*ヨ*/ 0x30E7, /* ョ*/ 0x30E7}, + { /*ラ*/ 0x30E8, /* ㇻ*/ 0x31FB}, + { /*リ*/ 0x30E9, /* ㇼ*/ 0x31FC}, + { /*ル*/ 0x30EA, /* ㇽ*/ 0x31FD}, + { /*レ*/ 0x30EB, /* ㇾ*/ 0x31FE}, + { /*ロ*/ 0x30EC, /* ㇿ*/ 0x31FF}, + { /*ワ*/ 0x30EE, /* ヮ*/ 0x30EE}, + { /*ア*/ 0xFF70, /* ァ*/ 0xFF67}, + { /*イ*/ 0xFF71, /* ィ*/ 0xFF68}, + { /*ウ*/ 0xFF72, /* ゥ*/ 0xFF69}, + { /*エ*/ 0xFF73, /* ェ*/ 0xFF6A}, + { /*オ*/ 0xFF74, /* ォ*/ 0xFF6B}, + { /*ツ*/ 0xFF81, /* ッ*/ 0xFF6F}, + { /*ヤ*/ 0xFF93, /* ャ*/ 0xFF6C}, + { /*ユ*/ 0xFF94, /* ュ*/ 0xFF6D}, + { /*ヨ*/ 0xFF95, /* ョ*/ 0xFF6E}, +}; + +/** Converts a glyph to small Kana. */ +UChar32 GUIAPI UCharToSmallKana (UChar32 uc) +{ + unsigned int lower = 0; + unsigned int upper = TABLESIZE (kana_full_size_to_small_table) - 1; + int mid = TABLESIZE (kana_full_size_to_small_table) / 2; + + if (uc < kana_full_size_to_small_table[lower].one + || uc < kana_full_size_to_small_table[upper].one) + return uc; + + do { + if (uc < kana_full_size_to_small_table[mid].one) + upper = mid - 1; + else if (uc > kana_full_size_to_small_table[mid].one) + lower = mid + 1; + else + return kana_full_size_to_small_table[mid].other; + + mid = (lower + upper) / 2; + + } while (lower <= upper); + + return uc; +} + #endif /* _MGCHARSET_UNICODE */