aboutsummaryrefslogtreecommitdiffstats
path: root/src/virtualkeyboard/hangul.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/virtualkeyboard/hangul.cpp')
-rw-r--r--src/virtualkeyboard/hangul.cpp363
1 files changed, 0 insertions, 363 deletions
diff --git a/src/virtualkeyboard/hangul.cpp b/src/virtualkeyboard/hangul.cpp
deleted file mode 100644
index 4410b06f..00000000
--- a/src/virtualkeyboard/hangul.cpp
+++ /dev/null
@@ -1,363 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 or (at your option) any later version
-** approved by the KDE Free Qt Foundation. The licenses are as published by
-** the Free Software Foundation and appearing in the file LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "hangul.h"
-
-namespace QtVirtualKeyboard {
-
-const QList<ushort> Hangul::initials = QList<ushort>()
- << 0x3131 << 0x3132 << 0x3134 << 0x3137 << 0x3138 << 0x3139 << 0x3141
- << 0x3142 << 0x3143 << 0x3145 << 0x3146 << 0x3147 << 0x3148 << 0x3149
- << 0x314A << 0x314B << 0x314C << 0x314D << 0x314E;
-const QList<ushort> Hangul::finals = QList<ushort>()
- << 0x0000 << 0x3131 << 0x3132 << 0x3133 << 0x3134 << 0x3135 << 0x3136
- << 0x3137 << 0x3139 << 0x313A << 0x313B << 0x313C << 0x313D << 0x313E
- << 0x313F << 0x3140 << 0x3141 << 0x3142 << 0x3144 << 0x3145 << 0x3146
- << 0x3147 << 0x3148 << 0x314A << 0x314B << 0x314C << 0x314D << 0x314E;
-const QMap<ushort, Hangul::HangulMedialIndex> Hangul::doubleMedialMap =
- Hangul::initDoubleMedialMap();
-const QMap<ushort, Hangul::HangulFinalIndex> Hangul::doubleFinalMap =
- Hangul::initDoubleFinalMap();
-const int Hangul::SBase = 0xAC00;
-const int Hangul::LBase = 0x1100;
-const int Hangul::VBase = 0x314F;
-const int Hangul::TBase = 0x11A7;
-const int Hangul::LCount = 19;
-const int Hangul::VCount = 21;
-const int Hangul::TCount = 28;
-const int Hangul::NCount = Hangul::VCount * Hangul::TCount; // 588
-const int Hangul::SCount = Hangul::LCount * Hangul::NCount; // 11172
-
-/*!
- \class QtVirtualKeyboard::Hangul
- \internal
-*/
-
-QString Hangul::decompose(const QString &source)
-{
- QString result;
- const int len = source.length();
- for (int i = 0; i < len; i++) {
- QChar ch = source.at(i);
- int SIndex = (int)ch.unicode() - SBase;
- if (SIndex >= 0 && SIndex < SCount) {
-
- // Decompose initial consonant
- result.append(QChar((int)initials[SIndex / NCount]));
-
- // Decompose medial vowel and check if it consists of double Jamo
- int VIndex = (SIndex % NCount) / TCount;
- ushort key = findDoubleMedial((HangulMedialIndex)VIndex);
- if (key) {
- HangulMedialIndex VIndexA, VIndexB;
- unpackDoubleMedial(key, VIndexA, VIndexB);
- result.append(QChar(VBase + (int)VIndexA));
- result.append(QChar(VBase + (int)VIndexB));
- } else {
- result.append(QChar(VBase + VIndex));
- }
-
- // Decompose final consonant and check if it consists of double Jamo
- int TIndex = SIndex % TCount;
- if (TIndex != 0) {
- key = findDoubleFinal((HangulFinalIndex)TIndex);
- if (key) {
- HangulFinalIndex TIndexA, TIndexB;
- unpackDoubleFinal(key, TIndexA, TIndexB);
- result.append(QChar(finals[(int)TIndexA]));
- result.append(QChar(finals[(int)TIndexB]));
- } else {
- result.append(QChar(finals[TIndex]));
- }
- }
- } else {
- result.append(ch);
- }
- }
- return result;
-}
-
-QString Hangul::compose(const QString &source)
-{
- const int len = source.length();
- if (len == 0)
- return QString();
-
- // Always add the initial character into buffer.
- // The last character will serve as the current
- // Hangul Syllable.
- QChar last = source.at(0);
- QString result = QString(last);
-
- // Go through the input buffer starting at next character
- for (int i = 1; i < len; i++) {
- const QChar ch = source.at(i);
-
- // Check to see if the character is Hangul Compatibility Jamo
- const ushort unicode = ch.unicode();
- if (isJamo(unicode)) {
-
- // Check to see if the character is syllable
- const ushort lastUnicode = last.unicode();
- int SIndex = (int)lastUnicode - SBase;
- if (SIndex >= 0 && SIndex < SCount) {
-
- // Check to see if the syllable type is LV or LV+T
- int TIndex = SIndex % TCount;
- if (TIndex == 0) {
-
- // If the current character is final consonant, then
- // make syllable of form LV+T
- TIndex = finals.indexOf(unicode);
- if (TIndex != -1) {
- last = QChar((int)lastUnicode + TIndex);
- result.replace(result.length() - 1, 1, last);
- continue;
- }
-
- // Check to see if the current character is vowel
- HangulMedialIndex VIndexB = (HangulMedialIndex)((int)unicode - VBase);
- if (isMedial(VIndexB)) {
-
- // Some medial Jamos do not exist in the keyboard layout as is.
- // Such Jamos can only be formed by combining the two specific Jamos,
- // aka the double Jamos.
-
- HangulMedialIndex VIndexA = (HangulMedialIndex)((SIndex % NCount) / TCount);
- if (isMedial(VIndexA)) {
-
- // Search the double medial map if such a combination exists
- ushort key = packDoubleMedial(VIndexA, VIndexB);
- const auto it = doubleMedialMap.constFind(key);
- if (it != doubleMedialMap.cend()) {
-
- // Update syllable by adding the difference between
- // the vowels indices
- HangulMedialIndex VIndexD = it.value();
- int VDiff = (int)VIndexD - (int)VIndexA;
- last = QChar((int)lastUnicode + VDiff * TCount);
- result.replace(result.length() - 1, 1, last);
- continue;
- }
- }
- }
-
- } else {
-
- // Check to see if current jamo is vowel
- int VIndex = (int)unicode - VBase;
- if (VIndex >= 0 && VIndex < VCount) {
-
- // Since some initial and final consonants use the same
- // Unicode values, we need to check whether the previous final
- // Jamo is actually an initial Jamo of the next syllable.
- //
- // Consider the following scenario:
- // LVT+V == not possible
- // LV, L+V == possible
- int LIndex = initials.indexOf(finals[TIndex]);
- if (LIndex >= 0 && LIndex < LCount) {
-
- // Remove the previous final jamo from the syllable,
- // making the current syllable of form LV
- last = QChar((int)lastUnicode - TIndex);
- result.replace(result.length() - 1, 1, last);
-
- // Make new syllable of form LV
- last = QChar(SBase + (LIndex * VCount + VIndex) * TCount);
- result.append(last);
- continue;
- }
-
- // Check to see if the current final Jamo is double consonant.
- // In this scenario, the double consonant is split into parts
- // and the second part is removed from the current syllable.
- // Then the second part is joined with the current vowel making
- // the new syllable of form LV.
- ushort key = findDoubleFinal((HangulFinalIndex)TIndex);
- if (key) {
-
- // Split the consonant into two jamos and remove the
- // second jamo B from the current syllable
- HangulFinalIndex TIndexA, TIndexB;
- unpackDoubleFinal(key, TIndexA, TIndexB);
- last = QChar((int)lastUnicode - TIndex + (int)TIndexA);
- result.replace(result.length() - 1, 1, last);
-
- // Add new syllable by combining the initial jamo
- // and the current vowel
- LIndex = initials.indexOf(finals[TIndexB]);
- last = QChar(SBase + (LIndex * VCount + VIndex) * TCount);
- result.append(last);
- continue;
- }
- }
-
- // Check whether the current consonant can connect to current
- // consonant forming a double final consonant
- HangulFinalIndex TIndexA = (HangulFinalIndex)TIndex;
- if (isFinal(TIndexA)) {
-
- HangulFinalIndex TIndexB = (HangulFinalIndex)finals.indexOf(unicode);
- if (isFinal(TIndexB)) {
-
- // Search the double final map if such a combination exists
- ushort key = packDoubleFinal(TIndexA, TIndexB);
- const auto it = doubleFinalMap.constFind(key);
- if (it != doubleFinalMap.cend()) {
-
- // Update syllable by adding the difference between
- // the consonant indices
- HangulFinalIndex TIndexD = it.value();
- int TDiff = (int)TIndexD - (int)TIndexA;
- last = QChar((int)lastUnicode + TDiff);
- result.replace(result.length() - 1, 1, last);
- continue;
- }
- }
- }
- }
-
- } else {
-
- // The last character is not syllable.
- // Check to see if the last character is an initial consonant
- int LIndex = initials.indexOf(lastUnicode);
- if (LIndex != -1) {
-
- // If the current character is medial vowel,
- // make syllable of form LV
- int VIndex = (int)unicode - VBase;
- if (VIndex >= 0 && VIndex < VCount) {
- last = QChar(SBase + (LIndex * VCount + VIndex) * TCount);
- result.replace(result.length() - 1, 1, last);
- continue;
- }
- }
-
- }
- }
-
- // Otherwise, add the character into buffer
- last = ch;
- result = result.append(ch);
- }
- return result;
-}
-
-bool Hangul::isJamo(const ushort &unicode)
-{
- return unicode >= 0x3131 && unicode <= 0x3163;
-}
-
-bool Hangul::isMedial(HangulMedialIndex vowel)
-{
- return vowel >= HANGUL_MEDIAL_A && vowel <= HANGUL_MEDIAL_I;
-}
-
-bool Hangul::isFinal(HangulFinalIndex consonant)
-{
- return consonant >= HANGUL_FINAL_KIYEOK && consonant <= HANGUL_FINAL_HIEUH;
-}
-
-ushort Hangul::findDoubleMedial(HangulMedialIndex vowel)
-{
- return doubleMedialMap.key(vowel, 0);
-}
-
-ushort Hangul::findDoubleFinal(HangulFinalIndex consonant)
-{
- return doubleFinalMap.key(consonant, 0);
-}
-
-// Packs two Hangul Jamo indices into 16-bit integer.
-// The result can be used as a key to the double jamos lookup table.
-// Note: The returned value is not a Unicode character!
-ushort Hangul::packDoubleMedial(HangulMedialIndex a, HangulMedialIndex b)
-{
- Q_ASSERT(isMedial(a));
- Q_ASSERT(isMedial(b));
- return (ushort)a | ((ushort)b << 8);
-}
-
-ushort Hangul::packDoubleFinal(HangulFinalIndex a, HangulFinalIndex b)
-{
- Q_ASSERT(isFinal(a));
- Q_ASSERT(isFinal(b));
- return (ushort)a | ((ushort)b << 8);
-}
-
-void Hangul::unpackDoubleMedial(ushort key, HangulMedialIndex &a, HangulMedialIndex &b)
-{
- a = (HangulMedialIndex)(key & 0xFF);
- b = (HangulMedialIndex)(key >> 8);
- Q_ASSERT(isMedial(a));
- Q_ASSERT(isMedial(b));
-}
-
-void Hangul::unpackDoubleFinal(ushort key, HangulFinalIndex &a, HangulFinalIndex &b)
-{
- a = (HangulFinalIndex)(key & 0xFF);
- b = (HangulFinalIndex)(key >> 8);
- Q_ASSERT(isFinal(a));
- Q_ASSERT(isFinal(b));
-}
-
-QMap<ushort, Hangul::HangulMedialIndex> Hangul::initDoubleMedialMap()
-{
- QMap<ushort, HangulMedialIndex> map;
- map.insert(packDoubleMedial(HANGUL_MEDIAL_O, HANGUL_MEDIAL_A), HANGUL_MEDIAL_WA);
- map.insert(packDoubleMedial(HANGUL_MEDIAL_O, HANGUL_MEDIAL_AE), HANGUL_MEDIAL_WAE);
- map.insert(packDoubleMedial(HANGUL_MEDIAL_O, HANGUL_MEDIAL_I), HANGUL_MEDIAL_OE);
- map.insert(packDoubleMedial(HANGUL_MEDIAL_U, HANGUL_MEDIAL_EO), HANGUL_MEDIAL_WEO);
- map.insert(packDoubleMedial(HANGUL_MEDIAL_U, HANGUL_MEDIAL_E), HANGUL_MEDIAL_WE);
- map.insert(packDoubleMedial(HANGUL_MEDIAL_U, HANGUL_MEDIAL_I), HANGUL_MEDIAL_WI);
- map.insert(packDoubleMedial(HANGUL_MEDIAL_EU, HANGUL_MEDIAL_I), HANGUL_MEDIAL_YI);
- return map;
-}
-
-QMap<ushort, Hangul::HangulFinalIndex> Hangul::initDoubleFinalMap()
-{
- QMap<ushort, HangulFinalIndex> map;
- map.insert(packDoubleFinal(HANGUL_FINAL_KIYEOK, HANGUL_FINAL_SIOS), HANGUL_FINAL_KIYEOK_SIOS);
- map.insert(packDoubleFinal(HANGUL_FINAL_NIEUN, HANGUL_FINAL_CIEUC), HANGUL_FINAL_NIEUN_CIEUC);
- map.insert(packDoubleFinal(HANGUL_FINAL_NIEUN, HANGUL_FINAL_HIEUH), HANGUL_FINAL_NIEUN_HIEUH);
- map.insert(packDoubleFinal(HANGUL_FINAL_RIEUL, HANGUL_FINAL_KIYEOK), HANGUL_FINAL_RIEUL_KIYEOK);
- map.insert(packDoubleFinal(HANGUL_FINAL_RIEUL, HANGUL_FINAL_MIEUM), HANGUL_FINAL_RIEUL_MIEUM);
- map.insert(packDoubleFinal(HANGUL_FINAL_RIEUL, HANGUL_FINAL_PIEUP), HANGUL_FINAL_RIEUL_PIEUP);
- map.insert(packDoubleFinal(HANGUL_FINAL_RIEUL, HANGUL_FINAL_SIOS), HANGUL_FINAL_RIEUL_SIOS);
- map.insert(packDoubleFinal(HANGUL_FINAL_RIEUL, HANGUL_FINAL_THIEUTH), HANGUL_FINAL_RIEUL_THIEUTH);
- map.insert(packDoubleFinal(HANGUL_FINAL_RIEUL, HANGUL_FINAL_PHIEUPH), HANGUL_FINAL_RIEUL_PHIEUPH);
- map.insert(packDoubleFinal(HANGUL_FINAL_RIEUL, HANGUL_FINAL_HIEUH), HANGUL_FINAL_RIEUL_HIEUH);
- map.insert(packDoubleFinal(HANGUL_FINAL_PIEUP, HANGUL_FINAL_SIOS), HANGUL_FINAL_PIEUP_SIOS);
- map.insert(packDoubleFinal(HANGUL_FINAL_SIOS, HANGUL_FINAL_SIOS), HANGUL_FINAL_SSANGSIOS);
- return map;
-}
-
-} // namespace QtVirtualKeyboard