diff --git a/icu4c/source/i18n/dcfmtsym.cpp b/icu4c/source/i18n/dcfmtsym.cpp index 809e8a1907..68d8238b23 100644 --- a/icu4c/source/i18n/dcfmtsym.cpp +++ b/icu4c/source/i18n/dcfmtsym.cpp @@ -1,6 +1,6 @@ /* ******************************************************************************* -* Copyright (C) 1997-2013, International Business Machines Corporation and +* Copyright (C) 1997-2014, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* * @@ -189,6 +189,7 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, UBool us NULL, /* seven digit - get it from the numbering system */ NULL, /* eight digit - get it from the numbering system */ NULL, /* nine digit - get it from the numbering system */ + "superscriptingExponent", /* Multiplication (x) symbol for exponents */ }; static const char *gLatn = "latn"; @@ -420,6 +421,7 @@ DecimalFormatSymbols::initialize() { fSymbols[kNaNSymbol] = (UChar)0xfffd; // SUB NaN fSymbols[kSignificantDigitSymbol] = (UChar)0x0040; // '@' significant digit fSymbols[kMonetaryGroupingSeparatorSymbol].remove(); // + fSymbols[kExponentMultiplicationSymbol] = (UChar)0xd7; // 'x' multiplication symbol for exponents } Locale diff --git a/icu4c/source/i18n/scientificformathelper.cpp b/icu4c/source/i18n/scientificformathelper.cpp index c9d7fdf58e..8b07e69545 100644 --- a/icu4c/source/i18n/scientificformathelper.cpp +++ b/icu4c/source/i18n/scientificformathelper.cpp @@ -12,33 +12,38 @@ #include "unicode/dcfmtsym.h" #include "unicode/fpositer.h" #include "unicode/utf16.h" +#include "unicode/uniset.h" +#include "decfmtst.h" #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) -// TODO: Add U_DRAFT_API directives. -// TODO: Add U_FORMATTING directives - U_NAMESPACE_BEGIN -static UChar kExponentDigits[] = {0x2070, 0xB9, 0xB2, 0xB3, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079}; +static UChar kSuperscriptDigits[] = {0x2070, 0xB9, 0xB2, 0xB3, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079}; + +static UChar kSuperscriptPlusSign = 0x207A; +static UChar kSuperscriptMinusSign = 0x207B; static UnicodeString getMultiplicationSymbol(const DecimalFormatSymbols &dfs) { - static UChar multSign = 0xD7; - return UnicodeString(FALSE, &multSign, 1); + return dfs.getConstSymbol(DecimalFormatSymbols::kExponentMultiplicationSymbol); } ScientificFormatHelper::ScientificFormatHelper( - const DecimalFormatSymbols &dfs, UErrorCode &status) : fPreExponent() { + const DecimalFormatSymbols &dfs, UErrorCode &status) + : fPreExponent(), fStaticSets(NULL) { if (U_FAILURE(status)) { return; } - fPreExponent.append(getMultiplicationSymbol(dfs)); + fPreExponent.append(dfs.getConstSymbol( + DecimalFormatSymbols::kExponentMultiplicationSymbol)); fPreExponent.append(dfs.getSymbol(DecimalFormatSymbols::kOneDigitSymbol)); fPreExponent.append(dfs.getSymbol(DecimalFormatSymbols::kZeroDigitSymbol)); + fStaticSets = DecimalFormatStaticSets::getStaticSets(status); } ScientificFormatHelper::ScientificFormatHelper( - const ScientificFormatHelper &other) : fPreExponent(other.fPreExponent) { + const ScientificFormatHelper &other) + : fPreExponent(other.fPreExponent), fStaticSets(other.fStaticSets) { } ScientificFormatHelper &ScientificFormatHelper::operator=(const ScientificFormatHelper &other) { @@ -46,6 +51,7 @@ ScientificFormatHelper &ScientificFormatHelper::operator=(const ScientificFormat return *this; } fPreExponent = other.fPreExponent; + fStaticSets = other.fStaticSets; return *this; } @@ -98,17 +104,12 @@ static UBool copyAsSuperscript( status = U_INVALID_CHAR_FOUND; return FALSE; } - result.append(kExponentDigits[digit]); + result.append(kSuperscriptDigits[digit]); i += U16_LENGTH(c); } return TRUE; } -static UBool isMinusSign(UChar ch) { - // TODO: revisit this. - return (ch == 0x2D); -} - UnicodeString &ScientificFormatHelper::toSuperscriptExponentDigits( const UnicodeString &s, FieldPositionIterator &fpi, @@ -127,9 +128,13 @@ UnicodeString &ScientificFormatHelper::toSuperscriptExponentDigits( { int32_t beginIndex = fp.getBeginIndex(); int32_t endIndex = fp.getEndIndex(); - if (endIndex - beginIndex == 1 && isMinusSign(s[beginIndex])) { + UChar32 aChar = s.char32At(beginIndex); + if (fStaticSets->fMinusSigns->contains(aChar)) { result.append(s, copyFromOffset, beginIndex - copyFromOffset); - result.append(0x207B); + result.append(kSuperscriptMinusSign); + } else if (fStaticSets->fPlusSigns->contains(aChar)) { + result.append(s, copyFromOffset, beginIndex - copyFromOffset); + result.append(kSuperscriptPlusSign); } else { status = U_INVALID_CHAR_FOUND; return result; diff --git a/icu4c/source/i18n/unicode/dcfmtsym.h b/icu4c/source/i18n/unicode/dcfmtsym.h index 662d58b221..b24ea9cd6b 100644 --- a/icu4c/source/i18n/unicode/dcfmtsym.h +++ b/icu4c/source/i18n/unicode/dcfmtsym.h @@ -163,6 +163,10 @@ public: * @stable ICU 4.6 */ kNineDigitSymbol, + /** Multiplication sign. + * @draft ICU 54 + */ + kExponentMultiplicationSymbol, /** count symbol constants */ kFormatSymbolCount }; diff --git a/icu4c/source/i18n/unicode/scientificformathelper.h b/icu4c/source/i18n/unicode/scientificformathelper.h index 9498ca3d5f..0ce9fee7a8 100644 --- a/icu4c/source/i18n/unicode/scientificformathelper.h +++ b/icu4c/source/i18n/unicode/scientificformathelper.h @@ -24,6 +24,7 @@ U_NAMESPACE_BEGIN class DecimalFormatSymbols; class FieldPositionIterator; +class DecimalFormatStaticSets; /** * A helper class for formatting in user-friendly scientific notation. @@ -121,6 +122,7 @@ class U_I18N_API ScientificFormatHelper : public UObject { UErrorCode &status) const; private: UnicodeString fPreExponent; + const DecimalFormatStaticSets *fStaticSets; }; U_NAMESPACE_END diff --git a/icu4c/source/i18n/unicode/unum.h b/icu4c/source/i18n/unicode/unum.h index 6071f2f487..c7d0e6e2f2 100644 --- a/icu4c/source/i18n/unicode/unum.h +++ b/icu4c/source/i18n/unicode/unum.h @@ -1190,8 +1190,14 @@ typedef enum UNumberFormatSymbol { * @stable ICU 4.6 */ UNUM_NINE_DIGIT_SYMBOL = 26, + + /** Multiplication sign + * @draft ICU 54 + */ + UNUM_EXPONENT_MULTIPLICATION_SYMBOL = 27, + /** count symbol constants */ - UNUM_FORMAT_SYMBOL_COUNT = 27 + UNUM_FORMAT_SYMBOL_COUNT = 28 } UNumberFormatSymbol; /** diff --git a/icu4c/source/test/intltest/scientificformathelpertest.cpp b/icu4c/source/test/intltest/scientificformathelpertest.cpp index f0855f8b76..e1c1f665d3 100644 --- a/icu4c/source/test/intltest/scientificformathelpertest.cpp +++ b/icu4c/source/test/intltest/scientificformathelpertest.cpp @@ -29,6 +29,7 @@ public: void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0); private: void TestBasic(); + void TestPlusSignInExponent(); }; void ScientificFormatHelperTest::runIndexedTest( @@ -38,6 +39,7 @@ void ScientificFormatHelperTest::runIndexedTest( } TESTCASE_AUTO_BEGIN; TESTCASE_AUTO(TestBasic); + TESTCASE_AUTO(TestPlusSignInExponent); TESTCASE_AUTO_END; } @@ -72,6 +74,24 @@ void ScientificFormatHelperTest::TestBasic() { } } +void ScientificFormatHelperTest::TestPlusSignInExponent() { + UErrorCode status = U_ZERO_ERROR; + LocalPointer decfmt((DecimalFormat *) NumberFormat::createScientificInstance("en", status)); + decfmt->applyPattern("0.00E+0", status); + assertSuccess("1", status); + UnicodeString appendTo; + FieldPositionIterator fpositer; + decfmt->format(6.02e23, appendTo, &fpositer, status); + ScientificFormatHelper helper(*decfmt->getDecimalFormatSymbols(), status); + UnicodeString result; + const char *expected = "6.02\\u00d710\\u207a\\u00b2\\u00b3"; + assertEquals( + "", + UnicodeString(expected).unescape(), + helper.toSuperscriptExponentDigits(appendTo, fpositer, result, status)); + assertSuccess("", status); +} + extern IntlTest *createScientificFormatHelperTest() { return new ScientificFormatHelperTest(); }