mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-13 08:53:20 +00:00
ICU-12030 move some code to QuantityFormatter so that PluralRules does not depend on NumberFormat and to be more parallel with C++
X-SVN-Rev: 38135
This commit is contained in:
parent
8c6d77a375
commit
cab8879780
3 changed files with 80 additions and 42 deletions
|
@ -1017,34 +1017,23 @@ public class MeasureFormat extends UFormat {
|
|||
ImmutableNumberFormat nf,
|
||||
StringBuilder appendTo,
|
||||
FieldPosition fieldPosition) {
|
||||
if (measure.getUnit() instanceof Currency) {
|
||||
Number n = measure.getNumber();
|
||||
MeasureUnit unit = measure.getUnit();
|
||||
if (unit instanceof Currency) {
|
||||
return appendTo.append(
|
||||
currencyFormat.format(
|
||||
new CurrencyAmount(measure.getNumber(), (Currency) measure.getUnit()),
|
||||
new CurrencyAmount(n, (Currency) unit),
|
||||
new StringBuffer(),
|
||||
fieldPosition));
|
||||
|
||||
}
|
||||
Number n = measure.getNumber();
|
||||
MeasureUnit unit = measure.getUnit();
|
||||
UFieldPosition fpos = new UFieldPosition(fieldPosition.getFieldAttribute(), fieldPosition.getField());
|
||||
StringBuffer formattedNumber = nf.format(n, new StringBuffer(), fpos);
|
||||
String keyword = rules.select(new PluralRules.FixedDecimal(n.doubleValue(), fpos.getCountVisibleFractionDigits(), fpos.getFractionDigits()));
|
||||
|
||||
int pluralForm = StandardPlural.indexOrOtherIndexFromString(keyword);
|
||||
SimplePatternFormatter formatter = getPluralFormatter(unit, formatWidth, pluralForm);
|
||||
int[] offsets = new int[1];
|
||||
formatter.formatAndAppend(appendTo, offsets, formattedNumber);
|
||||
if (offsets[0] != -1) { // there is a number (may not happen with, say, Arabic dual)
|
||||
// Fix field position
|
||||
if (fpos.getBeginIndex() != 0 || fpos.getEndIndex() != 0) {
|
||||
fieldPosition.setBeginIndex(fpos.getBeginIndex() + offsets[0]);
|
||||
fieldPosition.setEndIndex(fpos.getEndIndex() + offsets[0]);
|
||||
}
|
||||
}
|
||||
return appendTo;
|
||||
StringBuffer formattedNumber = new StringBuffer();
|
||||
StandardPlural pluralForm = QuantityFormatter.selectPlural(
|
||||
n, nf.nf, rules, formattedNumber, fieldPosition);
|
||||
SimplePatternFormatter formatter = getPluralFormatter(unit, formatWidth, pluralForm.ordinal());
|
||||
return QuantityFormatter.format(formatter, formattedNumber, appendTo, fieldPosition);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Instances contain all MeasureFormat specific data for a particular locale.
|
||||
* This data is cached. It is never copied, but is shared via shared pointers.
|
||||
|
|
|
@ -1954,18 +1954,6 @@ public class PluralRules implements Serializable {
|
|||
return rules.select(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @deprecated This API is ICU internal only.
|
||||
*/
|
||||
@Deprecated
|
||||
public String select(double number, NumberFormat numberFormat) {
|
||||
if (numberFormat instanceof DecimalFormat) {
|
||||
return select(((DecimalFormat) numberFormat).getFixedDecimal(number));
|
||||
}
|
||||
return select(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a number information, and keyword, return whether the keyword would match the number.
|
||||
*
|
||||
|
|
|
@ -6,8 +6,11 @@
|
|||
*/
|
||||
package com.ibm.icu.text;
|
||||
|
||||
import java.text.FieldPosition;
|
||||
|
||||
import com.ibm.icu.impl.SimplePatternFormatter;
|
||||
import com.ibm.icu.impl.StandardPlural;
|
||||
import com.ibm.icu.text.PluralRules.FixedDecimal;
|
||||
|
||||
/**
|
||||
* QuantityFormatter represents an unknown quantity of something and formats a known quantity
|
||||
|
@ -49,19 +52,24 @@ class QuantityFormatter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Format formats a quantity with this object.
|
||||
* @param quantity the quantity to be formatted
|
||||
* @param numberFormat used to actually format the quantity.
|
||||
* @param pluralRules uses the quantity and the numberFormat to determine what plural
|
||||
* Format formats a number with this object.
|
||||
* @param number the number to be formatted
|
||||
* @param numberFormat used to actually format the number.
|
||||
* @param pluralRules uses the number and the numberFormat to determine what plural
|
||||
* variant to use for fetching the formatting template.
|
||||
* @return the formatted string e.g '3 apples'
|
||||
*/
|
||||
public String format(double quantity, NumberFormat numberFormat, PluralRules pluralRules) {
|
||||
String formatStr = numberFormat.format(quantity);
|
||||
String variant = pluralRules.select(quantity, numberFormat);
|
||||
return getByVariant(variant).format(formatStr);
|
||||
public String format(double number, NumberFormat numberFormat, PluralRules pluralRules) {
|
||||
String formatStr = numberFormat.format(number);
|
||||
StandardPlural p = selectPlural(number, numberFormat, pluralRules);
|
||||
SimplePatternFormatter formatter = templates[p.ordinal()];
|
||||
if (formatter == null) {
|
||||
formatter = templates[StandardPlural.OTHER_INDEX];
|
||||
assert formatter != null;
|
||||
}
|
||||
return formatter.format(formatStr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the SimplePatternFormatter for a particular variant.
|
||||
* @param variant "zero", "one", "two", "few", "many", "other"
|
||||
|
@ -74,4 +82,57 @@ class QuantityFormatter {
|
|||
return (template == null && idx != StandardPlural.OTHER_INDEX) ?
|
||||
templates[StandardPlural.OTHER_INDEX] : template;
|
||||
}
|
||||
|
||||
// The following methods live here so that class PluralRules does not depend on number formatting,
|
||||
// and the SimplePatternFormatter does not depend on FieldPosition.
|
||||
|
||||
/**
|
||||
* Selects the standard plural form for the number/formatter/rules.
|
||||
*/
|
||||
public static StandardPlural selectPlural(double number, NumberFormat numberFormat, PluralRules rules) {
|
||||
String pluralKeyword;
|
||||
if (numberFormat instanceof DecimalFormat) {
|
||||
pluralKeyword = rules.select(((DecimalFormat) numberFormat).getFixedDecimal(number));
|
||||
} else {
|
||||
pluralKeyword = rules.select(number);
|
||||
}
|
||||
return StandardPlural.orOtherFromString(pluralKeyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the standard plural form for the number/formatter/rules.
|
||||
*/
|
||||
public static StandardPlural selectPlural(
|
||||
Number number, NumberFormat fmt, PluralRules rules,
|
||||
StringBuffer formattedNumber, FieldPosition pos) {
|
||||
UFieldPosition fpos = new UFieldPosition(pos.getFieldAttribute(), pos.getField());
|
||||
fmt.format(number, formattedNumber, fpos);
|
||||
// TODO: Long, BigDecimal & BigInteger may not fit into doubleValue().
|
||||
FixedDecimal fd = new FixedDecimal(
|
||||
number.doubleValue(),
|
||||
fpos.getCountVisibleFractionDigits(), fpos.getFractionDigits());
|
||||
String pluralKeyword = rules.select(fd);
|
||||
pos.setBeginIndex(fpos.getBeginIndex());
|
||||
pos.setEndIndex(fpos.getEndIndex());
|
||||
return StandardPlural.orOtherFromString(pluralKeyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the pattern with the value and adjusts the FieldPosition.
|
||||
*/
|
||||
public static StringBuilder format(SimplePatternFormatter pattern, CharSequence value,
|
||||
StringBuilder appendTo, FieldPosition pos) {
|
||||
int[] offsets = new int[1];
|
||||
pattern.formatAndAppend(appendTo, offsets, value);
|
||||
if (pos.getBeginIndex() != 0 || pos.getEndIndex() != 0) {
|
||||
if (offsets[0] >= 0) {
|
||||
pos.setBeginIndex(pos.getBeginIndex() + offsets[0]);
|
||||
pos.setEndIndex(pos.getEndIndex() + offsets[0]);
|
||||
} else {
|
||||
pos.setBeginIndex(0);
|
||||
pos.setEndIndex(0);
|
||||
}
|
||||
}
|
||||
return appendTo;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue