Reformat with clang-format
This commit is contained in:
parent
4ebe1a1a11
commit
71b69cae50
File diff suppressed because it is too large
Load Diff
|
@ -29,9 +29,9 @@
|
|||
#define Mandarin_h
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace Formosa {
|
||||
namespace Mandarin {
|
||||
|
@ -40,32 +40,26 @@ namespace Formosa {
|
|||
class BopomofoSyllable {
|
||||
public:
|
||||
typedef unsigned int Component;
|
||||
BopomofoSyllable(Component syllable = 0)
|
||||
: m_syllable(syllable)
|
||||
{
|
||||
}
|
||||
BopomofoSyllable(Component syllable = 0) : m_syllable(syllable) {}
|
||||
|
||||
BopomofoSyllable(const BopomofoSyllable& another)
|
||||
: m_syllable(another.m_syllable)
|
||||
{
|
||||
}
|
||||
: m_syllable(another.m_syllable) {}
|
||||
|
||||
~BopomofoSyllable()
|
||||
{
|
||||
}
|
||||
~BopomofoSyllable() {}
|
||||
|
||||
BopomofoSyllable& operator=(const BopomofoSyllable& another)
|
||||
{
|
||||
BopomofoSyllable& operator=(const BopomofoSyllable& another) {
|
||||
m_syllable = another.m_syllable;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// takes the ASCII-form, "v"-tolerant, TW-style Hanyu Pinyin (fong, pong, bong acceptable)
|
||||
// takes the ASCII-form, "v"-tolerant, TW-style Hanyu Pinyin (fong, pong, bong
|
||||
// acceptable)
|
||||
static const BopomofoSyllable FromHanyuPinyin(const string& str);
|
||||
|
||||
// TO DO: Support accented vowels
|
||||
const string HanyuPinyinString(bool includesTone, bool useVForUUmlaut) const;
|
||||
// const string HanyuPinyinString(bool includesTone, bool useVForUUmlaut, bool composeAccentedVowel) const;
|
||||
// const string HanyuPinyinString(bool includesTone, bool useVForUUmlaut, bool
|
||||
// composeAccentedVowel) const;
|
||||
|
||||
// PHT = Pai-hua-tsi
|
||||
static const BopomofoSyllable FromPHT(const string& str);
|
||||
|
@ -74,88 +68,55 @@ namespace Formosa {
|
|||
static const BopomofoSyllable FromComposedString(const string& str);
|
||||
const string composedString() const;
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_syllable = 0;
|
||||
}
|
||||
void clear() { m_syllable = 0; }
|
||||
|
||||
bool isEmpty() const
|
||||
{
|
||||
return !m_syllable;
|
||||
}
|
||||
bool isEmpty() const { return !m_syllable; }
|
||||
|
||||
bool hasConsonant() const
|
||||
{
|
||||
return !!(m_syllable & ConsonantMask);
|
||||
}
|
||||
bool hasConsonant() const { return !!(m_syllable & ConsonantMask); }
|
||||
|
||||
bool hasMiddleVowel() const
|
||||
{
|
||||
return !!(m_syllable & MiddleVowelMask);
|
||||
}
|
||||
bool hasVowel() const
|
||||
{
|
||||
return !!(m_syllable & VowelMask);
|
||||
}
|
||||
bool hasMiddleVowel() const { return !!(m_syllable & MiddleVowelMask); }
|
||||
bool hasVowel() const { return !!(m_syllable & VowelMask); }
|
||||
|
||||
bool hasToneMarker() const
|
||||
{
|
||||
return !!(m_syllable & ToneMarkerMask);
|
||||
}
|
||||
bool hasToneMarker() const { return !!(m_syllable & ToneMarkerMask); }
|
||||
|
||||
Component consonantComponent() const
|
||||
{
|
||||
return m_syllable & ConsonantMask;
|
||||
}
|
||||
Component consonantComponent() const { return m_syllable & ConsonantMask; }
|
||||
|
||||
Component middleVowelComponent() const
|
||||
{
|
||||
Component middleVowelComponent() const {
|
||||
return m_syllable & MiddleVowelMask;
|
||||
}
|
||||
|
||||
Component vowelComponent() const
|
||||
{
|
||||
return m_syllable & VowelMask;
|
||||
}
|
||||
Component vowelComponent() const { return m_syllable & VowelMask; }
|
||||
|
||||
Component toneMarkerComponent() const
|
||||
{
|
||||
return m_syllable & ToneMarkerMask;
|
||||
}
|
||||
Component toneMarkerComponent() const { return m_syllable & ToneMarkerMask; }
|
||||
|
||||
bool operator==(const BopomofoSyllable& another) const
|
||||
{
|
||||
bool operator==(const BopomofoSyllable& another) const {
|
||||
return m_syllable == another.m_syllable;
|
||||
}
|
||||
|
||||
bool operator!=(const BopomofoSyllable& another) const
|
||||
{
|
||||
bool operator!=(const BopomofoSyllable& another) const {
|
||||
return m_syllable != another.m_syllable;
|
||||
}
|
||||
|
||||
bool isOverlappingWith(const BopomofoSyllable& another) const
|
||||
{
|
||||
bool isOverlappingWith(const BopomofoSyllable& another) const {
|
||||
#define IOW_SAND(mask) ((m_syllable & mask) && (another.m_syllable & mask))
|
||||
return IOW_SAND(ConsonantMask) || IOW_SAND(MiddleVowelMask) || IOW_SAND(VowelMask) || IOW_SAND(ToneMarkerMask);
|
||||
return IOW_SAND(ConsonantMask) || IOW_SAND(MiddleVowelMask) ||
|
||||
IOW_SAND(VowelMask) || IOW_SAND(ToneMarkerMask);
|
||||
#undef IOW_SAND
|
||||
}
|
||||
|
||||
// consonants J, Q, X all require the existence of vowel I or UE
|
||||
bool belongsToJQXClass() const
|
||||
{
|
||||
bool belongsToJQXClass() const {
|
||||
Component consonant = m_syllable & ConsonantMask;
|
||||
return (consonant == J || consonant == Q || consonant == X);
|
||||
}
|
||||
|
||||
// zi, ci, si, chi, chi, shi, ri
|
||||
bool belongsToZCSRClass() const
|
||||
{
|
||||
bool belongsToZCSRClass() const {
|
||||
Component consonant = m_syllable & ConsonantMask;
|
||||
return (consonant >= ZH && consonant <= S);
|
||||
}
|
||||
|
||||
Component maskType() const
|
||||
{
|
||||
Component maskType() const {
|
||||
Component mask = 0;
|
||||
mask |= (m_syllable & ConsonantMask) ? ConsonantMask : 0;
|
||||
mask |= (m_syllable & MiddleVowelMask) ? MiddleVowelMask : 0;
|
||||
|
@ -164,10 +125,11 @@ namespace Formosa {
|
|||
return mask;
|
||||
}
|
||||
|
||||
const BopomofoSyllable operator+(const BopomofoSyllable& another) const
|
||||
{
|
||||
const BopomofoSyllable operator+(const BopomofoSyllable& another) const {
|
||||
Component newSyllable = m_syllable;
|
||||
#define OP_SOVER(mask) if (another.m_syllable & mask) newSyllable = (newSyllable & ~mask) | (another.m_syllable & mask)
|
||||
#define OP_SOVER(mask) \
|
||||
if (another.m_syllable & mask) \
|
||||
newSyllable = (newSyllable & ~mask) | (another.m_syllable & mask)
|
||||
OP_SOVER(ConsonantMask);
|
||||
OP_SOVER(MiddleVowelMask);
|
||||
OP_SOVER(VowelMask);
|
||||
|
@ -176,9 +138,10 @@ namespace Formosa {
|
|||
return BopomofoSyllable(newSyllable);
|
||||
}
|
||||
|
||||
BopomofoSyllable& operator+=(const BopomofoSyllable& another)
|
||||
{
|
||||
#define OPE_SOVER(mask) if (another.m_syllable & mask) m_syllable = (m_syllable & ~mask) | (another.m_syllable & mask)
|
||||
BopomofoSyllable& operator+=(const BopomofoSyllable& another) {
|
||||
#define OPE_SOVER(mask) \
|
||||
if (another.m_syllable & mask) \
|
||||
m_syllable = (m_syllable & ~mask) | (another.m_syllable & mask)
|
||||
OPE_SOVER(ConsonantMask);
|
||||
OPE_SOVER(MiddleVowelMask);
|
||||
OPE_SOVER(VowelMask);
|
||||
|
@ -187,8 +150,7 @@ namespace Formosa {
|
|||
return *this;
|
||||
}
|
||||
|
||||
short absoluteOrder() const
|
||||
{
|
||||
short absoluteOrder() const {
|
||||
// turn BPMF syllable into a 4*14*4*22 number
|
||||
return (short)(m_syllable & ConsonantMask) +
|
||||
(short)((m_syllable & MiddleVowelMask) >> 5) * 22 +
|
||||
|
@ -196,8 +158,7 @@ namespace Formosa {
|
|||
(short)((m_syllable & ToneMarkerMask) >> 11) * 22 * 4 * 14;
|
||||
}
|
||||
|
||||
const string absoluteOrderString() const
|
||||
{
|
||||
const string absoluteOrderString() const {
|
||||
// 5*14*4*22 = 6160, we use a 79*79 encoding to represent that
|
||||
short order = absoluteOrder();
|
||||
char low = 48 + (char)(order % 79);
|
||||
|
@ -208,20 +169,14 @@ namespace Formosa {
|
|||
return result;
|
||||
}
|
||||
|
||||
static BopomofoSyllable FromAbsoluteOrder(short order)
|
||||
{
|
||||
return BopomofoSyllable(
|
||||
(order % 22) |
|
||||
((order / 22) % 4) << 5 |
|
||||
static BopomofoSyllable FromAbsoluteOrder(short order) {
|
||||
return BopomofoSyllable((order % 22) | ((order / 22) % 4) << 5 |
|
||||
((order / (22 * 4)) % 14) << 7 |
|
||||
((order / (22 * 4 * 14)) % 5) << 11
|
||||
);
|
||||
((order / (22 * 4 * 14)) % 5) << 11);
|
||||
}
|
||||
|
||||
static BopomofoSyllable FromAbsoluteOrderString(const string& str)
|
||||
{
|
||||
if (str.length() != 2)
|
||||
return BopomofoSyllable();
|
||||
static BopomofoSyllable FromAbsoluteOrderString(const string& str) {
|
||||
if (str.length() != 2) return BopomofoSyllable();
|
||||
|
||||
return FromAbsoluteOrder((short)(str[1] - 48) * 79 + (short)(str[0] - 48));
|
||||
}
|
||||
|
@ -233,25 +188,22 @@ namespace Formosa {
|
|||
MiddleVowelMask = 0x0060, // 0000 0000 0110 0000, 3 middle vowels
|
||||
VowelMask = 0x0780, // 0000 0111 1000 0000, 13 vowels
|
||||
ToneMarkerMask = 0x3800, // 0011 1000 0000 0000, 5 tones (tone1 = 0x00)
|
||||
B = 0x0001, P = 0x0002, M = 0x0003, F = 0x0004,
|
||||
D = 0x0005, T = 0x0006, N = 0x0007, L = 0x0008,
|
||||
G = 0x0009, K = 0x000a, H = 0x000b,
|
||||
J = 0x000c, Q = 0x000d, X = 0x000e,
|
||||
ZH = 0x000f, CH = 0x0010, SH = 0x0011, R = 0x0012,
|
||||
Z = 0x0013, C = 0x0014, S = 0x0015,
|
||||
I = 0x0020, U = 0x0040, UE = 0x0060, // ue = u umlaut (we use the German convention here as an ersatz to the /ju:/ sound)
|
||||
A = 0x0080, O = 0x0100, ER = 0x0180, E = 0x0200,
|
||||
AI = 0x0280, EI = 0x0300, AO = 0x0380, OU = 0x0400,
|
||||
AN = 0x0480, EN = 0x0500, ANG = 0x0580, ENG = 0x0600,
|
||||
ERR = 0x0680,
|
||||
Tone1 = 0x0000, Tone2 = 0x0800, Tone3 = 0x1000, Tone4 = 0x1800, Tone5 = 0x2000;
|
||||
B = 0x0001, P = 0x0002, M = 0x0003, F = 0x0004, D = 0x0005, T = 0x0006,
|
||||
N = 0x0007, L = 0x0008, G = 0x0009, K = 0x000a, H = 0x000b, J = 0x000c,
|
||||
Q = 0x000d, X = 0x000e, ZH = 0x000f, CH = 0x0010, SH = 0x0011, R = 0x0012,
|
||||
Z = 0x0013, C = 0x0014, S = 0x0015, I = 0x0020, U = 0x0040,
|
||||
UE = 0x0060, // ue = u umlaut (we use the German convention here as an
|
||||
// ersatz to the /ju:/ sound)
|
||||
A = 0x0080, O = 0x0100, ER = 0x0180, E = 0x0200, AI = 0x0280, EI = 0x0300,
|
||||
AO = 0x0380, OU = 0x0400, AN = 0x0480, EN = 0x0500, ANG = 0x0580,
|
||||
ENG = 0x0600, ERR = 0x0680, Tone1 = 0x0000, Tone2 = 0x0800,
|
||||
Tone3 = 0x1000, Tone4 = 0x1800, Tone5 = 0x2000;
|
||||
|
||||
protected:
|
||||
Component m_syllable;
|
||||
};
|
||||
|
||||
inline ostream& operator<<(ostream& stream, const BopomofoSyllable& syllable)
|
||||
{
|
||||
inline ostream& operator<<(ostream& stream, const BopomofoSyllable& syllable) {
|
||||
stream << syllable.composedString();
|
||||
return stream;
|
||||
}
|
||||
|
@ -271,39 +223,41 @@ namespace Formosa {
|
|||
static const BopomofoKeyboardLayout* IBMLayout();
|
||||
static const BopomofoKeyboardLayout* HanyuPinyinLayout();
|
||||
|
||||
BopomofoKeyboardLayout(const BopomofoKeyToComponentMap& ktcm, const string& name)
|
||||
: m_keyToComponent(ktcm)
|
||||
, m_name(name)
|
||||
{
|
||||
for (BopomofoKeyToComponentMap::const_iterator miter = m_keyToComponent.begin() ; miter != m_keyToComponent.end() ; ++miter)
|
||||
for (vector<BPMF::Component>::const_iterator viter = (*miter).second.begin() ; viter != (*miter).second.end() ; ++viter)
|
||||
BopomofoKeyboardLayout(const BopomofoKeyToComponentMap& ktcm,
|
||||
const string& name)
|
||||
: m_keyToComponent(ktcm), m_name(name) {
|
||||
for (BopomofoKeyToComponentMap::const_iterator miter =
|
||||
m_keyToComponent.begin();
|
||||
miter != m_keyToComponent.end(); ++miter)
|
||||
for (vector<BPMF::Component>::const_iterator viter =
|
||||
(*miter).second.begin();
|
||||
viter != (*miter).second.end(); ++viter)
|
||||
m_componentToKey[*viter] = (*miter).first;
|
||||
}
|
||||
|
||||
const string name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
const string name() const { return m_name; }
|
||||
|
||||
char componentToKey(BPMF::Component component) const
|
||||
{
|
||||
BopomofoComponentToKeyMap::const_iterator iter = m_componentToKey.find(component);
|
||||
char componentToKey(BPMF::Component component) const {
|
||||
BopomofoComponentToKeyMap::const_iterator iter =
|
||||
m_componentToKey.find(component);
|
||||
return (iter == m_componentToKey.end()) ? 0 : (*iter).second;
|
||||
}
|
||||
|
||||
const vector<BPMF::Component> keyToComponents(char key) const
|
||||
{
|
||||
const vector<BPMF::Component> keyToComponents(char key) const {
|
||||
BopomofoKeyToComponentMap::const_iterator iter = m_keyToComponent.find(key);
|
||||
return (iter == m_keyToComponent.end()) ? vector<BPMF::Component>() : (*iter).second;
|
||||
return (iter == m_keyToComponent.end()) ? vector<BPMF::Component>()
|
||||
: (*iter).second;
|
||||
}
|
||||
|
||||
const string keySequenceFromSyllable(BPMF syllable) const
|
||||
{
|
||||
const string keySequenceFromSyllable(BPMF syllable) const {
|
||||
string sequence;
|
||||
|
||||
BPMF::Component c;
|
||||
char k;
|
||||
#define STKS_COMBINE(component) if ((c = component)) { if ((k = componentToKey(c))) sequence += string(1, k); }
|
||||
#define STKS_COMBINE(component) \
|
||||
if ((c = component)) { \
|
||||
if ((k = componentToKey(c))) sequence += string(1, k); \
|
||||
}
|
||||
STKS_COMBINE(syllable.consonantComponent());
|
||||
STKS_COMBINE(syllable.middleVowelComponent());
|
||||
STKS_COMBINE(syllable.vowelComponent());
|
||||
|
@ -312,19 +266,17 @@ namespace Formosa {
|
|||
return sequence;
|
||||
}
|
||||
|
||||
const BPMF syllableFromKeySequence(const string& sequence) const
|
||||
{
|
||||
const BPMF syllableFromKeySequence(const string& sequence) const {
|
||||
BPMF syllable;
|
||||
|
||||
for (string::const_iterator iter = sequence.begin() ; iter != sequence.end() ; ++iter)
|
||||
{
|
||||
for (string::const_iterator iter = sequence.begin(); iter != sequence.end();
|
||||
++iter) {
|
||||
bool beforeSeqHasIorUE = sequenceContainsIorUE(sequence.begin(), iter);
|
||||
bool aheadSeqHasIorUE = sequenceContainsIorUE(iter + 1, sequence.end());
|
||||
|
||||
vector<BPMF::Component> components = keyToComponents(*iter);
|
||||
|
||||
if (!components.size())
|
||||
continue;
|
||||
if (!components.size()) continue;
|
||||
|
||||
if (components.size() == 1) {
|
||||
syllable += BPMF(components[0]);
|
||||
|
@ -336,25 +288,24 @@ namespace Formosa {
|
|||
BPMF ending = components.size() > 2 ? BPMF(components[2]) : follow;
|
||||
|
||||
// apply the I/UE + E rule
|
||||
if (head.vowelComponent() == BPMF::E && follow.vowelComponent() != BPMF::E)
|
||||
{
|
||||
if (head.vowelComponent() == BPMF::E &&
|
||||
follow.vowelComponent() != BPMF::E) {
|
||||
syllable += beforeSeqHasIorUE ? head : follow;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (head.vowelComponent() != BPMF::E && follow.vowelComponent() == BPMF::E)
|
||||
{
|
||||
if (head.vowelComponent() != BPMF::E &&
|
||||
follow.vowelComponent() == BPMF::E) {
|
||||
syllable += beforeSeqHasIorUE ? follow : head;
|
||||
continue;
|
||||
}
|
||||
|
||||
// apply the J/Q/X + I/UE rule, only two components are allowed in the components vector here
|
||||
// apply the J/Q/X + I/UE rule, only two components are allowed in the
|
||||
// components vector here
|
||||
if (head.belongsToJQXClass() && !follow.belongsToJQXClass()) {
|
||||
if (!syllable.isEmpty()) {
|
||||
if (ending != follow)
|
||||
syllable += ending;
|
||||
}
|
||||
else {
|
||||
if (ending != follow) syllable += ending;
|
||||
} else {
|
||||
syllable += aheadSeqHasIorUE ? head : follow;
|
||||
}
|
||||
|
||||
|
@ -363,10 +314,8 @@ namespace Formosa {
|
|||
|
||||
if (!head.belongsToJQXClass() && follow.belongsToJQXClass()) {
|
||||
if (!syllable.isEmpty()) {
|
||||
if (ending != follow)
|
||||
syllable += ending;
|
||||
}
|
||||
else {
|
||||
if (ending != follow) syllable += ending;
|
||||
} else {
|
||||
syllable += aheadSeqHasIorUE ? follow : head;
|
||||
}
|
||||
|
||||
|
@ -375,7 +324,8 @@ namespace Formosa {
|
|||
|
||||
// the nasty issue of only one char in the buffer
|
||||
if (iter == sequence.begin() && iter + 1 == sequence.end()) {
|
||||
if (head.hasVowel() || follow.hasToneMarker() || head.belongsToZCSRClass())
|
||||
if (head.hasVowel() || follow.hasToneMarker() ||
|
||||
head.belongsToZCSRClass())
|
||||
syllable += head;
|
||||
else {
|
||||
if (follow.hasVowel() || ending.hasToneMarker())
|
||||
|
@ -384,21 +334,19 @@ namespace Formosa {
|
|||
syllable += ending;
|
||||
}
|
||||
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(syllable.maskType() & head.maskType()) && !endAheadOrAheadHasToneMarkKey(iter + 1, sequence.end())) {
|
||||
if (!(syllable.maskType() & head.maskType()) &&
|
||||
!endAheadOrAheadHasToneMarkKey(iter + 1, sequence.end())) {
|
||||
syllable += head;
|
||||
}
|
||||
else {
|
||||
if (endAheadOrAheadHasToneMarkKey(iter + 1, sequence.end()) && head.belongsToZCSRClass() && syllable.isEmpty()) {
|
||||
} else {
|
||||
if (endAheadOrAheadHasToneMarkKey(iter + 1, sequence.end()) &&
|
||||
head.belongsToZCSRClass() && syllable.isEmpty()) {
|
||||
syllable += head;
|
||||
}
|
||||
else if (syllable.maskType() < follow.maskType()) {
|
||||
} else if (syllable.maskType() < follow.maskType()) {
|
||||
syllable += follow;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
syllable += ending;
|
||||
}
|
||||
}
|
||||
|
@ -407,24 +355,23 @@ namespace Formosa {
|
|||
// heuristics for Hsu keyboard layout
|
||||
if (this == HsuLayout()) {
|
||||
// fix the left out L to ERR when it has sound, and GI, GUE -> JI, JUE
|
||||
if (syllable.vowelComponent() == BPMF::ENG && !syllable.hasConsonant() && !syllable.hasMiddleVowel()) {
|
||||
if (syllable.vowelComponent() == BPMF::ENG && !syllable.hasConsonant() &&
|
||||
!syllable.hasMiddleVowel()) {
|
||||
syllable += BPMF(BPMF::ERR);
|
||||
}
|
||||
else if (syllable.consonantComponent() == BPMF::G && (syllable.middleVowelComponent() == BPMF::I || syllable.middleVowelComponent() == BPMF::UE)) {
|
||||
} else if (syllable.consonantComponent() == BPMF::G &&
|
||||
(syllable.middleVowelComponent() == BPMF::I ||
|
||||
syllable.middleVowelComponent() == BPMF::UE)) {
|
||||
syllable += BPMF(BPMF::J);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return syllable;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
bool endAheadOrAheadHasToneMarkKey(string::const_iterator ahead, string::const_iterator end) const
|
||||
{
|
||||
if (ahead == end)
|
||||
return true;
|
||||
bool endAheadOrAheadHasToneMarkKey(string::const_iterator ahead,
|
||||
string::const_iterator end) const {
|
||||
if (ahead == end) return true;
|
||||
|
||||
char tone1 = componentToKey(BPMF::Tone1);
|
||||
char tone2 = componentToKey(BPMF::Tone2);
|
||||
|
@ -435,20 +382,20 @@ namespace Formosa {
|
|||
if (tone1)
|
||||
if (*ahead == tone1) return true;
|
||||
|
||||
if (*ahead == tone2 || *ahead == tone3 || *ahead == tone4 || *ahead == tone5)
|
||||
if (*ahead == tone2 || *ahead == tone3 || *ahead == tone4 ||
|
||||
*ahead == tone5)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sequenceContainsIorUE(string::const_iterator start, string::const_iterator end) const
|
||||
{
|
||||
bool sequenceContainsIorUE(string::const_iterator start,
|
||||
string::const_iterator end) const {
|
||||
char iChar = componentToKey(BPMF::I);
|
||||
char ueChar = componentToKey(BPMF::UE);
|
||||
|
||||
for (; start != end; ++start)
|
||||
if (*start == iChar || *start == ueChar)
|
||||
return true;
|
||||
if (*start == iChar || *start == ueChar) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -462,24 +409,22 @@ namespace Formosa {
|
|||
static const BopomofoKeyboardLayout* c_ETen26Layout;
|
||||
static const BopomofoKeyboardLayout* c_IBMLayout;
|
||||
|
||||
// this is essentially an empty layout, but we use pointer semantic to tell the differences--and pass on the responsibility to BopomofoReadingBuffer
|
||||
// this is essentially an empty layout, but we use pointer semantic to tell
|
||||
// the differences--and pass on the responsibility to BopomofoReadingBuffer
|
||||
static const BopomofoKeyboardLayout* c_HanyuPinyinLayout;
|
||||
};
|
||||
|
||||
class BopomofoReadingBuffer {
|
||||
public:
|
||||
BopomofoReadingBuffer(const BopomofoKeyboardLayout* layout)
|
||||
: m_layout(layout)
|
||||
, m_pinyinMode(false)
|
||||
{
|
||||
: m_layout(layout), m_pinyinMode(false) {
|
||||
if (layout == BopomofoKeyboardLayout::HanyuPinyinLayout()) {
|
||||
m_pinyinMode = true;
|
||||
m_pinyinSequence = "";
|
||||
}
|
||||
}
|
||||
|
||||
void setKeyboardLayout(const BopomofoKeyboardLayout* layout)
|
||||
{
|
||||
void setKeyboardLayout(const BopomofoKeyboardLayout* layout) {
|
||||
m_layout = layout;
|
||||
|
||||
if (layout == BopomofoKeyboardLayout::HanyuPinyinLayout()) {
|
||||
|
@ -488,8 +433,7 @@ namespace Formosa {
|
|||
}
|
||||
}
|
||||
|
||||
bool isValidKey(char k) const
|
||||
{
|
||||
bool isValidKey(char k) const {
|
||||
if (!m_pinyinMode) {
|
||||
return m_layout ? (m_layout->keyToComponents(k)).size() > 0 : false;
|
||||
}
|
||||
|
@ -514,10 +458,8 @@ namespace Formosa {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool combineKey(char k)
|
||||
{
|
||||
if (!isValidKey(k))
|
||||
return false;
|
||||
bool combineKey(char k) {
|
||||
if (!isValidKey(k)) return false;
|
||||
|
||||
if (m_pinyinMode) {
|
||||
m_pinyinSequence += string(1, tolower(k));
|
||||
|
@ -525,25 +467,24 @@ namespace Formosa {
|
|||
return true;
|
||||
}
|
||||
|
||||
string sequence = m_layout->keySequenceFromSyllable(m_syllable) + string(1, k);
|
||||
string sequence =
|
||||
m_layout->keySequenceFromSyllable(m_syllable) + string(1, k);
|
||||
m_syllable = m_layout->syllableFromKeySequence(sequence);
|
||||
return true;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
void clear() {
|
||||
m_pinyinSequence.clear();
|
||||
m_syllable.clear();
|
||||
}
|
||||
|
||||
void backspace()
|
||||
{
|
||||
if (!m_layout)
|
||||
return;
|
||||
void backspace() {
|
||||
if (!m_layout) return;
|
||||
|
||||
if (m_pinyinMode) {
|
||||
if (m_pinyinSequence.length()) {
|
||||
m_pinyinSequence = m_pinyinSequence.substr(0, m_pinyinSequence.length() - 1);
|
||||
m_pinyinSequence =
|
||||
m_pinyinSequence.substr(0, m_pinyinSequence.length() - 1);
|
||||
}
|
||||
|
||||
m_syllable = BPMF::FromHanyuPinyin(m_pinyinSequence);
|
||||
|
@ -557,13 +498,9 @@ namespace Formosa {
|
|||
}
|
||||
}
|
||||
|
||||
bool isEmpty() const
|
||||
{
|
||||
return m_syllable.isEmpty();
|
||||
}
|
||||
bool isEmpty() const { return m_syllable.isEmpty(); }
|
||||
|
||||
const string composedString() const
|
||||
{
|
||||
const string composedString() const {
|
||||
if (m_pinyinMode) {
|
||||
return m_pinyinSequence;
|
||||
}
|
||||
|
@ -571,25 +508,18 @@ namespace Formosa {
|
|||
return m_syllable.composedString();
|
||||
}
|
||||
|
||||
const BPMF syllable() const
|
||||
{
|
||||
return m_syllable;
|
||||
const BPMF syllable() const { return m_syllable; }
|
||||
|
||||
const string standardLayoutQueryString() const {
|
||||
return BopomofoKeyboardLayout::StandardLayout()->keySequenceFromSyllable(
|
||||
m_syllable);
|
||||
}
|
||||
|
||||
const string standardLayoutQueryString() const
|
||||
{
|
||||
return BopomofoKeyboardLayout::StandardLayout()->keySequenceFromSyllable(m_syllable);
|
||||
}
|
||||
|
||||
const string absoluteOrderQueryString() const
|
||||
{
|
||||
const string absoluteOrderQueryString() const {
|
||||
return m_syllable.absoluteOrderString();
|
||||
}
|
||||
|
||||
bool hasToneMarker() const
|
||||
{
|
||||
return m_syllable.hasToneMarker();
|
||||
}
|
||||
bool hasToneMarker() const { return m_syllable.hasToneMarker(); }
|
||||
|
||||
protected:
|
||||
const BopomofoKeyboardLayout* m_layout;
|
||||
|
@ -598,7 +528,7 @@ namespace Formosa {
|
|||
bool m_pinyinMode;
|
||||
string m_pinyinSequence;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace Mandarin
|
||||
} // namespace Formosa
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue