2 * Copyright (C) 2005-2024 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "InputCodingTableKorean.h"
11 #include "utils/CharsetConverter.h"
15 CInputCodingTableKorean::CInputCodingTableKorean() = default;
17 std::vector
<std::wstring
> CInputCodingTableKorean::GetResponse(int)
22 bool CInputCodingTableKorean::GetWordListPage(const std::string
& strCode
, bool isFirstPage
)
27 void CInputCodingTableKorean::SetTextPrev(const std::string
& strTextPrev
)
29 m_strTextPrev
= strTextPrev
;
32 int CInputCodingTableKorean::MergeCode(int choseong
, int jungseong
, int jongseong
)
34 return (unsigned short)0xAC00 + choseong
* 21 * 28 + jungseong
* 28 + jongseong
+ 1;
38 // https://en.wikipedia.org/wiki/Hangul
39 // http://www.theyt.net/wiki/%ED%95%9C%EC%98%81%ED%83%80%EB%B3%80%ED%99%98%EA%B8%B0
41 std::wstring
CInputCodingTableKorean::InputToKorean(const std::wstring
& input
)
43 std::wstring dicEnglish
= // L"rRseEfaqQtTdwWczxvgkoiOjpuPhynbml";
44 {0x72, 0x52, 0x73, 0x65, 0x45, 0x66, 0x61, 0x71, 0x51, 0x74, 0x54,
45 0x64, 0x77, 0x57, 0x63, 0x7A, 0x78, 0x76, 0x67, 0x6B, 0x6F, 0x69,
46 0x4F, 0x6A, 0x70, 0x75, 0x50, 0x68, 0x79, 0x6E, 0x62, 0x6D, 0x6C};
47 std::wstring dicKorean
= // L"ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎㅏㅐㅑㅒㅓㅔㅕㅖㅗㅛㅜㅠㅡㅣ";
48 {0x3131, 0x3132, 0x3134, 0x3137, 0x3138, 0x3139, 0x3141, 0x3142, 0x3143, 0x3145, 0x3146,
49 0x3147, 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f, 0x3150, 0x3151,
50 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x315b, 0x315c, 0x3160, 0x3161, 0x3163};
51 std::wstring dicChoseong
= // L"ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ";
52 {0x3131, 0x3132, 0x3134, 0x3137, 0x3138, 0x3139, 0x3141, 0x3142, 0x3143, 0x3145,
53 0x3146, 0x3147, 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e};
54 std::wstring dicJungseong
= // L"ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ";
55 {0x314f, 0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x3158, 0x3159,
56 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f, 0x3160, 0x3161, 0x3162, 0x3163};
57 std::wstring dicJongseong
= // L"ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ";
58 {0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3139, 0x313a,
59 0x313b, 0x313c, 0x313d, 0x313e, 0x313f, 0x3140, 0x3141, 0x3142, 0x3144,
60 0x3145, 0x3146, 0x3147, 0x3148, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e};
67 int choseong
= -1, jungseong
= -1, jongseong
= -1;
69 for (unsigned int i
= 0; i
< input
.size(); i
++)
71 wchar_t ch
= input
.at(i
);
72 int key
= dicKorean
.find(ch
);
74 // H/W Keyboard input with English will be changed to Korean
75 // because H/W input in Korean is not supported.
77 key
= dicEnglish
.find(ch
);
79 if (key
== -1) // If not Korean and English
81 // If there is remained Korean, merge code into character
82 if (choseong
!= -1) // There is choseong
84 if (jungseong
!= -1) // choseong+jungseong+(jongseong)
85 korean
+= MergeCode(choseong
, jungseong
, jongseong
);
87 korean
+= dicChoseong
.at(choseong
);
91 if (jungseong
!= -1) // Jungseong
92 korean
+= dicJungseong
.at(jungseong
);
94 if (jongseong
!= -1) // Jongseong
95 korean
+= dicJongseong
.at(jongseong
);
102 else if (key
< 19) // If key is consonant, key could be choseong or jungseong
106 // Jungseong without choseong cannot have jongseong.
107 // So inputted key is jungseong character, new character is begun.
110 korean
+= dicJungseong
.at(jungseong
);
114 else // Jungseong with choseong can have jongseong.
116 // Chongseong can have two consonant. So this is first consonant of chongseong.
119 jongseong
= dicJongseong
.find(dicKorean
.at(key
));
120 if (jongseong
== -1) // This consonant cannot be jongseong. ex) "ㄸ", "ㅃ", "ㅉ"
122 korean
+= MergeCode(choseong
, jungseong
, jongseong
);
123 choseong
= dicChoseong
.find(dicKorean
.at(key
));
127 else if (jongseong
== 0 && key
== 9) // "ㄳ"
129 else if (jongseong
== 3 && key
== 12) // "ㄵ"
131 else if (jongseong
== 3 && key
== 18) // "ㄶ"
133 else if (jongseong
== 7 && key
== 0) // "ㄺ"
135 else if (jongseong
== 7 && key
== 6) // "ㄻ"
137 else if (jongseong
== 7 && key
== 7) // "ㄼ"
139 else if (jongseong
== 7 && key
== 9) // "ㄽ"
141 else if (jongseong
== 7 && key
== 16) // "ㄾ"
143 else if (jongseong
== 7 && key
== 17) // "ㄿ"
145 else if (jongseong
== 7 && key
== 18) // "ㅀ"
147 else if (jongseong
== 16 && key
== 9) // "ㅄ"
149 else // Jongseong is completed. So new consonant is choseong.
151 korean
+= MergeCode(choseong
, jungseong
, jongseong
);
152 choseong
= dicChoseong
.find(dicKorean
.at(key
));
158 else // If there is no jungseong, new consonant can be choseong or second part of double
161 // New consonant is choseong. Also it could be first part of double consonant.
164 // If choseong is already completed, new consonant is another choseong.
165 // So previous character has only jongseong.
168 korean
+= dicJongseong
.at(jongseong
);
171 choseong
= dicChoseong
.find(dicKorean
.at(key
));
173 // Find double consonant of chongseong
174 else if (choseong
== 0 && key
== 9) // "ㄳ"
179 else if (choseong
== 2 && key
== 12) // "ㄵ"
184 else if (choseong
== 2 && key
== 18) // "ㄶ"
189 else if (choseong
== 5 && key
== 0) // "ㄺ"
194 else if (choseong
== 5 && key
== 6) // "ㄻ"
199 else if (choseong
== 5 && key
== 7) // "ㄼ"
204 else if (choseong
== 5 && key
== 9) // "ㄽ"
209 else if (choseong
== 5 && key
== 16) // "ㄾ"
214 else if (choseong
== 5 && key
== 17) // "ㄿ"
219 else if (choseong
== 5 && key
== 18) // "ㅀ"
224 else if (choseong
== 7 && key
== 9) // "ㅄ"
229 else // In this case, previous character has only choseong. And new consonant is choseong.
231 korean
+= dicChoseong
.at(choseong
);
232 choseong
= dicChoseong
.find(dicKorean
.at(key
));
236 else // If key is vowel, key is jungseong.
238 // If previous character has jongseong and this key is jungseong,
239 // actually latest vowel is not jongseong. It's choseong of new character.
242 // If jongseong of previous character is double consonant, we will separate it to two vowel
243 // again. First part of double consonant is jongseong of previous character. Second part of
244 // double consonant is choseong of current character.
246 if (jongseong
== 2) // "ㄱ, ㅅ"
251 else if (jongseong
== 4) // "ㄴ, ㅈ"
256 else if (jongseong
== 5) // "ㄴ, ㅎ"
261 else if (jongseong
== 8) // "ㄹ, ㄱ"
266 else if (jongseong
== 9) // "ㄹ, ㅁ"
271 else if (jongseong
== 10) // "ㄹ, ㅂ"
276 else if (jongseong
== 11) // "ㄹ, ㅅ"
281 else if (jongseong
== 12) // "ㄹ, ㅌ"
286 else if (jongseong
== 13) // "ㄹ, ㅍ"
291 else if (jongseong
== 14) // "ㄹ, ㅎ"
296 else if (jongseong
== 17) // "ㅂ, ㅅ"
303 // If jongseong is single consonant, previous character has no chongseong.
304 // It's choseong of current character.
305 newCho
= dicChoseong
.find(dicJongseong
.at(jongseong
));
308 if (choseong
!= -1) // If previous character has choseong and jungseong.
309 korean
+= MergeCode(choseong
, jungseong
, jongseong
);
310 else // If previous character has Jongseong only.
311 korean
+= dicJongseong
.at(jongseong
);
317 if (jungseong
== -1) // If this key is first vowel, it's first part of jungseong.
319 jungseong
= dicJungseong
.find(dicKorean
.at(key
));
321 // If there is jungseong already, jungseong is double vowel.
322 else if (jungseong
== 8 && key
== 19) // "ㅘ"
324 else if (jungseong
== 8 && key
== 20) // "ㅙ"
326 else if (jungseong
== 8 && key
== 32) // "ㅚ"
328 else if (jungseong
== 13 && key
== 23) // "ㅝ"
330 else if (jungseong
== 13 && key
== 24) // "ㅞ"
332 else if (jungseong
== 13 && key
== 32) // "ㅟ"
334 else if (jungseong
== 18 && key
== 32) // "ㅢ"
336 else // If two vowel cannot be double vowel.
338 // Previous character is completed.
339 // Current character is begin with jungseong.
342 korean
+= MergeCode(choseong
, jungseong
, jongseong
);
345 else // Previous character has jungseon only.
346 korean
+= dicJungseong
.at(jungseong
);
348 korean
+= dicKorean
.at(key
);
353 // Process last character
356 if (jungseong
!= -1) // Current character has choseong and jungseong.
357 korean
+= MergeCode(choseong
, jungseong
, jongseong
);
358 else // Current character has choseong only.
359 korean
+= dicChoseong
.at(choseong
);
363 if (jungseong
!= -1) // Current character has jungseong only
364 korean
+= dicJungseong
.at(jungseong
);
365 else if (jongseong
!= -1) // Current character has jongseong only
366 korean
+= dicJongseong
.at(jongseong
);
372 std::string
CInputCodingTableKorean::ConvertString(const std::string
& strCode
)
376 g_charsetConverter
.utf8ToW(strCode
, input
);
377 InputToKorean(input
);
378 g_charsetConverter
.wToUTF8(InputToKorean(input
), result
);
379 return m_strTextPrev
+ result
;