Skip to content

Commit cfad5a0

Browse files
committed
Allow enforcing CSVT ordering with failure report.
1 parent 53bfd4f commit cfad5a0

2 files changed

Lines changed: 44 additions & 15 deletions

File tree

Sources/Tekkon/include/Tekkon.hh

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,6 +1718,13 @@ class Composer {
17181718
/// 是否對錯誤的注音讀音組合做出自動糾正處理。
17191719
bool phonabetCombinationCorrectionEnabled;
17201720

1721+
/// 是否嚴格要求按照聲介韻調(consonant→semivowel→vowel→intonation)順序輸入。
1722+
/// 啟用後,若 phonabet 要填入的 slot 比目前已填的最大 slot 更早(例如 vowel
1723+
/// 已填而 semivowel 後到), 則該 phonabet
1724+
/// 會被拒絕。聲調(intonation)永遠允許。
1725+
/// 此特性僅供部分特殊場合使用,等同於停用並擊特性。
1726+
bool enforceCSVTOrdering = false;
1727+
17211728
// MARK: Private
17221729

17231730
/// 追蹤 romajiBuffer 是否需要從聲介韻重建。
@@ -1937,10 +1944,10 @@ class Composer {
19371944
/// 如果是諸如複合型注音排列的話,翻譯結果有可能為空,但翻譯過程已經處理好聲介韻調分配了。
19381945
///
19391946
/// @param input 傳入的 String 內容。
1940-
void receiveKey(std::string input) {
1947+
/// @return 若按鍵被接受則為 true,被拒絕則為 false。
1948+
bool receiveKey(std::string input) {
19411949
if (!isPinyinMode()) {
1942-
receiveKeyFromPhonabet(translate(input));
1943-
return;
1950+
return receiveKeyFromPhonabet(translate(input));
19441951
}
19451952
int maxCount;
19461953
if (mapArayuruPinyinIntonation.count(input)) {
@@ -1959,6 +1966,7 @@ class Composer {
19591966
romajiBuffer = romajiBufferBackup;
19601967
_needsRomajiUpdate = false;
19611968
}
1969+
return true;
19621970
}
19631971

19641972
/// 接受傳入的按鍵訊號時的處理,處理對象為 UniChar。
@@ -1967,7 +1975,8 @@ class Composer {
19671975
/// 如果是諸如複合型注音排列的話,翻譯結果有可能為空,但翻譯過程已經處理好聲介韻調分配了。
19681976
///
19691977
/// @param input 傳入的 UniChar 內容。
1970-
void receiveKey(char input) { receiveKey((charToString(input))); };
1978+
/// @return 若按鍵被接受則為 true,被拒絕則為 false。
1979+
bool receiveKey(char input) { return receiveKey((charToString(input))); };
19711980

19721981
/// 接受傳入的按鍵訊號時的處理,處理對象為單個注音符號。
19731982
/// 主要就是將注音符號拆分辨識且分配到正確的貯存位置而已。
@@ -1977,7 +1986,8 @@ class Composer {
19771986
/// 主要就是將注音符號拆分辨識且分配到正確的貯存位置而已。
19781987
///
19791988
/// @param phonabet 傳入的單個注音符號 Unicode scalar。
1980-
void receiveKeyFromPhonabet(char32_t phonabet) {
1989+
/// @return 若按鍵被接受則為 true,被拒絕則為 false。
1990+
bool receiveKeyFromPhonabet(char32_t phonabet) {
19811991
Phonabet thePhone = Phonabet(phonabet);
19821992
if (phonabetCombinationCorrectionEnabled) {
19831993
switch (phonabet) {
@@ -2056,6 +2066,21 @@ class Composer {
20562066
}
20572067
}
20582068

2069+
// 個別情形需強制聲介韻調的輸入順序。
2070+
if (enforceCSVTOrdering) {
2071+
int newSlot = static_cast<int>(
2072+
thePhone.type); // 1=consonant, 2=semivowel, 3=vowel, 4=intonation
2073+
int maxFilledSlot = std::max({
2074+
intonation.isEmpty() ? 0 : static_cast<int>(PhoneType::intonation),
2075+
vowel.isEmpty() ? 0 : static_cast<int>(PhoneType::vowel),
2076+
semivowel.isEmpty() ? 0 : static_cast<int>(PhoneType::semivowel),
2077+
consonant.isEmpty() ? 0 : static_cast<int>(PhoneType::consonant),
2078+
});
2079+
if (newSlot != static_cast<int>(PhoneType::intonation) &&
2080+
newSlot < maxFilledSlot)
2081+
return false;
2082+
}
2083+
20592084
switch (thePhone.type) {
20602085
case PhoneType::consonant:
20612086
consonant = thePhone;
@@ -2073,14 +2098,16 @@ class Composer {
20732098
break;
20742099
}
20752100
updateRomajiBuffer();
2101+
return true;
20762102
}
20772103

20782104
/// 接受傳入的按鍵訊號時的處理,處理對象為單個注音符號(字串版本,為了向後兼容)。
20792105
/// 主要就是將注音符號拆分辨識且分配到正確的貯存位置而已。
20802106
///
20812107
/// @param phonabet 傳入的單個注音符號字串。
2082-
void receiveKeyFromPhonabet(std::string phonabet = "") {
2083-
if (phonabet.empty()) return;
2108+
/// @return 若按鍵被接受則為 true,被拒絕則為 false。
2109+
bool receiveKeyFromPhonabet(std::string phonabet = "") {
2110+
if (phonabet.empty()) return true;
20842111
// Convert first character to char32_t and call the scalar version
20852112
auto chars = splitByCodepoint(phonabet);
20862113
if (!chars.empty()) {
@@ -2101,10 +2128,11 @@ class Composer {
21012128
((bytes[2] & 0x3F) << 6) | (bytes[3] & 0x3F);
21022129
}
21032130
if (scalar != 0) {
2104-
receiveKeyFromPhonabet(scalar);
2131+
return receiveKeyFromPhonabet(scalar);
21052132
}
21062133
}
21072134
}
2135+
return false;
21082136
}
21092137

21102138
/// 處理一連串的按鍵輸入、且返回被處理之後的注音(陰平為空格)。
@@ -2115,8 +2143,9 @@ class Composer {
21152143
bool isRomaji = false) {
21162144
clear();
21172145
if (!isRomaji) {
2146+
// 使用 for 迴圈,以利 enforceCSVTOrdering 拒絕時提前終止。
21182147
for (char key : givenSequence) {
2119-
receiveKey(key);
2148+
if (!receiveKey(key)) break;
21202149
}
21212150
return value();
21222151
}

utils/unittest/googletest/src/gtest-port.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,13 @@ size_t GetThreadCount() {
160160
// we cannot detect it.
161161
size_t GetThreadCount() {
162162
int mib[] = {
163-
CTL_KERN,
164-
KERN_PROC,
165-
KERN_PROC_PID,
166-
getpid(),
163+
CTL_KERN,
164+
KERN_PROC,
165+
KERN_PROC_PID,
166+
getpid(),
167167
#if GTEST_OS_NETBSD
168-
sizeof(struct kinfo_proc),
169-
1,
168+
sizeof(struct kinfo_proc),
169+
1,
170170
#endif
171171
};
172172
u_int miblen = sizeof(mib) / sizeof(mib[0]);

0 commit comments

Comments
 (0)