summaryrefslogtreecommitdiff
path: root/i18npool/source/nativenumber
diff options
context:
space:
mode:
authorAleksandr Andreev <aleksandr.andreev@gmail.com>2015-11-06 11:31:40 +0300
committerEike Rathke <erack@redhat.com>2015-11-27 13:00:31 +0000
commit33a774bb1ff7b1af48b3a534b53dd3843a279eac (patch)
tree2b4eeb380272d67ce9ba626c54aad3cf1cda5b66 /i18npool/source/nativenumber
parentb33236bfd25333513823e69fac1bc833ee4b5f6e (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/source/nativenumber')
-rw-r--r--i18npool/source/nativenumber/data/numberchar.h7
-rw-r--r--i18npool/source/nativenumber/nativenumbersupplier.cxx131
2 files changed, 135 insertions, 3 deletions
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 )