Add ability to handle digraphs in gesture and tap typing
Example: Gesture the German word "ueber" and the system will now replace the transliteration "ue" with the correct u-umlaut. Bug: 8493920 Change-Id: I03e1d6311b4187b6c7f802d8fef43a50eee12721main
parent
b6e1777d4b
commit
fd9f3d97ae
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "char_utils.h"
|
#include "char_utils.h"
|
||||||
#include "dictionary.h"
|
#include "dictionary.h"
|
||||||
|
#include "digraph_utils.h"
|
||||||
#include "proximity_info.h"
|
#include "proximity_info.h"
|
||||||
#include "suggest/core/dicnode/dic_node.h"
|
#include "suggest/core/dicnode/dic_node.h"
|
||||||
#include "suggest/core/dicnode/dic_node_priority_queue.h"
|
#include "suggest/core/dicnode/dic_node_priority_queue.h"
|
||||||
|
@ -221,7 +222,7 @@ int Suggest::outputSuggestions(DicTraverseSession *traverseSession, int *frequen
|
||||||
void Suggest::expandCurrentDicNodes(DicTraverseSession *traverseSession) const {
|
void Suggest::expandCurrentDicNodes(DicTraverseSession *traverseSession) const {
|
||||||
const int inputSize = traverseSession->getInputSize();
|
const int inputSize = traverseSession->getInputSize();
|
||||||
DicNodeVector childDicNodes(TRAVERSAL->getDefaultExpandDicNodeSize());
|
DicNodeVector childDicNodes(TRAVERSAL->getDefaultExpandDicNodeSize());
|
||||||
DicNode omissionDicNode;
|
DicNode correctionDicNode;
|
||||||
|
|
||||||
// TODO: Find more efficient caching
|
// TODO: Find more efficient caching
|
||||||
const bool shouldDepthLevelCache = TRAVERSAL->shouldDepthLevelCache(traverseSession);
|
const bool shouldDepthLevelCache = TRAVERSAL->shouldDepthLevelCache(traverseSession);
|
||||||
|
@ -257,7 +258,10 @@ void Suggest::expandCurrentDicNodes(DicTraverseSession *traverseSession) const {
|
||||||
dicNode.setCached();
|
dicNode.setCached();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLookAheadCorrection) {
|
if (dicNode.isInDigraph()) {
|
||||||
|
// Finish digraph handling if the node is in the middle of a digraph expansion.
|
||||||
|
processDicNodeAsDigraph(traverseSession, &dicNode);
|
||||||
|
} else if (isLookAheadCorrection) {
|
||||||
// The algorithm maintains a small set of "deferred" nodes that have not consumed the
|
// The algorithm maintains a small set of "deferred" nodes that have not consumed the
|
||||||
// latest touch point yet. These are needed to apply look-ahead correction operations
|
// latest touch point yet. These are needed to apply look-ahead correction operations
|
||||||
// that require special handling of the latest touch point. For example, with insertions
|
// that require special handling of the latest touch point. For example, with insertions
|
||||||
|
@ -291,12 +295,18 @@ void Suggest::expandCurrentDicNodes(DicTraverseSession *traverseSession) const {
|
||||||
processDicNodeAsMatch(traverseSession, childDicNode);
|
processDicNodeAsMatch(traverseSession, childDicNode);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (DigraphUtils::hasDigraphForCodePoint(traverseSession->getDictFlags(),
|
||||||
|
childDicNode->getNodeCodePoint())) {
|
||||||
|
correctionDicNode.initByCopy(childDicNode);
|
||||||
|
correctionDicNode.advanceDigraphIndex();
|
||||||
|
processDicNodeAsDigraph(traverseSession, &correctionDicNode);
|
||||||
|
}
|
||||||
if (allowsErrorCorrections
|
if (allowsErrorCorrections
|
||||||
&& TRAVERSAL->isOmission(traverseSession, &dicNode, childDicNode)) {
|
&& TRAVERSAL->isOmission(traverseSession, &dicNode, childDicNode)) {
|
||||||
// TODO: (Gesture) Change weight between omission and substitution errors
|
// TODO: (Gesture) Change weight between omission and substitution errors
|
||||||
// TODO: (Gesture) Terminal node should not be handled as omission
|
// TODO: (Gesture) Terminal node should not be handled as omission
|
||||||
omissionDicNode.initByCopy(childDicNode);
|
correctionDicNode.initByCopy(childDicNode);
|
||||||
processDicNodeAsOmission(traverseSession, &omissionDicNode);
|
processDicNodeAsOmission(traverseSession, &correctionDicNode);
|
||||||
}
|
}
|
||||||
const ProximityType proximityType = TRAVERSAL->getProximityType(
|
const ProximityType proximityType = TRAVERSAL->getProximityType(
|
||||||
traverseSession, &dicNode, childDicNode);
|
traverseSession, &dicNode, childDicNode);
|
||||||
|
@ -400,6 +410,16 @@ void Suggest::processDicNodeAsSubstitution(DicTraverseSession *traverseSession,
|
||||||
processExpandedDicNode(traverseSession, childDicNode);
|
processExpandedDicNode(traverseSession, childDicNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Process the node codepoint as a digraph. This means that composite glyphs like the German
|
||||||
|
// u-umlaut is expanded to the transliteration "ue". Note that this happens in parallel with
|
||||||
|
// the normal non-digraph traversal, so both "uber" and "ueber" can be corrected to "[u-umlaut]ber".
|
||||||
|
void Suggest::processDicNodeAsDigraph(DicTraverseSession *traverseSession,
|
||||||
|
DicNode *childDicNode) const {
|
||||||
|
weightChildNode(traverseSession, childDicNode);
|
||||||
|
childDicNode->advanceDigraphIndex();
|
||||||
|
processExpandedDicNode(traverseSession, childDicNode);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the dicNode as an omission error (e.g., ths => this). Skip the current letter and consider
|
* Handle the dicNode as an omission error (e.g., ths => this). Skip the current letter and consider
|
||||||
* matches for all possible next letters. Note that just skipping the current letter without any
|
* matches for all possible next letters. Note that just skipping the current letter without any
|
||||||
|
|
|
@ -64,6 +64,7 @@ class Suggest : public SuggestInterface {
|
||||||
void generateFeatures(
|
void generateFeatures(
|
||||||
DicTraverseSession *traverseSession, DicNode *dicNode, float *features) const;
|
DicTraverseSession *traverseSession, DicNode *dicNode, float *features) const;
|
||||||
void processDicNodeAsOmission(DicTraverseSession *traverseSession, DicNode *dicNode) const;
|
void processDicNodeAsOmission(DicTraverseSession *traverseSession, DicNode *dicNode) const;
|
||||||
|
void processDicNodeAsDigraph(DicTraverseSession *traverseSession, DicNode *dicNode) const;
|
||||||
void processDicNodeAsTransposition(DicTraverseSession *traverseSession,
|
void processDicNodeAsTransposition(DicTraverseSession *traverseSession,
|
||||||
DicNode *dicNode) const;
|
DicNode *dicNode) const;
|
||||||
void processDicNodeAsInsertion(DicTraverseSession *traverseSession, DicNode *dicNode) const;
|
void processDicNodeAsInsertion(DicTraverseSession *traverseSession, DicNode *dicNode) const;
|
||||||
|
|
Loading…
Reference in New Issue