ICU-10046 Expose Exponent Multiplication Symbol. ScientificFormatHelper class to recognize variants of the plus and minus sign.

X-SVN-Rev: 35614
This commit is contained in:
Travis Keep 2014-04-10 18:13:29 +00:00
parent 1ec6826469
commit 93559e74a8
6 changed files with 58 additions and 19 deletions

View File

@ -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

View File

@ -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;

View File

@ -163,6 +163,10 @@ public:
* @stable ICU 4.6
*/
kNineDigitSymbol,
/** Multiplication sign.
* @draft ICU 54
*/
kExponentMultiplicationSymbol,
/** count symbol constants */
kFormatSymbolCount
};

View File

@ -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

View File

@ -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;
/**

View File

@ -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<DecimalFormat> 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();
}