File indexing completed on 2024-05-05 05:53:43

0001 /*
0002     SPDX-FileCopyrightText: 2022 Luis Javier Merino MorĂ¡n <ninjalj@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 // Own
0008 #include "Hangul.h"
0009 
0010 // Qt
0011 
0012 // Konsole
0013 #include "Character.h"
0014 
0015 namespace Konsole
0016 {
0017 
0018 int Hangul::width(uint c, int widthFromTable, enum Hangul::SyllablePos &syllablePos)
0019 {
0020     int w = 0;
0021     switch (syllablePos) {
0022     case NotInSyllable:
0023         if (isLeadingJamo(c)) {
0024             // new Hangul syllable
0025             syllablePos = AtLeadingJamo;
0026             w += widthFromTable;
0027         } else if (isLvSyllable(c)) {
0028             // new Hangul syllable
0029             syllablePos = AtVowelJamo;
0030             w += widthFromTable;
0031         } else if (isLvtSyllable(c)) {
0032             // new Hangul syllable
0033             syllablePos = AtTrailingJamo;
0034             w += widthFromTable;
0035         } else if (isVowelJamo(c)) {
0036             // invalid here, isolated Jamo
0037             w += 2;
0038         } else if (isTrailingJamo(c)) {
0039             // invalid here, isolated Jamo
0040             w += 2;
0041         }
0042         break;
0043     case AtLeadingJamo:
0044         if (isLeadingJamo(c)) {
0045             // conjoin
0046         } else if (isLvSyllable(c)) {
0047             // new Hangul syllable
0048             syllablePos = AtVowelJamo;
0049             w += widthFromTable;
0050         } else if (isLvtSyllable(c)) {
0051             // new Hangul syllable
0052             syllablePos = AtTrailingJamo;
0053             w += widthFromTable;
0054         } else if (isVowelJamo(c)) {
0055             syllablePos = AtVowelJamo;
0056             // conjoin
0057         } else if (isTrailingJamo(c)) {
0058             // invalid here, isolated Jamo
0059             syllablePos = NotInSyllable;
0060             w += 2;
0061         }
0062         break;
0063     case AtVowelJamo:
0064         if (isLeadingJamo(c)) {
0065             // new Hangul syllable
0066             syllablePos = AtLeadingJamo;
0067             w += widthFromTable;
0068         } else if (isLvSyllable(c)) {
0069             // new Hangul syllable
0070             syllablePos = AtVowelJamo;
0071             w += widthFromTable;
0072         } else if (isLvtSyllable(c)) {
0073             // new Hangul syllable
0074             syllablePos = AtTrailingJamo;
0075             w += widthFromTable;
0076         } else if (isVowelJamo(c)) {
0077             // conjoin
0078         } else if (isTrailingJamo(c)) {
0079             syllablePos = AtTrailingJamo;
0080             // conjoin
0081         }
0082         break;
0083     case AtTrailingJamo:
0084         if (isLeadingJamo(c)) {
0085             // new Hangul syllable
0086             syllablePos = AtLeadingJamo;
0087             w += widthFromTable;
0088         } else if (isLvSyllable(c)) {
0089             // new Hangul syllable
0090             syllablePos = AtVowelJamo;
0091             w += widthFromTable;
0092         } else if (isLvtSyllable(c)) {
0093             // new Hangul syllable
0094             syllablePos = AtTrailingJamo;
0095             w += widthFromTable;
0096         } else if (isVowelJamo(c)) {
0097             // invalid here, isolated Jamo
0098             syllablePos = NotInSyllable;
0099             w += 2;
0100         } else if (isTrailingJamo(c)) {
0101             // conjoin
0102         }
0103     }
0104 
0105     return w;
0106 }
0107 
0108 void Hangul::updateHangulSyllablePos(Hangul::SyllablePos &syllablePos, uint c)
0109 {
0110     if (!isHangul(c)) {
0111         syllablePos = NotInSyllable;
0112     }
0113     (void)Hangul::width(c, 0, syllablePos);
0114 }
0115 
0116 bool Hangul::validSyllableContinuation(Hangul::SyllablePos syllablePos, uint c)
0117 {
0118     SyllableType type = jamoType(c);
0119 
0120     switch (syllablePos) {
0121     case AtLeadingJamo:
0122         return type != Trailing_Jamo && type != Not_Applicable;
0123     case AtVowelJamo:
0124         return type == Trailing_Jamo || type == Vowel_Jamo;
0125     case AtTrailingJamo:
0126         return type == Trailing_Jamo;
0127     default:
0128         return false;
0129     }
0130 }
0131 
0132 bool Hangul::combinesWith(Character prevChar, uint c)
0133 {
0134     Hangul::SyllablePos syllablePos = Hangul::NotInSyllable;
0135 
0136     if (prevChar.rendition.f.extended == 0) {
0137         const uint prev = prevChar.character;
0138         updateHangulSyllablePos(syllablePos, prev);
0139     } else {
0140         ushort extendedCharLength;
0141         const char32_t *oldChars = ExtendedCharTable::instance.lookupExtendedChar(prevChar.character, extendedCharLength);
0142         if (oldChars == nullptr) {
0143             return false;
0144         } else {
0145             for (int i = 0; i < extendedCharLength; i++) {
0146                 updateHangulSyllablePos(syllablePos, oldChars[i]);
0147             }
0148         }
0149     }
0150 
0151     return validSyllableContinuation(syllablePos, c);
0152 }
0153 
0154 }