Add a replacement character to digraphs system

The digraphs system used to allow only the replacement of
a pair (A, B) by (A). This change allows the replacement to
be any character.
Bug: 5140033

Change-Id: Icf5995f0ec553f7b7989af9902cbb2c4c6b51009
main
Jean Chalard 2012-03-21 18:38:25 +09:00
parent 9c4396abb3
commit d30433837d
2 changed files with 24 additions and 12 deletions

View File

@ -30,9 +30,9 @@
namespace latinime { namespace latinime {
const UnigramDictionary::digraph_t UnigramDictionary::GERMAN_UMLAUT_DIGRAPHS[] = const UnigramDictionary::digraph_t UnigramDictionary::GERMAN_UMLAUT_DIGRAPHS[] =
{ { 'a', 'e' }, { { 'a', 'e', 0x00E4 }, // U+00E4 : LATIN SMALL LETTER A WITH DIAERESIS
{ 'o', 'e' }, { 'o', 'e', 0x00F6 }, // U+00F6 : LATIN SMALL LETTER O WITH DIAERESIS
{ 'u', 'e' } }; { 'u', 'e', 0x00FC } }; // U+00FC : LATIN SMALL LETTER U WITH DIAERESIS
// TODO: check the header // TODO: check the header
UnigramDictionary::UnigramDictionary(const uint8_t* const streamStart, int typedLetterMultiplier, UnigramDictionary::UnigramDictionary(const uint8_t* const streamStart, int typedLetterMultiplier,
@ -64,7 +64,8 @@ static inline void addWord(
queue->push(frequency, word, length); queue->push(frequency, word, length);
} }
bool UnigramDictionary::isDigraph(const int *codes, const int i, const int codesSize, // Return the replacement code point for a digraph, or 0 if none.
int UnigramDictionary::getDigraphReplacement(const int *codes, const int i, const int codesSize,
const digraph_t* const digraphs, const unsigned int digraphsSize) const { const digraph_t* const digraphs, const unsigned int digraphsSize) const {
// There can't be a digraph if we don't have at least 2 characters to examine // There can't be a digraph if we don't have at least 2 characters to examine
@ -77,10 +78,14 @@ bool UnigramDictionary::isDigraph(const int *codes, const int i, const int codes
if (thisChar == digraphs[lastDigraphIndex].first) break; if (thisChar == digraphs[lastDigraphIndex].first) break;
} }
// No match: return early // No match: return early
if (lastDigraphIndex < 0) return false; if (lastDigraphIndex < 0) return 0;
// It's an interesting digraph if the second char matches too. // It's an interesting digraph if the second char matches too.
return digraphs[lastDigraphIndex].second == codes[(i + 1) * MAX_PROXIMITY_CHARS]; if (digraphs[lastDigraphIndex].second == codes[(i + 1) * MAX_PROXIMITY_CHARS]) {
return digraphs[lastDigraphIndex].replacement;
} else {
return 0;
}
} }
// Mostly the same arguments as the non-recursive version, except: // Mostly the same arguments as the non-recursive version, except:
@ -102,16 +107,23 @@ void UnigramDictionary::getWordWithDigraphSuggestionsRec(ProximityInfo *proximit
for (int i = 0; i < codesRemain; ++i) { for (int i = 0; i < codesRemain; ++i) {
xCoordinatesBuffer[startIndex + i] = xcoordinates[codesBufferSize - codesRemain + i]; xCoordinatesBuffer[startIndex + i] = xcoordinates[codesBufferSize - codesRemain + i];
yCoordinatesBuffer[startIndex + i] = ycoordinates[codesBufferSize - codesRemain + i]; yCoordinatesBuffer[startIndex + i] = ycoordinates[codesBufferSize - codesRemain + i];
if (isDigraph(codesSrc, i, codesRemain, digraphs, digraphsSize)) { const int replacementCodePoint =
getDigraphReplacement(codesSrc, i, codesRemain, digraphs, digraphsSize);
if (0 != replacementCodePoint) {
// Found a digraph. We will try both spellings. eg. the word is "pruefen" // Found a digraph. We will try both spellings. eg. the word is "pruefen"
// Copy the word up to the first char of the digraph, then continue processing // Copy the word up to the first char of the digraph, including proximity chars,
// on the remaining part of the word, skipping the second char of the digraph. // and overwrite the primary code with the replacement code point. Then, continue
// In our example, copy "pru" and continue running on "fen" // processing on the remaining part of the word, skipping the second char of the
// digraph.
// In our example, copy "pru", replace "u" with the version with the diaeresis and
// continue running on "fen".
// Make i the index of the second char of the digraph for simplicity. Forgetting // Make i the index of the second char of the digraph for simplicity. Forgetting
// to do that results in an infinite recursion so take care! // to do that results in an infinite recursion so take care!
++i; ++i;
memcpy(codesDest, codesSrc, i * BYTES_IN_ONE_CHAR); memcpy(codesDest, codesSrc, i * BYTES_IN_ONE_CHAR);
codesDest[(i - 1) * (BYTES_IN_ONE_CHAR / sizeof(codesDest[0]))] =
replacementCodePoint;
getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates, getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates,
codesBuffer, xCoordinatesBuffer, yCoordinatesBuffer, codesBufferSize, flags, codesBuffer, xCoordinatesBuffer, yCoordinatesBuffer, codesBufferSize, flags,
codesSrc + (i + 1) * MAX_PROXIMITY_CHARS, codesRemain - i - 1, codesSrc + (i + 1) * MAX_PROXIMITY_CHARS, codesRemain - i - 1,

View File

@ -29,7 +29,7 @@ namespace latinime {
class TerminalAttributes; class TerminalAttributes;
class UnigramDictionary { class UnigramDictionary {
typedef struct { int first; int second; } digraph_t; typedef struct { int first; int second; int replacement; } digraph_t;
public: public:
// Mask and flags for children address type selection. // Mask and flags for children address type selection.
@ -88,7 +88,7 @@ class UnigramDictionary {
void getWordSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates, void getWordSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates,
const int *ycoordinates, const int *codes, const int inputLength, const int *ycoordinates, const int *codes, const int inputLength,
const int flags, Correction *correction, WordsPriorityQueuePool *queuePool); const int flags, Correction *correction, WordsPriorityQueuePool *queuePool);
bool isDigraph(const int *codes, const int i, const int codesSize, int getDigraphReplacement(const int *codes, const int i, const int codesSize,
const digraph_t* const digraphs, const unsigned int digraphsSize) const; const digraph_t* const digraphs, const unsigned int digraphsSize) const;
void getWordWithDigraphSuggestionsRec(ProximityInfo *proximityInfo, void getWordWithDigraphSuggestionsRec(ProximityInfo *proximityInfo,
const int *xcoordinates, const int* ycoordinates, const int *codesBuffer, const int *xcoordinates, const int* ycoordinates, const int *codesBuffer,