diff options
Diffstat (limited to 'i18npool/source/nativenumber/nativenumbersupplier.cxx')
-rw-r--r-- | i18npool/source/nativenumber/nativenumbersupplier.cxx | 107 |
1 files changed, 91 insertions, 16 deletions
diff --git a/i18npool/source/nativenumber/nativenumbersupplier.cxx b/i18npool/source/nativenumber/nativenumbersupplier.cxx index 6dc7c792c931..f3c40a2b7d61 100644 --- a/i18npool/source/nativenumber/nativenumbersupplier.cxx +++ b/i18npool/source/nativenumber/nativenumbersupplier.cxx @@ -17,6 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <i18nlangtag/languagetag.hxx> #include <i18nlangtag/mslangid.hxx> #include <rtl/ustrbuf.hxx> #include <sal/macros.h> @@ -24,8 +25,12 @@ #include <localedata.hxx> #include "data/numberchar.h" #include <comphelper/string.hxx> +#include <comphelper/processfactory.hxx> #include <cppuhelper/supportsservice.hxx> +#include <map> #include <memory> +#include <unordered_map> +#include <com/sun/star/linguistic2/NumberText.hpp> using namespace ::com::sun::star::uno; using namespace ::com::sun::star::i18n; @@ -250,7 +255,10 @@ OUString AsciiToNative( const OUString& inStr, sal_Int32 nCount, } return aRet; } -static void NativeToAscii_numberMaker(sal_Int16 max, sal_Int16 prev, const sal_Unicode *str, + +namespace +{ +void NativeToAscii_numberMaker(sal_Int16 max, sal_Int16 prev, const sal_Unicode *str, sal_Int32& i, sal_Int32 nCount, sal_Unicode *dst, sal_Int32& count, Sequence< sal_Int32 >& offset, bool useOffset, OUString& numberChar, OUString& multiplierChar) { @@ -300,7 +308,7 @@ static void NativeToAscii_numberMaker(sal_Int16 max, sal_Int16 prev, const sal_U } /// @throws RuntimeException -static OUString NativeToAscii(const OUString& inStr, +OUString NativeToAscii(const OUString& inStr, sal_Int32 nCount, Sequence< sal_Int32 >& offset, bool useOffset ) { OUString aRet; @@ -374,7 +382,7 @@ static OUString NativeToAscii(const OUString& inStr, return aRet; } -static const Number natnum4[4] = { +const Number natnum4[4] = { { NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh], 0, ExponentCount_6_CJK, MultiplierExponent_6_CJK }, { NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh_TW], 0, @@ -385,7 +393,7 @@ static const Number natnum4[4] = { ExponentCount_6_CJK, MultiplierExponent_6_CJK }, }; -static const Number natnum5[4] = { +const Number natnum5[4] = { { NumberChar_Upper_zh, MultiplierChar_6_CJK[Multiplier_Upper_zh], 0, ExponentCount_6_CJK, MultiplierExponent_6_CJK }, { NumberChar_Upper_zh_TW, MultiplierChar_6_CJK[Multiplier_Upper_zh_TW], 0, @@ -396,7 +404,7 @@ static const Number natnum5[4] = { ExponentCount_6_CJK, MultiplierExponent_6_CJK }, }; -static const Number natnum6[4] = { +const Number natnum6[4] = { { NumberChar_FullWidth, MultiplierChar_6_CJK[Multiplier_Lower_zh], 0, ExponentCount_6_CJK, MultiplierExponent_6_CJK }, { NumberChar_FullWidth, MultiplierChar_6_CJK[Multiplier_Lower_zh_TW], 0, @@ -407,7 +415,7 @@ static const Number natnum6[4] = { ExponentCount_6_CJK, MultiplierExponent_6_CJK }, }; -static const Number natnum7[4] = { +const Number natnum7[4] = { { NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh], NUMBER_OMIT_ALL, ExponentCount_6_CJK, MultiplierExponent_6_CJK }, { NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh_TW], NUMBER_OMIT_ALL, @@ -418,7 +426,7 @@ static const Number natnum7[4] = { ExponentCount_6_CJK, MultiplierExponent_6_CJK }, }; -static const Number natnum8[4] = { +const Number natnum8[4] = { { NumberChar_Upper_zh, MultiplierChar_6_CJK[Multiplier_Upper_zh], NUMBER_OMIT_ALL, ExponentCount_6_CJK, MultiplierExponent_6_CJK }, { NumberChar_Upper_zh_TW, MultiplierChar_6_CJK[Multiplier_Upper_zh_TW], NUMBER_OMIT_ALL, @@ -429,14 +437,14 @@ static const Number natnum8[4] = { ExponentCount_6_CJK, MultiplierExponent_6_CJK }, }; -static const Number natnum10 = { NumberChar_Hangul_ko, MultiplierChar_6_CJK[Multiplier_Hangul_ko], NUMBER_OMIT_ZERO, +const Number natnum10 = { NumberChar_Hangul_ko, MultiplierChar_6_CJK[Multiplier_Hangul_ko], NUMBER_OMIT_ZERO, ExponentCount_6_CJK, MultiplierExponent_6_CJK }; -static const Number natnum11 = { NumberChar_Hangul_ko, MultiplierChar_6_CJK[Multiplier_Hangul_ko], NUMBER_OMIT_ALL, +const Number natnum11 = { NumberChar_Hangul_ko, MultiplierChar_6_CJK[Multiplier_Hangul_ko], NUMBER_OMIT_ALL, ExponentCount_6_CJK, MultiplierExponent_6_CJK }; //! ATTENTION: Do not change order of elements! //! Append new languages to the end of the list! -static const sal_Char *natnum1Locales[] = { +const sal_Char *natnum1Locales[] = { "zh_CN", "zh_TW", "ja", @@ -464,11 +472,11 @@ static const sal_Char *natnum1Locales[] = { "fa", "cu" }; -static sal_Int16 nbOfLocale = SAL_N_ELEMENTS(natnum1Locales); +sal_Int16 nbOfLocale = SAL_N_ELEMENTS(natnum1Locales); //! ATTENTION: Do not change order of elements! //! Number and order must match elements of natnum1Locales! -static const sal_Int16 natnum1[] = { +const sal_Int16 natnum1[] = { NumberChar_Lower_zh, NumberChar_Lower_zh, NumberChar_Modern_ja, @@ -496,20 +504,20 @@ static const sal_Int16 natnum1[] = { NumberChar_EastIndic_ar, NumberChar_cu }; -static const sal_Int16 sizeof_natnum1 = SAL_N_ELEMENTS(natnum1); +const sal_Int16 sizeof_natnum1 = SAL_N_ELEMENTS(natnum1); //! ATTENTION: Do not change order of elements! //! Order must match first elements of natnum1Locales! -static const sal_Int16 natnum2[] = { +const sal_Int16 natnum2[] = { NumberChar_Upper_zh, NumberChar_Upper_zh_TW, NumberChar_Traditional_ja, NumberChar_Upper_ko, NumberChar_he }; -static const sal_Int16 sizeof_natnum2 = SAL_N_ELEMENTS(natnum2); +const sal_Int16 sizeof_natnum2 = SAL_N_ELEMENTS(natnum2); -static sal_Int16 getLanguageNumber( const Locale& rLocale) +sal_Int16 getLanguageNumber( const Locale& rLocale) { // return zh_TW for TW, HK and MO, return zh_CN for other zh locales. if (rLocale.Language == "zh") return MsLangId::isTraditionalChinese(rLocale) ? 1 : 0; @@ -521,12 +529,76 @@ static sal_Int16 getLanguageNumber( const Locale& rLocale) return -1; } +OUString getNumberText(const Locale& aLocale, sal_Int16 numType, const OUString& rNumberString) +{ + assert(numType == NativeNumberMode::NATNUM12 || numType == NativeNumberMode::NATNUM13 + || numType == NativeNumberMode::NATNUM14); + + sal_Int32 i, count = 0; + const sal_Int32 len = rNumberString.getLength(); + const sal_Unicode* src = rNumberString.getStr(); + + OUStringBuffer sBuf(len); + for (i = 0; i < len; i++) + { + sal_Unicode ch = src[i]; + if (isNumber(ch)) + { + ++count; + sBuf.append(ch); + } + else if (isSeparator(ch) && count > 0) + continue; + else if (isMinus(ch) && count == 0) + sBuf.append(ch); + else + break; + } + + if (count == 0) + return rNumberString; + + OUString aNumberStr = sBuf.makeStringAndClear(); + + static auto xNumberText + = css::linguistic2::NumberText::create(comphelper::getProcessComponentContext()); + OUString aLoc = LanguageTag::convertToBcp47(aLocale); + OUString numbertext_prefix; + if (numType == NativeNumberMode::NATNUM14) + numbertext_prefix = "ordinal-number "; + else if (numType == NativeNumberMode::NATNUM13) + numbertext_prefix = "ordinal "; + // Several hundreds of headings could result typing lags because + // of the continuous update of the multiple number names during typing. + // We fix this by buffering the result of the conversion. + static std::unordered_map<OUString, std::map<OUString, OUString>> aBuff; + auto& rItems = aBuff[aNumberStr]; + auto& rItem = rItems[numbertext_prefix + aLoc]; + if (rItem.isEmpty()) + { + rItem = xNumberText->getNumberText(numbertext_prefix + aNumberStr, aLocale); + // use number at missing number to text conversion + if (rItem.isEmpty()) + rItem = aNumberStr; + } + OUString sResult = rItem; + if (i < len) + sResult += rNumberString.copy(i); + return sResult; +} +} + OUString NativeNumberSupplierService::getNativeNumberString(const OUString& aNumberString, const Locale& rLocale, sal_Int16 nNativeNumberMode, Sequence< sal_Int32 >& offset) { if (!isValidNatNum(rLocale, nNativeNumberMode)) return aNumberString; + if (nNativeNumberMode == NativeNumberMode::NATNUM12 + || nNativeNumberMode == NativeNumberMode::NATNUM13 + || nNativeNumberMode == NativeNumberMode::NATNUM14) + return getNumberText(rLocale, nNativeNumberMode, aNumberString); + sal_Int16 langnum = getLanguageNumber(rLocale); if (langnum == -1) return aNumberString; @@ -664,6 +736,9 @@ sal_Bool SAL_CALL NativeNumberSupplierService::isValidNatNum( const Locale& rLoc switch (nNativeNumberMode) { case NativeNumberMode::NATNUM0: // Ascii case NativeNumberMode::NATNUM3: // Char, FullWidth + case NativeNumberMode::NATNUM12: // Cardinal number names (one, two, three, ...) + case NativeNumberMode::NATNUM13: // Ordinal number names (first, second, third, ...) + case NativeNumberMode::NATNUM14: // Ordinal indicators (1st, 2nd, 3rd, ...) return true; case NativeNumberMode::NATNUM1: // Char, Lower return (langnum >= 0); |