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>
This commit is contained in:
committed by
Eike Rathke
parent
b33236bfd2
commit
33a774bb1f
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 )
|
||||
|
||||
Reference in New Issue
Block a user