diff options
Diffstat (limited to 'src/plugins/cerence/xt9/xt9common/xt9cpime.cpp')
-rw-r--r-- | src/plugins/cerence/xt9/xt9common/xt9cpime.cpp | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/src/plugins/cerence/xt9/xt9common/xt9cpime.cpp b/src/plugins/cerence/xt9/xt9common/xt9cpime.cpp new file mode 100644 index 00000000..5dff7495 --- /dev/null +++ b/src/plugins/cerence/xt9/xt9common/xt9cpime.cpp @@ -0,0 +1,284 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "xt9cpime.h" +#include "xt9languagemap.h" +#include "xt9dbfile.h" +#include "xt9callbacks.h" +#include <QStandardPaths> +#include <QLoggingCategory> + +QT_BEGIN_NAMESPACE +namespace QtVirtualKeyboard { + +static const ET9SYMB CANGJIE_MAP[] = { + 0x65E5, 0x6708, 0x91D1, 0x6728, 0x6C34, 0x706B, 0x571F, 0x7AF9, 0x6208, + 0x5341, 0x5927, 0x4E2D, 0x4E00, 0x5F13, 0x4EBA, 0x5FC3, 0x624B, 0x53E3, + 0x5C38, 0x5EFF, 0x5C71, 0x5973, 0x7530, 0x96E3, 0x535C }; +static const size_t CANGJIE_MAP_SIZE = sizeof(CANGJIE_MAP) / sizeof(ET9SYMB); +static const ET9SYMB CANGJIE_WILDCARD_SYMB = 0x91CD; + +static ET9SYMB GetCangjieMappingSymb(ET9SYMB symb) +{ + if (symb == CANGJIE_WILDCARD_SYMB) + return ET9CPCANGJIEWILDCARD; + + for (size_t i = 0; i < CANGJIE_MAP_SIZE; i++) { + if (CANGJIE_MAP[i] == symb) + return static_cast<ET9SYMB>(i + 'a'); + } + + return symb; +} + +static ET9SYMB GetCangjieSymb(ET9SYMB symb) +{ + if (symb == ET9CPCANGJIEWILDCARD) + return CANGJIE_WILDCARD_SYMB; + + if (ET9CPIsCangJieLowerSymbol(symb)) + return CANGJIE_MAP[symb - 'a']; + + if (ET9CPIsCangJieUpperSymbol(symb)) + return CANGJIE_MAP[symb - 'A']; + + return symb; +} + +class CangjieConverter : public Xt9KeyboardGenerator::CodeConverter { +public: + QString convertTo(const QString &codes) const override + { + QVector<ushort> cangjieBuf(codes.size()); + for (int i = 0; i < codes.size(); ++i) { + cangjieBuf[i] = GetCangjieSymb(codes.at(i).unicode()); + } + return QString::fromUtf16(reinterpret_cast<const char16_t *>(cangjieBuf.constData()), cangjieBuf.size()); + } + + QString convertFrom(const QString &codes) const override + { + QVector<ushort> cangjieBuf(codes.size()); + for (int i = 0; i < codes.size(); ++i) { + cangjieBuf[i] = GetCangjieMappingSymb(codes.at(i).unicode()); + } + return QString::fromUtf16(reinterpret_cast<const char16_t *>(cangjieBuf.constData()), cangjieBuf.size()); + } +}; + +Q_GLOBAL_STATIC(CangjieConverter, cangjieConverter) + +Xt9CpIme::Xt9CpIme(Xt9RequestCallback *requestCallback) : + Xt9Ime(requestCallback) +{ +} + +Xt9KeyboardGenerator::CodeConverter *Xt9CpIme::getCangjieConverter() +{ + return cangjieConverter; +} + +void Xt9CpIme::sysInit() +{ + Xt9Ime::sysInit(); + memset(&sLingInfo, 0, sizeof(sLingInfo)); + XT9_API(ET9CPSysInit, &sLingInfo, &sWordSymbInfo, this); +} + +bool Xt9CpIme::ldbInit(ET9U32 dwFirstLdbNum, ET9U32 dwSecondLdbNum, ET9U32 eInputMode) +{ + ET9STATUS eStatus; + Q_UNUSED(dwSecondLdbNum) + + eStatus = XT9_API(ET9CPLdbInit, &sLingInfo, dwFirstLdbNum, &ET9CPLdbReadData); + if (!eStatus) { + XT9_API(ET9CPSetInputMode, &sLingInfo, static_cast<ET9CPMode>(eInputMode)); + XT9_API(ET9CPClearComponent, &sLingInfo); + XT9_API(ET9CPSetBilingual, &sLingInfo); + } + + return !eStatus; +} + +qint64 Xt9CpIme::dlmPreferredSize() const +{ + return ET9CPDLM_SIZE_NORMAL; +} + +bool Xt9CpIme::dlmInit(void *data, qint64 size) +{ + ET9STATUS eStatus; + + eStatus = XT9_API(ET9CPDLMInit, &sLingInfo, static_cast<ET9CPDLM_info *>(data), static_cast<ET9U32>(size), nullptr); + + return !eStatus; +} + +QString Xt9CpIme::exactWord(int *wordCompLen) +{ + QString exactWord = Xt9Ime::exactWord(wordCompLen); + + ET9CPPhrase phrase; + ET9CPSpell spell; + ET9U8 selSymbCount = 0; + if (!XT9_API(ET9CPGetSelection, &sLingInfo, &phrase, &spell, &selSymbCount) && selSymbCount) + exactWord.remove(0, static_cast<int>(selSymbCount)); + + replaceSpecialSymbol(exactWord); + + return exactWord; +} + +void Xt9CpIme::replaceSpecialSymbol(QString &exactWord) const +{ + for (int i = 0; i < exactWord.length(); ++i) { + ET9SYMB symb = exactWord.at(i).unicode(); + if (ET9CPSymToCPTone(symb)) { + exactWord.replace(i, 1, QChar(symb - ET9CPTONE1 + '1')); + } else if (ET9CPIsStrokeSymbol(symb)) { + int strokeIndex = symb - ET9CPSTROKE1; + static const ushort STROKE_TABLE[ET9CPSTROKEWILDCARD - ET9CPSTROKE1 + 1] = { + 0x4E00, + 0x4E28, + 0x4E3F, + 0x4E36, + 0x4E5B, + '*' + }; + exactWord.replace(i, 1, QChar(STROKE_TABLE[strokeIndex])); + } + } +} + +QString Xt9CpIme::spell() +{ + ET9STATUS eStatus; + ET9CPSpell spell; + + eStatus = XT9_API(ET9CPGetSpell, &sLingInfo, &spell); + if (eStatus == ET9STATUS_NEED_SELLIST_BUILD) { + ET9U16 gestureValue; + eStatus = XT9_API(ET9CPBuildSelectionList, &sLingInfo, &gestureValue); + if (eStatus) + return QString(); + + eStatus = XT9_API(ET9CPGetSpell, &sLingInfo, &spell); + if (eStatus) + return QString(); + } else if (eStatus) { + return QString(); + } + + QString result = QString::fromUtf16(reinterpret_cast<const char16_t *>(spell.pSymbs), spell.bLen); + + replaceSpecialSymbol(result); + + return result; +} + +QStringList Xt9CpIme::buildSelectionList(int *defaultListIndex, ET9U16 *gestureValue, ET9STATUS &eStatus) +{ + ET9U16 totalWords; + + eStatus = XT9_API(ET9CPBuildSelectionList, &sLingInfo, gestureValue); + + if (defaultListIndex) + *defaultListIndex = -1; + + if (eStatus) + return QStringList(); + + eStatus = XT9_API(ET9CPGetPhraseCount, &sLingInfo, &totalWords); + + if (defaultListIndex && totalWords > 0 && !exactWord().isEmpty()) + *defaultListIndex = 0; + + QStringList list; + for (ET9U16 i = 0; i < totalWords; ++i) { + ET9CPPhrase phrase; + ET9CPSpell spell; + ET9CPPhraseSource phraseSource; + eStatus = ET9CPGetPhrase(&sLingInfo, i, &phrase, &spell, &phraseSource); + if (eStatus) + return QStringList(); + + const QString word = QString::fromUtf16(reinterpret_cast<const char16_t *>(phrase.pSymbs), phrase.bLen); + + list.append(word); + } + + return list; +} + +ET9STATUS Xt9CpIme::selectWord(int index) +{ + ET9CPPhrase phrase; + ET9CPSpell spell; + ET9CPPhraseSource phraseSource; + ET9STATUS eStatus; + + qCDebug(lcXT9) << "selectWord" << index; + + eStatus = XT9_API(ET9CPGetPhrase, &sLingInfo, static_cast<ET9U16>(index), &phrase, &spell, &phraseSource); + if (!eStatus) { + eStatus = XT9_API(ET9CPSelectPhrase, &sLingInfo, static_cast<ET9U16>(index), &spell); + } + + return eStatus; +} + +void Xt9CpIme::cursorMoved() +{ + const ET9U32 maxBufLen = 456; + ET9SYMB buffer[maxBufLen]; + ET9_Request request; + + request.eType = ET9_REQ_BufferContext; + request.data.sBufferContextInfo.psBuf = buffer; + request.data.sBufferContextInfo.dwMaxBufLen = maxBufLen; + request.data.sBufferContextInfo.dwBufLen = static_cast<ET9U32>(-1); + + _requestCallback->request(&request); + + if (request.data.sBufferContextInfo.dwBufLen != static_cast<ET9U32>(-1)) + ET9CPSetContext(&sLingInfo, request.data.sBufferContextInfo.psBuf, request.data.sBufferContextInfo.dwBufLen); + else + ET9CPSetContext(&sLingInfo, request.data.sBufferContextInfo.psBuf, 0); +} + +void Xt9CpIme::commitSelection() +{ + XT9_API(ET9CPCommitSelection, &sLingInfo); +} + +ET9SYMB Xt9CpIme::lastSymb() +{ + const QString word = Xt9Ime::exactWord(); + const int wordLength = word.length(); + return wordLength > 0 ? word.at(wordLength - 1).unicode() : 0; +} + +bool Xt9CpIme::addTone(ET9CPSYMB symb) +{ + ET9STATUS eStatus; + + eStatus = XT9_API(ET9AddExplicitSymb, sLingInfo.Base.pWordSymbInfo, symb, 0, ET9NOSHIFT, ET9_NO_ACTIVE_INDEX); + if (eStatus) + return false; + + eStatus = XT9_API(ET9CPBuildSelectionList, &sLingInfo, nullptr); + if (eStatus) { + XT9_API(ET9ClearOneSymb, sLingInfo.Base.pWordSymbInfo); + return false; + } + + return true; +} + +ET9STATUS Xt9CpIme::ET9CPLdbReadData(ET9CPLingInfo *pLingInfo, ET9U8 *ET9FARDATA *ppbSrc, ET9U32 *pdwSizeInBytes) +{ + return reinterpret_cast<Xt9CpIme *>(pLingInfo->pPublicExtension)->ldbReadData(pLingInfo->dwLdbNum, ppbSrc, pdwSizeInBytes); +} + +} // namespace QtVirtualKeyboard +QT_END_NAMESPACE |