--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+#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
+}
+
+};
--- /dev/null
+#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
libexec_PROGRAMS = ibus-engine-pinyin
ibus_engine_c_sources = \
+ BopomofoEditor.cc \
Config.cc \
Database.cc \
DoublePinyinEditor.cc \
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 \
}
}
+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)
{
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; }
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;
#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"
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));
{
/* reset pinyin editor */
if (Config::doublePinyin ()) {
- if (dynamic_cast <DoublePinyinEditor *> (m_editors[MODE_INIT].get ()) == NULL) {
- m_editors[MODE_INIT].reset (new DoublePinyinEditor (m_props));
+ //if (dynamic_cast <DoublePinyinEditor *> (m_editors[MODE_INIT].get ()) == NULL) {
+ // m_editors[MODE_INIT].reset (new DoublePinyinEditor (m_props));
+ if (dynamic_cast <BopomofoEditor *> (m_editors[MODE_INIT].get ()) == NULL) {
+ m_editors[MODE_INIT].reset (new BopomofoEditor (m_props));
connectEditorSignals (m_editors[MODE_INIT]);
}
}
namespace PY {
+#include "Bopomofo.h"
#include "PinyinParserTable.h"
static gboolean
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;j<i;j++){
+ wchar_t key = *(bpmf+j);
+
+ if (j == i-1 && isBopomofoToneChar(key)) {
+ break; /* ignore tone */
+ }
+
+ buf[j] = key;
+ }
+
+ buf[j] = '\0';
+ bs_res = (const Pinyin **) std::bsearch (buf, bopomofo_table,
+ G_N_ELEMENTS (bopomofo_table),
+ sizeof(bopomofo_table[0]),
+ bopomofo_cmp);
+ if (G_UNLIKELY (bs_res != NULL))
+ break;
+ }
+ result.append(*bs_res,bpmf - bopomofo.begin() ,(*bs_res)->len);
+ bpmf += i;
+ }
+
+ return bpmf - bopomofo.begin();
};
+};
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
{ &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 */
};
-