diff options
Diffstat (limited to 'i18npool/source')
-rw-r--r-- | i18npool/source/defaultnumberingprovider/defaultnumberingprovider.cxx | 66 | ||||
-rw-r--r-- | i18npool/source/nativenumber/nativenumbersupplier.cxx | 107 |
2 files changed, 115 insertions, 58 deletions
diff --git a/i18npool/source/defaultnumberingprovider/defaultnumberingprovider.cxx b/i18npool/source/defaultnumberingprovider/defaultnumberingprovider.cxx index e222611a2afe..af4e27d0f69f 100644 --- a/i18npool/source/defaultnumberingprovider/defaultnumberingprovider.cxx +++ b/i18npool/source/defaultnumberingprovider/defaultnumberingprovider.cxx @@ -19,7 +19,6 @@ #include <defaultnumberingprovider.hxx> #include <com/sun/star/lang/IllegalArgumentException.hpp> -#include <com/sun/star/linguistic2/NumberText.hpp> #include <com/sun/star/style/NumberingType.hpp> #include <com/sun/star/beans/PropertyValue.hpp> #include <com/sun/star/configuration/theDefaultProvider.hpp> @@ -32,9 +31,6 @@ #include <string.h> #include <comphelper/propertysequence.hxx> #include <cppuhelper/supportsservice.hxx> -#include <i18nlangtag/languagetag.hxx> -#include <unordered_map> -#include <map> // Cyrillic upper case #define C_CYR_A "\xD0\x90" @@ -588,6 +584,7 @@ DefaultNumberingProvider::makeNumberingString( const Sequence<beans::PropertyVal sal_Int16 tableSize = 0; const sal_Unicode *table = nullptr; // initialize to avoid compiler warning bool bRecycleSymbol = false; + bool bCapitalize = false; Locale locale; OUString prefix; @@ -639,45 +636,20 @@ DefaultNumberingProvider::makeNumberingString( const Sequence<beans::PropertyVal lcl_formatChars( lowerLetter, 26, number-1, result ); break; case TEXT_NUMBER: + natNum = NativeNumberMode::NATNUM14; // ordinal indicators (1st, 2nd, 3rd, ...) + locale = aLocale; + bCapitalize = true; + break; case TEXT_CARDINAL: + natNum = NativeNumberMode::NATNUM12; // cardinal number names (one, two, three, ...) + locale = aLocale; + bCapitalize = true; + break; case TEXT_ORDINAL: - { - static css::uno::Reference< css::linguistic2::XNumberText > xNumberText; - if (!xNumberText.is()) - xNumberText = linguistic2::NumberText::create( m_xContext ); - OUString aLoc = LanguageTag::convertToBcp47(aLocale); - OUString numbertext_prefix = ""; - if (numType == TEXT_NUMBER) - numbertext_prefix += "ordinal-number "; - else if (numType == TEXT_ORDINAL) - 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<sal_Int32,std::map<OUString, OUString> > aBuff; - auto aBuffItem = aBuff.find(number); - std::map<OUString, OUString> aItem; - if (aBuffItem == aBuff.end() || !aBuffItem->second.count(numbertext_prefix + aLoc)) - { - OUString snumber = OUString::number(number); - OUString aNum = - xNumberText->getNumberText( numbertext_prefix + snumber, aLocale); - if ( !xCharClass.is() ) - xCharClass = CharacterClassification::create( m_xContext ); - // use number at missing number to text conversion - if (aNum.getLength() == 0) - aNum = snumber; - // capitalize first letter - aItem[numbertext_prefix + aLoc] = xCharClass->toTitle(aNum, 0, 1, aLocale) + aNum.copy(1); - aBuff.insert(std::make_pair(number, aItem)); - } - else - { - aItem = aBuffItem->second; - } - result += aItem[numbertext_prefix + aLoc]; - break; - } + natNum = NativeNumberMode::NATNUM13; // ordinal number names (first, second, third, ...) + locale = aLocale; + bCapitalize = true; + break; case ROMAN_UPPER: result += toRoman( number ); break; @@ -937,7 +909,17 @@ DefaultNumberingProvider::makeNumberingString( const Sequence<beans::PropertyVal if (natNum) { rtl::Reference<NativeNumberSupplierService> xNatNum(new NativeNumberSupplierService); - result += xNatNum->getNativeNumberString(OUString::number( number ), locale, natNum); + OUString aNum + = xNatNum->getNativeNumberString(OUString::number(number), locale, natNum); + if (bCapitalize) + { + if (!xCharClass.is()) + xCharClass = CharacterClassification::create(m_xContext); + // capitalize first letter + result += xCharClass->toTitle(aNum, 0, 1, aLocale) + aNum.copy(1); + } + else + result += aNum; } else if (tableSize) { if ( number > tableSize && !bRecycleSymbol) result += OUString::number( number); 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); |