diff options
author | Aleksandr Andreev <aleksandr.andreev@gmail.com> | 2015-11-06 11:31:40 +0300 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2015-11-27 13:00:31 +0000 |
commit | 33a774bb1ff7b1af48b3a534b53dd3843a279eac (patch) | |
tree | 2b4eeb380272d67ce9ba626c54aad3cf1cda5b66 /i18npool | |
parent | b33236bfd25333513823e69fac1bc833ee4b5f6e (diff) |
Adding native number support for Cyrillic numerals
Change-Id: I054786a97b6f0e6ba3fe3b824ff9ff9748d8be4a
Reviewed-on: https://gerrit.libreoffice.org/20013
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Eike Rathke <erack@redhat.com>
Diffstat (limited to 'i18npool')
-rw-r--r-- | i18npool/source/localedata/data/cu_RU.xml | 150 | ||||
-rw-r--r-- | i18npool/source/nativenumber/data/numberchar.h | 7 | ||||
-rw-r--r-- | i18npool/source/nativenumber/nativenumbersupplier.cxx | 131 |
3 files changed, 284 insertions, 4 deletions
diff --git a/i18npool/source/localedata/data/cu_RU.xml b/i18npool/source/localedata/data/cu_RU.xml index d4dde4665dc9..fd28ddfeeeab 100644 --- a/i18npool/source/localedata/data/cu_RU.xml +++ b/i18npool/source/localedata/data/cu_RU.xml @@ -52,7 +52,155 @@ <TimePM>по по́лꙋд.</TimePM> <MeasurementSystem>metric</MeasurementSystem> </LC_CTYPE> - <LC_FORMAT ref="ru_RU" replaceFrom="[CURRENCY]" replaceTo="[$р.-694]" /> + <LC_FORMAT replaceFrom="[CURRENCY]" replaceTo="[$р.-694]"> + <DateAcceptancePattern>D.M.</DateAcceptancePattern> + <DateAcceptancePattern>D/M/</DateAcceptancePattern> + <FormatElement msgid="FixedFormatskey1" default="true" type="medium" usage="FIXED_NUMBER" formatindex="0"> + <FormatCode>General</FormatCode> + </FormatElement> + <FormatElement msgid="FixedFormatskey2" default="true" type="short" usage="FIXED_NUMBER" formatindex="1"> + <FormatCode>0</FormatCode> + </FormatElement> + <FormatElement msgid="FixedFormatskey3" default="false" type="medium" usage="FIXED_NUMBER" formatindex="2"> + <FormatCode>0,00</FormatCode> + </FormatElement> + <FormatElement msgid="FixedFormatskey4" default="false" type="short" usage="FIXED_NUMBER" formatindex="3"> + <FormatCode># ##0</FormatCode> + </FormatElement> + <FormatElement msgid="FixedFormatskey5" default="false" type="medium" usage="FIXED_NUMBER" formatindex="4"> + <FormatCode># ##0,00</FormatCode> + </FormatElement> + <FormatElement msgid="FixedFormatskey6" default="false" type="medium" usage="FIXED_NUMBER" formatindex="5"> + <FormatCode># ###,00</FormatCode> + </FormatElement> + <FormatElement msgid="FixedFormatskey7" default="false" type="medium" usage="FIXED_NUMBER" formatindex="59"> + <FormatCode>[NatNum1]0;-0</FormatCode> + </FormatElement> + <FormatElement msgid="ScientificFormatskey1" default="false" type="medium" usage="SCIENTIFIC_NUMBER" formatindex="6"> + <FormatCode>0,00E+000</FormatCode> + </FormatElement> + <FormatElement msgid="ScientificFormatskey2" default="true" type="medium" usage="SCIENTIFIC_NUMBER" formatindex="7"> + <FormatCode>0,00E+00</FormatCode> + </FormatElement> + <FormatElement msgid="ScientificFormatskey3" default="false" type="medium" usage="SCIENTIFIC_NUMBER" formatindex="78"> + <FormatCode>##0,00E+00</FormatCode> + </FormatElement> + <FormatElement msgid="PercentFormatskey1" default="true" type="short" usage="PERCENT_NUMBER" formatindex="8"> + <FormatCode>0%</FormatCode> + </FormatElement> + <FormatElement msgid="PercentFormatskey2" default="true" type="long" usage="PERCENT_NUMBER" formatindex="9"> + <FormatCode>0,00%</FormatCode> + </FormatElement> + <FormatElement msgid="CurrencyFormatskey1" default="true" type="short" usage="CURRENCY" formatindex="12"> + <FormatCode># ##0 [CURRENCY];-# ##0 [CURRENCY]</FormatCode> + </FormatElement> + <FormatElement msgid="CurrencyFormatskey2" default="false" type="medium" usage="CURRENCY" formatindex="13"> + <FormatCode># ##0,00 [CURRENCY];-# ##0,00 [CURRENCY]</FormatCode> + </FormatElement> + <FormatElement msgid="CurrencyFormatskey3" default="false" type="medium" usage="CURRENCY" formatindex="14"> + <FormatCode># ##0 [CURRENCY];[RED]-# ##0 [CURRENCY]</FormatCode> + </FormatElement> + <FormatElement msgid="CurrencyFormatskey4" default="true" type="medium" usage="CURRENCY" formatindex="15"> + <FormatCode># ##0,00 [CURRENCY];[RED]-# ##0,00 [CURRENCY]</FormatCode> + </FormatElement> + <FormatElement msgid="CurrencyFormatskey5" default="false" type="medium" usage="CURRENCY" formatindex="16"> + <FormatCode># ##0,00 CCC</FormatCode> + </FormatElement> + <FormatElement msgid="CurrencyFormatskey6" default="false" type="medium" usage="CURRENCY" formatindex="17"> + <FormatCode># ##0,-- [CURRENCY];[RED]-# ##0,-- [CURRENCY]</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey1" default="true" type="short" usage="DATE" formatindex="18"> + <FormatCode>D.M.YY</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey9" default="true" type="long" usage="DATE" formatindex="19"> + <FormatCode>NNNNDD MMMM, YYYY</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey8" default="true" type="medium" usage="DATE" formatindex="20"> + <FormatCode>[NatNum1]DD.MM.YY</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey7" default="false" type="medium" usage="DATE" formatindex="21"> + <FormatCode>[NatNum1]DD.MM.YYYY</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey10" default="false" type="long" usage="DATE" formatindex="22"> + <FormatCode>[NatNum1]D MMM, YY</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey11" default="false" type="long" usage="DATE" formatindex="23"> + <FormatCode>[NatNum1]D MMM, YYYY</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey16" default="false" type="long" usage="DATE" formatindex="24"> + <FormatCode>[NatNum1]D. MMM. YYYY</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey12" default="false" type="long" usage="DATE" formatindex="25"> + <FormatCode>[NatNum1]D MMMM, YYYY</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey17" default="false" type="long" usage="DATE" formatindex="26"> + <FormatCode>[NatNum1]D. MMMM YYYY</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey13" default="false" type="long" usage="DATE" formatindex="27"> + <FormatCode>[NatNum1]NN, D MMM, YY</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey2" default="false" type="medium" usage="DATE" formatindex="28"> + <FormatCode>[NatNum1]NN DD.MMM YY</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey14" default="false" type="long" usage="DATE" formatindex="29"> + <FormatCode>[NatNum1]NN, D MMMM, YYYY</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey15" default="false" type="long" usage="DATE" formatindex="30"> + <FormatCode>[NatNum1]NNNND MMMM, YYYY</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey18" default="false" type="short" usage="DATE" formatindex="31"> + <FormatCode>MM-DD</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey19" default="false" type="medium" usage="DATE" formatindex="32"> + <FormatCode>YY-MM-DD</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey20" default="false" type="medium" usage="DATE" formatindex="33"> + <FormatCode>YYYY-MM-DD</FormatCode> + <DefaultName>ISO 8601</DefaultName> + </FormatElement> + <FormatElement msgid="DateFormatskey3" default="false" type="medium" usage="DATE" formatindex="34"> + <FormatCode>MM.YY</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey4" default="false" type="medium" usage="DATE" formatindex="35"> + <FormatCode>DD.MMM</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey5" default="false" type="medium" usage="DATE" formatindex="36"> + <FormatCode>MMMM</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey6" default="false" type="medium" usage="DATE" formatindex="37"> + <FormatCode>QQ YY</FormatCode> + </FormatElement> + <FormatElement msgid="DateFormatskey21" default="false" type="medium" usage="DATE" formatindex="38"> + <FormatCode>WW</FormatCode> + </FormatElement> + <FormatElement msgid="TimeFormatskey1" default="true" type="short" usage="TIME" formatindex="39"> + <FormatCode>HH:MM</FormatCode> + </FormatElement> + <FormatElement msgid="TimeFormatskey2" default="true" type="medium" usage="TIME" formatindex="40"> + <FormatCode>HH:MM:SS</FormatCode> + </FormatElement> + <FormatElement msgid="TimeFormatskey3" default="false" type="short" usage="TIME" formatindex="41"> + <FormatCode>HH:MM AM/PM</FormatCode> + </FormatElement> + <FormatElement msgid="TimeFormatskey4" default="false" type="medium" usage="TIME" formatindex="42"> + <FormatCode>HH:MM:SS AM/PM</FormatCode> + </FormatElement> + <FormatElement msgid="TimeFormatskey5" default="false" type="medium" usage="TIME" formatindex="43"> + <FormatCode>[HH]:MM:SS</FormatCode> + </FormatElement> + <FormatElement msgid="TimeFormatskey6" default="false" type="short" usage="TIME" formatindex="44"> + <FormatCode>MM:SS,00</FormatCode> + </FormatElement> + <FormatElement msgid="TimeFormatskey7" default="false" type="medium" usage="TIME" formatindex="45"> + <FormatCode>[HH]:MM:SS,00</FormatCode> + </FormatElement> + <FormatElement msgid="DateTimeFormatskey1" default="true" type="medium" usage="DATE_TIME" formatindex="46"> + <FormatCode>DD.MM.YY HH:MM</FormatCode> + </FormatElement> + <FormatElement msgid="DateTimeFormatskey2" default="false" type="medium" usage="DATE_TIME" formatindex="47"> + <FormatCode>DD.MM.YYYY HH:MM:SS</FormatCode> + </FormatElement> + </LC_FORMAT> <LC_COLLATION> <Collator unoid="charset" default="true"/> <CollationOptions> diff --git a/i18npool/source/nativenumber/data/numberchar.h b/i18npool/source/nativenumber/data/numberchar.h index cd22f12fd2bd..62e490fd71e1 100644 --- a/i18npool/source/nativenumber/data/numberchar.h +++ b/i18npool/source/nativenumber/data/numberchar.h @@ -53,7 +53,8 @@ static const sal_Int16 NumberChar_mn = 27; static const sal_Int16 NumberChar_he = 28; static const sal_Int16 NumberChar_ne = 29; static const sal_Int16 NumberChar_dz = 30; -static const sal_Int16 NumberChar_Count = 31; +static const sal_Int16 NumberChar_cu = 31; +static const sal_Int16 NumberChar_Count = 32; static const sal_Unicode NumberChar[][10] = { // 0 1 2 3 4 5 6 7 8 9 @@ -88,6 +89,7 @@ static const sal_Unicode NumberChar[][10] = { { 0x0020, 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8 }, // Hebrew { 0x0966, 0x0967, 0x0968, 0x0969, 0x096A, 0x096B, 0x096C, 0x096D, 0x096E, 0x096F }, // Nepali { 0x0F20, 0x0F21, 0x0F22, 0x0F23, 0x0F24, 0x0F25, 0x0F26, 0x0F27, 0x0F28, 0x0F29 }, // Dzongkha + { 0x0030, 0x0430, 0x0432, 0x0433, 0x0434, 0x0454, 0x0455, 0x0437, 0x0438, 0x0473 }, // Church Slavic }; static sal_Unicode DecimalChar[] = { @@ -122,6 +124,7 @@ static sal_Unicode DecimalChar[] = { 0x0000, // Hebrew 0x0000, // Nepali 0x0000, // Dzongkha + 0x0000, // Church Slavic }; static const sal_Unicode MinusChar[] = { @@ -156,6 +159,7 @@ static const sal_Unicode MinusChar[] = { 0x0000, // Hebrew 0x0000, // Nepali 0x0000, // Dzongkha + 0x0000, // Church Slavic }; static sal_uInt16 SeparatorChar[] = { @@ -190,6 +194,7 @@ static sal_uInt16 SeparatorChar[] = { 0x0000, // Hebrew 0x0000, // Nepali 0x0000, // Dzongkha + 0x0000, // Church Slavic }; #define NUMBER_ZERO NumberChar[NumberChar_HalfWidth][0] // 0x0030 diff --git a/i18npool/source/nativenumber/nativenumbersupplier.cxx b/i18npool/source/nativenumber/nativenumbersupplier.cxx index 76f421433ecd..94b5a78c3f42 100644 --- a/i18npool/source/nativenumber/nativenumbersupplier.cxx +++ b/i18npool/source/nativenumber/nativenumbersupplier.cxx @@ -59,6 +59,8 @@ namespace com { namespace sun { namespace star { namespace i18n { OUString SAL_CALL getHebrewNativeNumberString(const OUString& aNumberString, bool useGeresh); +OUString SAL_CALL getCyrillicNativeNumberString(const OUString& aNumberString); + OUString SAL_CALL AsciiToNativeChar( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount, Sequence< sal_Int32 >& offset, bool useOffset, sal_Int16 number ) throw(RuntimeException) { @@ -458,7 +460,8 @@ static const sal_Char *natnum1Locales[] = { "mn", "ne", "dz", - "fa" + "fa", + "cu" }; static sal_Int16 nbOfLocale = SAL_N_ELEMENTS(natnum1Locales); @@ -489,7 +492,8 @@ static const sal_Int16 natnum1[] = { NumberChar_mn, NumberChar_ne, NumberChar_dz, - NumberChar_EastIndic_ar + NumberChar_EastIndic_ar, + NumberChar_cu }; static const sal_Int16 sizeof_natnum1 = SAL_N_ELEMENTS(natnum1); @@ -592,6 +596,8 @@ OUString SAL_CALL NativeNumberSupplierService::getNativeNumberString(const OUStr else if (num == NumberChar_he) return getHebrewNativeNumberString(aNumberString, nNativeNumberMode == NativeNumberMode::NATNUM2); + else if (num == NumberChar_cu) + return getCyrillicNativeNumberString(aNumberString); else return AsciiToNativeChar(aNumberString, 0, aNumberString.getLength(), offset, useOffset, num); } @@ -902,6 +908,127 @@ OUString SAL_CALL getHebrewNativeNumberString(const OUString& aNumberString, boo return aNumberString; } +// Support for Cyrillic Numerals +// See UTN 41 for implementation information +// http://www.unicode.org/notes/tn41/ + +static sal_Unicode cyrillicThousandsMark = 0x0482; +static sal_Unicode cyrillicTitlo = 0x0483; +static sal_Unicode cyrillicTen = 0x0456; + +struct CyrillicNumberChar { + sal_Unicode code; + sal_Int16 value; +} CyrillicNumberCharArray[] = { + { 0x0446, 900 }, + { 0x047f, 800 }, + { 0x0471, 700 }, + { 0x0445, 600 }, + { 0x0444, 500 }, + { 0x0443, 400 }, + { 0x0442, 300 }, + { 0x0441, 200 }, + { 0x0440, 100 }, + { 0x0447, 90 }, + { 0x043f, 80 }, + { 0x047b, 70 }, + { 0x046f, 60 }, + { 0x043d, 50 }, + { 0x043c, 40 }, + { 0x043b, 30 }, + { 0x043a, 20 }, + { 0x0456, 10 }, + { 0x0473, 9 }, + { 0x0438, 8 }, + { 0x0437, 7 }, + { 0x0455, 6 }, + { 0x0454, 5 }, + { 0x0434, 4 }, + { 0x0433, 3 }, + { 0x0432, 2 }, + { 0x0430, 1 } +}; + +static sal_Int16 nbOfCyrillicNumberChar = sizeof(CyrillicNumberCharArray)/sizeof(CyrillicNumberChar); + +void makeCyrillicNumber(sal_Int64 value, OUStringBuffer& output, bool addTitlo) +{ + sal_Int16 num = sal::static_int_cast<sal_Int16>(value % 1000); + if (value >= 1000) { + output.append(cyrillicThousandsMark); + makeCyrillicNumber(value / 1000, output, false); + if (value >= 10000 && (value - 10000) % 1000 != 0) { + output.append(" "); + } + if (value % 1000 == 0) + addTitlo = false; + } + + for (sal_Int32 j = 0; num > 0 && j < nbOfCyrillicNumberChar; j++) { + if (num < 20 && num > 10) { + num -= 10; + makeCyrillicNumber(num, output, false); + output.append(cyrillicTen); + break; + } + + if (CyrillicNumberCharArray[j].value <= num) { + output.append(CyrillicNumberCharArray[j].code); + num = sal::static_int_cast<sal_Int16>( num - CyrillicNumberCharArray[j].value ); + } + } + + if (addTitlo) { + if (output.getLength() == 1) { + output.append(cyrillicTitlo); + } else if (output.getLength() == 2) { + if (value > 800 && value < 900) { + output.append(cyrillicTitlo); + } else { + output.insert(1, cyrillicTitlo); + } + } else if (output.getLength() > 2) { + if (output.indexOf(" ") == output.getLength() - 2) { + output.append(cyrillicTitlo); + } else { + output.insert(output.getLength() - 1, cyrillicTitlo); + } + } + } +} + +OUString SAL_CALL getCyrillicNativeNumberString(const OUString& aNumberString) +{ + sal_Int64 value = 0; + sal_Int32 i, count = 0, len = aNumberString.getLength(); + const sal_Unicode *src = aNumberString.getStr(); + + for (i = 0; i < len; i++) { + sal_Unicode ch = src[i]; + if (isNumber(ch)) { + if (++count >= 8) // Number is too long, could not be handled. + return aNumberString; + value = value * 10 + (ch - NUMBER_ZERO); + } + else if (isSeparator(ch) && count > 0) continue; + else if (isMinus(ch) && count == 0) continue; + else break; + } + + if (value > 0) { + OUStringBuffer output(count*2 + 2 + len - i); + + makeCyrillicNumber(value, output, true); + + if (i < len) + output.append(aNumberString.copy(i)); + + return output.makeStringAndClear(); + } + else + return aNumberString; +} + static const sal_Char* implementationName = "com.sun.star.i18n.NativeNumberSupplier"; OUString SAL_CALL NativeNumberSupplierService::getImplementationName() throw( RuntimeException, std::exception ) |