void QFSPenMatch::addStroke( QIMPenStroke *st ) { qLog(Input) << "QFSPenMatch:: addStroke"; if(!mCharSet){ qWarning("CharSet not set in QFSPenMatch::addStroke( QIMPenStroke *st )"); qWarning("QFSPenMatch::setCharSet() must be called before addStroke()"); return; } mCanvasHeight = 0; // reset mMatchList.clear(); mMatchCount = 0; /* want to test for current longest multi stroke and for each shorter.. then for low thresholds, drop them from the list of max lenght matches. */ // add 1 stroke test char to test chars that matched last time. QIMPenChar c; mTestChars.append(c); // and test current test chars for matches. uint minerror = UINT_MAX; int matched_height = 0; int input_height = 0; QMutableListIterator<QIMPenChar> it(mTestChars); while (it.hasNext()) { QIMPenChar c = it.next(); c.addStroke(st); it.setValue(c); QIMPenCharMatchList ml = mCharSet->match( &c ); // if ml is 0, drop this char... if (ml.count() > 0) { // later just append, for now, bias towards more stroke and // compare errors. appendNew(mMatchList, ml, c.strokeCount()); // if lowest error, up date height of matched char and height // of test char. QIMPenChar *ch = ml.first().penChar; if (ch && (uint)ml.first().error < minerror) { matched_height = ch->boundingRect().height(); input_height = c.boundingRect().height(); } } else { it.remove(); } } if (input_height && matched_height) mCanvasHeight = int(float(input_height * 75) / float(matched_height)); }
void appendNew(QList<QFSPenMatch::Guess> &list, const QIMPenCharMatchList &matched, int length) { QIMPenCharMatchList::ConstIterator it; for (it = matched.begin(); it != matched.end(); ++it) { if ((*it).error <= 200000 && (int)(*it).penChar->strokeCount() >= length) { QFSPenMatch::Guess g; g.length = length; g.error = length > 1 ? (*it).error / 3 : (*it).error; g.text = (*it).penChar->repCharacter(); g.key = (*it).penChar->key(); if (!contains(list, g.key, g.text)) list.append(g); } } }
void QIMPenInput::matchedCharacters( const QIMPenCharMatchList &cl ) { const QIMPenChar *ch = cl.first().penChar; int scan = ch->character() >> 16; if ( scan < QIMPenChar::ModeBase ) return; // We matched a special character... switch ( scan ) { case QIMPenChar::Caps: if ( profile->style() == QIMPenProfile::ToggleCases ) { // odebug << "Caps" << oendl; // if ( mode == SwitchLock ) { // odebug << "Switch to normal" << oendl; pw->changeCharSet( profile->lowercase(), currCharSet ); mode = Switch; } else { // odebug << "Switch to upper" << oendl; pw->changeCharSet( profile->uppercase(), currCharSet ); mode = Switch; } } break; case QIMPenChar::CapsLock: if ( profile->style() == QIMPenProfile::ToggleCases ) { // odebug << "CapsLock" << oendl; if ( mode == Switch && baseSets.at(currCharSet) == profile->uppercase() ) { // odebug << "Switch to normal" << oendl; pw->changeCharSet( profile->lowercase(), currCharSet ); // change our base set back to lower. baseSets.remove( currCharSet ); baseSets.insert( currCharSet, profile->lowercase() ); mode = Normal; } else { // odebug << "Switch to caps lock" << oendl; pw->changeCharSet( profile->uppercase(), currCharSet ); // change our base set to upper. baseSets.remove( currCharSet ); baseSets.insert( currCharSet, profile->uppercase() ); mode = SwitchLock; } } break; case QIMPenChar::Punctuation: if ( profile->punctuation() ) { //odebug << "Switch to punctuation" << oendl; pw->changeCharSet( profile->punctuation(), currCharSet ); mode = Switch; } break; case QIMPenChar::Symbol: if ( profile->symbol() ) { //odebug << "Switch to symbol" << oendl ; pw->changeCharSet( profile->symbol(), currCharSet ); mode = Switch; } break; case QIMPenChar::Shortcut: if ( shortcutCharSet ) { pw->changeCharSet( shortcutCharSet, currCharSet ); mode = Switch; } break; case QIMPenChar::Extended: handleExtended( ch->data() ); break; } }