diff options
author | Naruhiko Ogasawara <naruoga@gmail.com> | 2020-05-06 20:55:49 +0900 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2020-05-25 22:51:22 +0200 |
commit | 9efd7cd637d9d882f2fc8277b657ec117c591e80 (patch) | |
tree | 0b68c76e33f30cc94eea9d7d409ae47b11f109d8 /svl | |
parent | 20f3a7e461381eb0db3e4ff526b69f3b1185c1c9 (diff) |
tdf#130193: Asian Excel-Calc number format interop
remap NatNum - DBNum in Japanese/Chinese to improve
Excel interoprability
from DBNum to NatNum (import) in ja/zh:
- DBNum1 -> NatNum4 (modern long Kanji text)
- DBNum2 -> NatNum5 (traditional long Kanji text)
- DBNum3 -> NatNum3 (fullwidth Arabic digits)
from NatNum to DBNum (export) in ja:
- NatNum1 -> DBNum1
- NatNum2 -> DBNum2
- NatNum3 -> DBNum3
- NatNum4 -> DBNum1
- NatNum5 -> DBNum2
- NatNum6 -> DBNum3
- NatNum7 -> DBNum1
- NatNum8 -> DBNum2
- NatNum9 -> (DBNum0, as Arabic)
in zh, nothing change about export.
It also partially solves the issue tdf#130140
(about Japanese, not Korean)
To do this, more data-drivened MapDBNumToNatNum() and
MapNatNumToDBNum() in svl/source/numbers/zformat.cxx
By mapping "NatNum - DBNum" to a table using map and array, it
makes the specification for each language more understandable
The new test cases are also included in svl/qa/unit/svl.cxx
Change-Id: I34a70d970ef2e46c1b3db5db1c397ab89c056191
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94376
Tested-by: Jenkins
Reviewed-by: Eike Rathke <erack@redhat.com>
Diffstat (limited to 'svl')
-rw-r--r-- | svl/qa/unit/svl.cxx | 91 | ||||
-rw-r--r-- | svl/source/numbers/zformat.cxx | 96 |
2 files changed, 111 insertions, 76 deletions
diff --git a/svl/qa/unit/svl.cxx b/svl/qa/unit/svl.cxx index fc541861f182..80be2b2af79a 100644 --- a/svl/qa/unit/svl.cxx +++ b/svl/qa/unit/svl.cxx @@ -1453,6 +1453,97 @@ void Test::testUserDefinedNumberFormats() checkPreviewString(aFormatter, sCode, M_PI, eLang, sExpected); #endif } + { // tdf#130193 tdf#130140 Native Number Formats mapping for Chinese (Traditonal), Japanese, Korean + // -- Traditional Chinese: DBNum1 -> NatNum4, DBNum2 -> NatNum5, DBnum3 -> NatNum3 + + // DBNum1 -> NatNum4: Chinese lower case text for 123456789 + // 一億二千三百四十五萬六千七百八十九 + sExpected = u"\u4e00\u5104\u4e8c\u5343\u4e09\u767e\u56db\u5341\u4e94\u842c\u516d\u5343" + u"\u4e03\u767e\u516b\u5341\u4e5d "; + sCode = "[NatNum4][$-0404]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + sCode = "[DBNum1][$-0404]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + + // DBNum2 -> NatNum5: Chinese upper case text + // 壹億貳仟參佰肆拾伍萬陸仟柒佰捌拾玖 + sExpected = u"\u58f9\u5104\u8cb3\u4edf\u53c3\u4f70\u8086\u62fe\u4f0d\u842c\u9678\u4edf" + u"\u67d2\u4f70\u634c\u62fe\u7396 "; + sCode = "[NatNum5][$-0404]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + sCode = "[DBNum2][$-0404]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + + // DBNum3 -> NatNum3: fullwidth text + // 123456789 + sExpected = u"\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19 "; + sCode = "[NatNum3][$-0404]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + sCode = "[DBNum3][$-0404]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + + // -- Japanese: DBNum1 -> NatNum4, DBNum2 -> NatNum5, DBnum3 -> NatNum3 + + // DBNum1 -> NatNum4: Japanese modern long Kanji text for 123456789 + // 一億二千三百四十五万六千七百八十九 + sExpected = u"\u4e00\u5104\u4e8c\u5343\u4e09\u767e\u56db\u5341\u4e94\u4e07\u516d\u5343" + u"\u4e03\u767e\u516b\u5341\u4e5d "; + sCode = "[NatNum4][$-0411]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + sCode = "[DBNum1][$-0411]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + + // DBNum2 -> NatNum5: traditional long Kanji text + // 壱億弐阡参百四拾伍萬六阡七百八拾九 + sExpected = u"\u58f1\u5104\u5f10\u9621\u53c2\u767e\u56db\u62fe\u4f0d\u842c\u516d\u9621" + u"\u4e03\u767e\u516b\u62fe\u4e5d "; + sCode = "[NatNum5][$-0411]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + sCode = "[DBNum2][$-0411]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + + // DBNum3 -> NatNum3: fullwidth Arabic digits + // 123456789 + sExpected = u"\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19 "; + sCode = "[NatNum3][$-0411]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + sCode = "[DBNum3][$-0411]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + + // -- Korean: DBNum1 -> NatNum1, DBNum2 -> NatNum2, DBNum3 -> NatNum4, DBNum4 -> NatNum9 + + // DBNum1 -> NatNum1: Korean lower case characters + // 一二三四五六七八九 + sExpected = u"\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d "; + sCode = "[NatNum1][$-0412]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + sCode = "[DBNum1][$-0412]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + + // DBNum2 -> NatNum2: Korean upper case characters + // 壹貳參四伍六七八九 + sExpected = u"\u58f9\u8cb3\u53c3\u56db\u4f0d\u516d\u4e03\u516b\u4e5d "; + sCode = "[NatNum2][$-0412]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + sCode = "[DBNum2][$-0412]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + + // DBNum3 -> NatNum3: fullwidth Arabic digits + // 123456789 + sExpected = u"\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19 "; + sCode = "[NatNum3][$-0412]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + sCode = "[DBNum3][$-0412]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + + // DBNum4 -> NatNum9: Hangul characters + // 일이삼사오육칠팔구 + sExpected = u"\uc77c\uc774\uc0bc\uc0ac\uc624\uc721\uce60\ud314\uad6c "; + sCode = "[NatNum9][$-0412]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + sCode = "[DBNum4][$-0412]General\\ "; + checkPreviewString(aFormatter, sCode, 123456789, eLang, sExpected); + } { // tdf#105968 engineering format with value rounded up to next magnitude sCode = "##0.00E+00"; sExpected = "100.00E+00"; diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx index 8e78cf6ee613..af68a340f3d0 100644 --- a/svl/source/numbers/zformat.cxx +++ b/svl/source/numbers/zformat.cxx @@ -44,6 +44,7 @@ #include <svl/nfsymbol.hxx> #include <cmath> +#include <array> using namespace svt; @@ -137,6 +138,11 @@ void ImpSvNumberformatInfo::Copy( const ImpSvNumberformatInfo& rNumFor, sal_uInt nCntExp = rNumFor.nCntExp; } +static const std::map<LanguageType, std::array<sal_uInt8, 4>> tblDBNumToNatNum + = { { primary(LANGUAGE_CHINESE), { 4, 5, 3, 0 } }, + { primary(LANGUAGE_JAPANESE), { 4, 5, 3, 0 } }, + { primary(LANGUAGE_KOREAN), { 1, 2, 3, 9 } } }; + // static sal_uInt8 SvNumberNatNum::MapDBNumToNatNum( sal_uInt8 nDBNum, LanguageType eLang, bool bDate ) { @@ -156,43 +162,22 @@ sal_uInt8 SvNumberNatNum::MapDBNumToNatNum( sal_uInt8 nDBNum, LanguageType eLang } else { - switch ( nDBNum ) + if (1 <= nDBNum && nDBNum <= 4) { - case 1: - if ( eLang == primary(LANGUAGE_CHINESE) ) - nNatNum = 4; - else if ( eLang == primary(LANGUAGE_JAPANESE) ) - nNatNum = 1; - else if ( eLang == primary(LANGUAGE_KOREAN) ) - nNatNum = 1; - break; - case 2: - if ( eLang == primary(LANGUAGE_CHINESE)) - nNatNum = 5; - else if ( eLang == primary(LANGUAGE_JAPANESE) ) - nNatNum = 4; - else if ( eLang == primary(LANGUAGE_KOREAN) ) - nNatNum = 2; - break; - case 3: - if ( eLang == primary(LANGUAGE_CHINESE) ) - nNatNum = 6; - else if ( eLang == primary(LANGUAGE_JAPANESE) ) - nNatNum = 5; - else if ( eLang == primary(LANGUAGE_KOREAN) ) - nNatNum = 3; - break; - case 4: - if ( eLang == primary(LANGUAGE_JAPANESE) ) - nNatNum = 7; - else if ( eLang == primary(LANGUAGE_KOREAN) ) - nNatNum = 9; - break; + auto const it = tblDBNumToNatNum.find(eLang); + if (it != tblDBNumToNatNum.end()) + nNatNum = it->second[nDBNum - 1]; + } } return nNatNum; } +static const std::map<LanguageType, std::array<sal_uInt8, 9>> tblNatNumToDBNum + = { { primary(LANGUAGE_CHINESE), { 1, 0, 0, 1, 2, 3, 0, 0, 0 } }, + { primary(LANGUAGE_JAPANESE), { 1, 2, 3, 1, 2, 3, 1, 2, 0 } }, + { primary(LANGUAGE_KOREAN), { 0, 2, 3, 1, 0, 0, 0, 0, 0 } } }; + // static sal_uInt8 SvNumberNatNum::MapNatNumToDBNum( sal_uInt8 nNatNum, LanguageType eLang, bool bDate ) { @@ -212,52 +197,11 @@ sal_uInt8 SvNumberNatNum::MapNatNumToDBNum( sal_uInt8 nNatNum, LanguageType eLan } else { - switch ( nNatNum ) + if (1 <= nNatNum && nNatNum <= 9) { - case 1: - if ( eLang == primary(LANGUAGE_JAPANESE) ) - nDBNum = 1; - else if ( eLang == primary(LANGUAGE_KOREAN) ) - nDBNum = 1; - break; - case 2: - if ( eLang == primary(LANGUAGE_KOREAN) ) - nDBNum = 2; - break; - case 3: - if ( eLang == primary(LANGUAGE_KOREAN) ) - nDBNum = 3; - break; - case 4: - if ( eLang == primary(LANGUAGE_CHINESE) ) - nDBNum = 1; - else if ( eLang == primary(LANGUAGE_JAPANESE) ) - nDBNum = 2; - break; - case 5: - if ( eLang == primary(LANGUAGE_CHINESE) ) - nDBNum = 2; - else if ( eLang == primary(LANGUAGE_JAPANESE) ) - nDBNum = 3; - break; - case 6: - if ( eLang == primary(LANGUAGE_CHINESE) ) - nDBNum = 3; - break; - case 7: - if ( eLang == primary(LANGUAGE_JAPANESE) ) - nDBNum = 4; - break; - case 8: - break; - case 9: - if ( eLang == primary(LANGUAGE_KOREAN) ) - nDBNum = 4; - break; - case 10: - break; - case 11: - break; + auto const it = tblNatNumToDBNum.find(eLang); + if (it != tblNatNumToDBNum.end()) + nDBNum = it->second[nNatNum - 1]; } } return nDBNum; |