From a360dbe761107cd98530c24f2c115dd5c7613dca Mon Sep 17 00:00:00 2001 From: BYVoid Date: Thu, 13 May 2010 11:18:30 +0800 Subject: [PATCH] add Bopomofo Support --- src/Bopomofo.h | 66 ++++++++ src/BopomofoEditor.cc | 416 ++++++++++++++++++++++++++++++++++++++++++++++++ src/BopomofoEditor.h | 101 ++++++++++++ src/Makefile.am | 3 + src/PinyinEditor.cc | 19 +++ src/PinyinEditor.h | 28 +--- src/PinyinEngine.cc | 11 +- src/PinyinParser.cc | 66 ++++++++ src/PinyinParser.h | 7 + src/PinyinParserTable.h | 1 - 10 files changed, 691 insertions(+), 27 deletions(-) create mode 100644 src/Bopomofo.h create mode 100644 src/BopomofoEditor.cc create mode 100644 src/BopomofoEditor.h diff --git a/src/Bopomofo.h b/src/Bopomofo.h new file mode 100644 index 0000000..37c2cb9 --- /dev/null +++ b/src/Bopomofo.h @@ -0,0 +1,66 @@ +/* + * Bopomofo.h + * + * Created on: 2010-5-12 + * Author: byvoid + */ + +#ifndef BOPOMOFO_H_ +#define BOPOMOFO_H_ + +#define MAX_BOPOMOFO_LEN (4) + +#define BOPOMOFO_ZERO (0) +#define BOPOMOFO_B (1) +#define BOPOMOFO_P (2) +#define BOPOMOFO_M (3) +#define BOPOMOFO_F (4) +#define BOPOMOFO_D (5) +#define BOPOMOFO_T (6) +#define BOPOMOFO_N (7) +#define BOPOMOFO_L (8) +#define BOPOMOFO_G (9) +#define BOPOMOFO_K (10) +#define BOPOMOFO_H (11) +#define BOPOMOFO_J (12) +#define BOPOMOFO_Q (13) +#define BOPOMOFO_X (14) +#define BOPOMOFO_ZH (15) +#define BOPOMOFO_CH (16) +#define BOPOMOFO_SH (17) +#define BOPOMOFO_R (18) +#define BOPOMOFO_Z (19) +#define BOPOMOFO_C (20) +#define BOPOMOFO_S (21) +#define BOPOMOFO_I (22) +#define BOPOMOFO_U (23) +#define BOPOMOFO_V (24) +#define BOPOMOFO_A (25) +#define BOPOMOFO_O (26) +#define BOPOMOFO_E (27) +#define BOPOMOFO_E2 (28) +#define BOPOMOFO_AI (29) +#define BOPOMOFO_EI (30) +#define BOPOMOFO_AO (31) +#define BOPOMOFO_OU (32) +#define BOPOMOFO_AN (33) +#define BOPOMOFO_EN (34) +#define BOPOMOFO_ANG (35) +#define BOPOMOFO_ENG (36) +#define BOPOMOFO_ER (37) +#define BOPOMOFO_TONE_2 (38) +#define BOPOMOFO_TONE_3 (39) +#define BOPOMOFO_TONE_4 (40) +#define BOPOMOFO_TONE_5 (41) + +const static wchar_t bopomofo_char[] = { + L'\0',L'ㄅ',L'ㄆ',L'ㄇ',L'ㄈ',L'ㄉ',L'ㄊ',L'ㄋ',L'ㄌ',L'ㄍ',L'ㄎ', + L'ㄏ',L'ㄐ',L'ㄑ',L'ㄒ',L'ㄓ',L'ㄔ',L'ㄕ',L'ㄖ',L'ㄗ',L'ㄘ',L'ㄙ', + + L'ㄧ',L'ㄨ',L'ㄩ',L'ㄚ',L'ㄛ',L'ㄜ',L'ㄝ',L'ㄞ',L'ㄟ',L'ㄠ',L'ㄡ', + L'ㄢ',L'ㄣ',L'ㄤ',L'ㄥ',L'ㄦ', + + L'ˊ',L'ˇ',L'ˋ',L'˙', +}; + +#endif /* BOPOMOFO_H_ */ diff --git a/src/BopomofoEditor.cc b/src/BopomofoEditor.cc new file mode 100644 index 0000000..af5757e --- /dev/null +++ b/src/BopomofoEditor.cc @@ -0,0 +1,416 @@ +#include "Config.h" +#include "BopomofoEditor.h" +#include "SimpTradConverter.h" + +namespace PY { + +BopomofoEditor::BopomofoEditor (PinyinProperties & props) + : PinyinEditor (props) +{ +} + +BopomofoEditor::~BopomofoEditor (void) +{ +} + +void +BopomofoEditor::reset (void) +{ + PinyinEditor::reset (); +} + +gboolean +BopomofoEditor::insert (gint ch) +{ + /* is full */ + if (G_UNLIKELY (m_text.length () >= MAX_PINYIN_LEN)) + return TRUE; + + gint key = get_bopomofo_keyboard_map(ch); + if (key >= BOPOMOFO_TONE_2 && key <= BOPOMOFO_TONE_5) { + if (m_cursor == 0) + return TRUE; /* invalid format: tone should not be the first character */ + key = get_bopomofo_keyboard_map(m_text.c_str()[m_cursor - 1]); + if (key >= BOPOMOFO_TONE_2 && key <= BOPOMOFO_TONE_5) + return TRUE; /* invalid format: two tone character should not be together */ + } + + m_text.insert (m_cursor++, ch); + + if (G_UNLIKELY (!(Config::option () & PINYIN_INCOMPLETE_PINYIN))) { + updateSpecialPhrases (); + updatePinyin (); + } + else if (G_LIKELY (m_cursor <= m_pinyin_len + 2)) { + updateSpecialPhrases (); + updatePinyin (); + } + else { + if (updateSpecialPhrases ()) { + update (); + } + else { + updatePreeditText (); + updateAuxiliaryText (); + } + } + return TRUE; +} + +gboolean +BopomofoEditor::removeCharBefore (void) +{ + if (G_UNLIKELY (m_cursor == 0)) + return FALSE; + + m_cursor --; + m_text.erase (m_cursor, 1); + + updateSpecialPhrases (); + updatePinyin (); + + return TRUE; +} + +gboolean +BopomofoEditor::removeCharAfter (void) +{ + if (G_UNLIKELY (m_cursor == m_text.length ())) + return FALSE; + + m_text.erase (m_cursor, 1); + updatePreeditText (); + updateAuxiliaryText (); + + return TRUE; +} + +gboolean +BopomofoEditor::removeWordBefore (void) +{ + if (G_UNLIKELY (m_cursor == 0)) + return FALSE; + + guint cursor; + + if (G_UNLIKELY (m_cursor > m_pinyin_len)) { + cursor = m_pinyin_len; + } + else { + const Pinyin & p = *m_pinyin.back (); + cursor = m_cursor - p.len; + m_pinyin_len -= p.len; + m_pinyin.pop_back (); + } + + m_text.erase (cursor, m_cursor - cursor); + m_cursor = cursor; + updateSpecialPhrases (); + updatePhraseEditor (); + update (); + return TRUE; +} + +gboolean +BopomofoEditor::removeWordAfter (void) +{ + if (G_UNLIKELY (m_cursor == m_text.length ())) + return FALSE; + + m_text.erase (m_cursor, -1); + updatePreeditText (); + updateAuxiliaryText (); + return TRUE; +} + +gboolean +BopomofoEditor::moveCursorLeft (void) +{ + if (G_UNLIKELY (m_cursor == 0)) + return FALSE; + + m_cursor --; + updateSpecialPhrases (); + updatePinyin (); + + return TRUE; +} + +gboolean +BopomofoEditor::moveCursorRight (void) +{ + if (G_UNLIKELY (m_cursor == m_text.length ())) + return FALSE; + + m_cursor ++; + + updateSpecialPhrases (); + updatePinyin (); + + return TRUE; +} + +gboolean +BopomofoEditor::moveCursorLeftByWord (void) +{ + if (G_UNLIKELY (m_cursor == 0)) + return FALSE; + + if (G_UNLIKELY (m_cursor > m_pinyin_len)) { + m_cursor = m_pinyin_len; + return TRUE; + } + + const Pinyin & p = *m_pinyin.back (); + m_cursor -= p.len; + m_pinyin_len -= p.len; + m_pinyin.pop_back (); + + updateSpecialPhrases (); + updatePhraseEditor (); + update (); + + return TRUE; +} + +gboolean +BopomofoEditor::moveCursorRightByWord (void) +{ + return moveCursorToEnd (); +} + +gboolean +BopomofoEditor::moveCursorToBegin (void) +{ + if (G_UNLIKELY (m_cursor == 0)) + return FALSE; + + m_cursor = 0; + m_pinyin.clear (); + m_pinyin_len = 0; + + updateSpecialPhrases (); + updatePhraseEditor (); + update (); + + return TRUE; +} + +gboolean +BopomofoEditor::moveCursorToEnd (void) +{ + if (G_UNLIKELY (m_cursor == m_text.length ())) + return FALSE; + + m_cursor = m_text.length (); + updateSpecialPhrases (); + updatePinyin (); + + return TRUE; +} + +gboolean +BopomofoEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers) +{ + switch (keyval) { + /* Bopomofo */ + case IBUS_a ... IBUS_z: + case IBUS_0 ... IBUS_9: + case IBUS_comma: + case IBUS_period: + case IBUS_slash: + case IBUS_semicolon: + case IBUS_minus: + return processBopomofo (keyval, keycode, modifiers); + + default: + return PinyinEditor::processKeyEvent (keyval, keycode, modifiers); + } +} + +#define CMSHM_MASK \ + (IBUS_CONTROL_MASK | \ + IBUS_MOD1_MASK | \ + IBUS_SUPER_MASK | \ + IBUS_HYPER_MASK | \ + IBUS_META_MASK) + +#define CMSHM_FILTER(modifiers) \ + (modifiers & (CMSHM_MASK)) + +/** + * process bopomofo + */ +inline gboolean +BopomofoEditor::processBopomofo (guint keyval, guint keycode, guint modifiers) +{ + if (G_UNLIKELY (CMSHM_FILTER(modifiers) != 0)) + return m_text ? TRUE : FALSE; + + return insert (keyval); +} + +void +BopomofoEditor::updatePinyin (void) +{ + if (G_UNLIKELY (m_text.empty ())) { + m_pinyin.clear (); + m_pinyin_len = 0; + } + else { + bopomofo.clear(); + for(String::iterator i = m_text.begin();i != m_text.end(); ++i) { + bopomofo += bopomofo_char[get_bopomofo_keyboard_map(*i)]; + } + + m_pinyin_len = PinyinParser::parse_bopomofo(bopomofo, // bopomofo + m_cursor, // text length + Config::option (), // option + m_pinyin, // result + MAX_PHRASE_LEN); // max result length + } + + updatePhraseEditor (); + update (); +} + +void +BopomofoEditor::updateAuxiliaryText (void) +{ + if (G_UNLIKELY (m_text.empty () || + m_lookup_table.size () == 0)) { + hideAuxiliaryText (); + return; + } + + m_buffer.clear (); + + updateAuxiliaryTextBefore (m_buffer); + + for (String::iterator i = m_text.begin();i!=m_text.end();i++) { + if (m_cursor == i - m_text.begin()) + m_buffer << '|'; + m_buffer.appendUnichar(bopomofo_char[get_bopomofo_keyboard_map(*i)]); + } + if (m_cursor == m_text.length()) + m_buffer << '|'; + + updateAuxiliaryTextAfter (m_buffer); + + StaticText aux_text (m_buffer); + Editor::updateAuxiliaryText (aux_text, TRUE); +} + +void +BopomofoEditor::commit (void) +{ + if (G_UNLIKELY (empty ())) + return; + + m_buffer.clear (); + + m_buffer << m_phrase_editor.selectedString (); + + const gchar *p; + + if (m_selected_special_phrase.empty ()) { + p = textAfterPinyin (m_buffer.utf8Length ()); + } + else { + m_buffer << m_selected_special_phrase; + p = textAfterCursor (); + } + + while (*p != '\0') { + m_buffer.appendUnichar ((gunichar)bopomofo_char[get_bopomofo_keyboard_map(*p++)]); + } + + m_phrase_editor.commit (); + reset (); + PinyinEditor::commit ((const gchar *)m_buffer); +} + +void +BopomofoEditor::updatePreeditText (void) +{ + PinyinEditor::updatePreeditText(); +#if 0 + /* preedit text = selected phrases + highlight candidate + rest text */ + if (G_UNLIKELY (m_phrase_editor.empty () && m_text.empty ())) { + hidePreeditText (); + return; + } + + guint edit_begin = 0; + guint edit_end = 0; + + m_buffer.clear (); + + /* add selected phrases */ + m_buffer << m_phrase_editor.selectedString (); + + if (G_UNLIKELY (! m_selected_special_phrase.empty ())) { + /* add selected special phrase */ + m_buffer << m_selected_special_phrase; + edit_begin = m_buffer.utf8Length (); + + /* append text after cursor */ + m_buffer << textAfterCursor (); + } + else { + edit_begin = m_buffer.utf8Length (); + if (m_lookup_table.size () > 0) { + guint cursor = m_lookup_table.cursorPos (); + + if (cursor < m_special_phrases.size ()) { + m_buffer << m_special_phrases[cursor].c_str (); + edit_end = m_buffer.utf8Length (); + /* append text after cursor */ + m_buffer << textAfterCursor (); + } + else { + const Phrase & candidate = m_phrase_editor.candidate (cursor - m_special_phrases.size ()); + if (m_text.size () == m_cursor) { + /* cursor at end */ + if (m_props.modeSimp ()) + m_buffer << candidate; + else + SimpTradConverter::simpToTrad (candidate, m_buffer); + edit_end = m_buffer.utf8Length (); + + /* append rest text */ + m_buffer << textAfterPinyin (edit_end); + } + else { + guint candidate_end = edit_begin + candidate.len; + m_buffer << m_pinyin[edit_begin]->sheng << m_pinyin[edit_begin]->yun; + + for (guint i = edit_begin + 1; i < candidate_end; i++) { + m_buffer << ' ' << m_pinyin[i]->sheng << m_pinyin[i]->yun; + } + m_buffer << ' ' << textAfterPinyin (candidate_end); + edit_end = m_buffer.utf8Length (); + } + } + } + else { + m_buffer << textAfterPinyin (); + } + } + + StaticText preedit_text (m_buffer); + /* underline */ + preedit_text.appendAttribute (IBUS_ATTR_TYPE_UNDERLINE, IBUS_ATTR_UNDERLINE_SINGLE, 0, -1); + + /* candidate */ + if (edit_begin < edit_end) { + preedit_text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x00000000, + edit_begin, edit_end); + preedit_text.appendAttribute (IBUS_ATTR_TYPE_BACKGROUND, 0x00c8c8f0, + edit_begin, edit_end); + } + Editor::updatePreeditText (preedit_text, edit_begin, TRUE); +#endif +} + +}; diff --git a/src/BopomofoEditor.h b/src/BopomofoEditor.h new file mode 100644 index 0000000..9516233 --- /dev/null +++ b/src/BopomofoEditor.h @@ -0,0 +1,101 @@ +#ifndef __PY_BOPOMOFO_EDITOR_H_ +#define __PY_BOPOMOFO_EDITOR_H_ + +#include "PinyinEditor.h" + +namespace PY { + +#include "Bopomofo.h" + +class BopomofoEditor : public PinyinEditor { + +public: + BopomofoEditor (PinyinProperties & props); + ~BopomofoEditor (void); + +public: + /* virtual functions */ + virtual gboolean processKeyEvent (guint keyval, guint keycode, guint modifiers); + virtual void reset (void); + +protected: + std::wstring bopomofo; + + virtual void updatePinyin (void); + virtual void updateAuxiliaryText (void); + virtual void updatePreeditText (void); + virtual void commit (void); + + gboolean insert (gint ch); + + gboolean removeCharBefore (void); + gboolean removeCharAfter (void); + gboolean removeWordBefore (void); + gboolean removeWordAfter (void); + + gboolean moveCursorLeft (void); + gboolean moveCursorRight (void); + gboolean moveCursorLeftByWord (void); + gboolean moveCursorRightByWord (void); + gboolean moveCursorToBegin (void); + gboolean moveCursorToEnd (void); + + gboolean processBopomofo (guint keyval, guint keycode, guint modifiers); + + gint get_bopomofo_keyboard_map(gint ch) { + switch(ch){ + case IBUS_1: return BOPOMOFO_B; + case IBUS_q: return BOPOMOFO_P; + case IBUS_a: return BOPOMOFO_M; + case IBUS_z: return BOPOMOFO_F; + case IBUS_2: return BOPOMOFO_D; + case IBUS_w: return BOPOMOFO_T; + case IBUS_s: return BOPOMOFO_N; + case IBUS_x: return BOPOMOFO_L; + case IBUS_e: return BOPOMOFO_G; + case IBUS_d: return BOPOMOFO_K; + case IBUS_c: return BOPOMOFO_H; + case IBUS_r: return BOPOMOFO_J; + case IBUS_f: return BOPOMOFO_Q; + case IBUS_v: return BOPOMOFO_X; + case IBUS_5: return BOPOMOFO_ZH; + case IBUS_t: return BOPOMOFO_CH; + case IBUS_g: return BOPOMOFO_SH; + case IBUS_b: return BOPOMOFO_R; + case IBUS_y: return BOPOMOFO_Z; + case IBUS_h: return BOPOMOFO_C; + case IBUS_n: return BOPOMOFO_S; + + case IBUS_u: return BOPOMOFO_I; + case IBUS_j: return BOPOMOFO_U; + case IBUS_m: return BOPOMOFO_V; + case IBUS_8: return BOPOMOFO_A; + case IBUS_i: return BOPOMOFO_O; + case IBUS_k: return BOPOMOFO_E; + case IBUS_comma: return BOPOMOFO_E2; + case IBUS_9: return BOPOMOFO_AI; + case IBUS_o: return BOPOMOFO_EI; + case IBUS_l: return BOPOMOFO_AO; + case IBUS_period: return BOPOMOFO_OU; + case IBUS_0: return BOPOMOFO_AN; + case IBUS_p: return BOPOMOFO_EN; + case IBUS_semicolon: return BOPOMOFO_ANG; + case IBUS_slash: return BOPOMOFO_ENG; + case IBUS_minus: return BOPOMOFO_ER; + + case IBUS_3: return BOPOMOFO_TONE_2; + case IBUS_4: return BOPOMOFO_TONE_3; + case IBUS_6: return BOPOMOFO_TONE_4; + case IBUS_7: return BOPOMOFO_TONE_5; + + default: + return 0; + } + } + + +}; + +}; + +#endif diff --git a/src/Makefile.am b/src/Makefile.am index 3cd72e6..c86b82e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -34,6 +34,7 @@ libexec_PROGRAMS = ibus-engine-pinyin ibus_engine_c_sources = \ + BopomofoEditor.cc \ Config.cc \ Database.cc \ DoublePinyinEditor.cc \ @@ -55,10 +56,12 @@ ibus_engine_c_sources = \ SpecialPhraseTable.cc \ $(NULL) ibus_engine_built_h_sources = \ + Bopomofo.h \ PinyinParserTable.h \ SimpTradConverterTable.h \ $(NULL) ibus_engine_h_sources = \ + BopomofoEditor.h \ Bus.h \ Config.h \ Database.h \ diff --git a/src/PinyinEditor.cc b/src/PinyinEditor.cc index 4e5bc3b..07fd16d 100644 --- a/src/PinyinEditor.cc +++ b/src/PinyinEditor.cc @@ -325,6 +325,25 @@ PinyinEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers) } } +gboolean +PinyinEditor::updateSpecialPhrases (void) { + if (!m_selected_special_phrase.empty ()) + return FALSE; + + guint size = m_special_phrases.size (); + guint begin = m_phrase_editor.cursorInChar (); + guint end = m_cursor; + + m_special_phrases.clear (); + if (begin < end) { + SpecialPhraseTable::instance ().lookup ( + m_text.substr (begin, m_cursor - begin), + m_special_phrases); + } + + return size != m_special_phrases.size () || size != 0; +} + void PinyinEditor::updatePreeditText (void) { diff --git a/src/PinyinEditor.h b/src/PinyinEditor.h index 1ae3fb0..d8a1c15 100644 --- a/src/PinyinEditor.h +++ b/src/PinyinEditor.h @@ -39,37 +39,15 @@ protected: gboolean processSpace (guint keyval, guint keycode, guint modifiers); gboolean processOthers (guint keyval, guint keycode, guint modifiers); - void updatePreeditText (void); - void updateAuxiliaryText (void); - void updateLookupTable (void); gboolean fillLookupTableByPage (void); void updatePhraseEditor (void) { m_phrase_editor.update (m_pinyin); } - - gboolean updateSpecialPhrases (void) { - if (!m_selected_special_phrase.empty ()) - return FALSE; - - guint size = m_special_phrases.size (); - guint begin = m_phrase_editor.cursorInChar (); - guint end = m_cursor; - - m_special_phrases.clear (); - if (begin < end) { - SpecialPhraseTable::instance ().lookup ( - m_text.substr (begin, m_cursor - begin), - m_special_phrases); - } - - return size != m_special_phrases.size () || size != 0; - } - + gboolean updateSpecialPhrases (void); gboolean selectCandidate (guint i); gboolean selectCandidateInPage (guint i); gboolean resetCandidate (guint i); gboolean resetCandidateInPage (guint i); - void commit (void); void commit (const gchar *str); const String & text (void) const { return m_text; } @@ -89,6 +67,10 @@ protected: operator gboolean (void) const { return ! empty (); } /* virtual functions */ + virtual void updatePreeditText (void); + virtual void updateAuxiliaryText (void); + virtual void updateLookupTable (void); + virtual void commit (void); virtual gboolean insert (gint ch) = 0; virtual gboolean removeCharBefore (void) = 0; virtual gboolean removeCharAfter (void) = 0; diff --git a/src/PinyinEngine.cc b/src/PinyinEngine.cc index aa9f247..d279e66 100644 --- a/src/PinyinEngine.cc +++ b/src/PinyinEngine.cc @@ -7,8 +7,10 @@ #include "ExtEditor.h" #include "FullPinyinEditor.h" #include "DoublePinyinEditor.h" +#include "BopomofoEditor.h" #include "PinyinEngine.h" #include "HalfFullConverter.h" +#include "SimpTradConverter.h" #include "Config.h" #include "Text.h" #include "Util.h" @@ -27,7 +29,8 @@ PinyinEngine::PinyinEngine (IBusEngine *engine) gint i; /* create editors */ if (Config::doublePinyin ()) - m_editors[MODE_INIT].reset (new DoublePinyinEditor (m_props)); + //m_editors[MODE_INIT].reset (new DoublePinyinEditor (m_props)); + m_editors[MODE_INIT].reset (new BopomofoEditor (m_props)); else m_editors[MODE_INIT].reset (new FullPinyinEditor (m_props)); @@ -128,8 +131,10 @@ PinyinEngine::focusIn (void) { /* reset pinyin editor */ if (Config::doublePinyin ()) { - if (dynamic_cast (m_editors[MODE_INIT].get ()) == NULL) { - m_editors[MODE_INIT].reset (new DoublePinyinEditor (m_props)); + //if (dynamic_cast (m_editors[MODE_INIT].get ()) == NULL) { + // m_editors[MODE_INIT].reset (new DoublePinyinEditor (m_props)); + if (dynamic_cast (m_editors[MODE_INIT].get ()) == NULL) { + m_editors[MODE_INIT].reset (new BopomofoEditor (m_props)); connectEditorSignals (m_editors[MODE_INIT]); } } diff --git a/src/PinyinParser.cc b/src/PinyinParser.cc index d6d1e3e..fe8e31b 100644 --- a/src/PinyinParser.cc +++ b/src/PinyinParser.cc @@ -7,6 +7,7 @@ namespace PY { +#include "Bopomofo.h" #include "PinyinParserTable.h" static gboolean @@ -260,5 +261,70 @@ PinyinParser::isPinyin (gint sheng, gint yun, guint option) return NULL; } +static int +bopomofo_cmp (const void *p1, const void *p2) +{ + const wchar_t *s1 = (wchar_t *) p1; + const Pinyin *s2 = *(const Pinyin **) p2; + + return std::wcscmp (s1,s2->bopomofo); +} + +gboolean +PinyinParser::isBopomofoToneChar (const wchar_t ch) +{ + return ch == bopomofo_char[BOPOMOFO_TONE_2] + || ch == bopomofo_char[BOPOMOFO_TONE_3] + || ch == bopomofo_char[BOPOMOFO_TONE_4] + || ch == bopomofo_char[BOPOMOFO_TONE_5]; +} + +guint +PinyinParser::parse_bopomofo (const std::wstring &bopomofo, + gint len, + guint option, + PinyinArray &result, + guint max) +{ + std::wstring::const_iterator bpmf = bopomofo.begin(); + const std::wstring::const_iterator end = bpmf + len; + const Pinyin **bs_res; + wchar_t buf[MAX_BOPOMOFO_LEN + 1]; + gint i,j; + + result.clear (); + + if (G_UNLIKELY (len < 0)) + len = bopomofo.length(); + + for (; bpmf < end && result.size () < max; ) { + for (i = MAX_BOPOMOFO_LEN; i>0; i--){ + if (bpmf + i > end) + continue; + + for (j=0;jlen); + bpmf += i; + } + + return bpmf - bopomofo.begin(); }; +}; diff --git a/src/PinyinParser.h b/src/PinyinParser.h index e27f24b..ebf0815 100644 --- a/src/PinyinParser.h +++ b/src/PinyinParser.h @@ -16,6 +16,13 @@ public: PinyinArray &result, // store pinyin in result guint max); // max length of the result static const Pinyin * isPinyin (gint sheng, gint yun, guint option); + static guint parse_bopomofo (const std::wstring &bopomofo, + gint len, + guint option, + PinyinArray &result, + guint max); + static gboolean isBopomofoToneChar (const wchar_t ch); + }; }; #endif diff --git a/src/PinyinParserTable.h b/src/PinyinParserTable.h index 6e175e2..8e7548f 100644 --- a/src/PinyinParserTable.h +++ b/src/PinyinParserTable.h @@ -11438,4 +11438,3 @@ static const Pinyin *special_table[][4] = { { &pinyin_table[712], &pinyin_table[125], &pinyin_table[704], &pinyin_table[357], }, /* zun e => zu ne */ { &pinyin_table[712], &pinyin_table[126], &pinyin_table[704], &pinyin_table[359], }, /* zun ei => zu nei */ }; - -- 2.7.4