/** * Returns {@code true} if the specified object is an instance of <code>NumericShaper</code> and * shapes identically to this one, regardless of the range representations, the bit mask or the * enum. For example, the following code produces {@code "true"}. * * <blockquote> * * <pre> * NumericShaper ns1 = NumericShaper.getShaper(NumericShaper.ARABIC); * NumericShaper ns2 = NumericShaper.getShaper(NumericShaper.Range.ARABIC); * System.out.println(ns1.equals(ns2)); * </pre> * * </blockquote> * * @param o the specified object to compare to this <code>NumericShaper</code> * @return <code>true</code> if <code>o</code> is an instance of <code>NumericShaper</code> and * shapes in the same way; <code>false</code> otherwise. * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object o) { if (o != null) { try { NumericShaper rhs = (NumericShaper) o; if (rangeSet != null) { if (rhs.rangeSet != null) { return isContextual() == rhs.isContextual() && rangeSet.equals(rhs.rangeSet) && shapingRange == rhs.shapingRange; } return isContextual() == rhs.isContextual() && rangeSet.equals(Range.maskToRangeSet(rhs.mask)) && shapingRange == Range.indexToRange(rhs.key); } else if (rhs.rangeSet != null) { Set<Range> rset = Range.maskToRangeSet(mask); Range srange = Range.indexToRange(key); return isContextual() == rhs.isContextual() && rset.equals(rhs.rangeSet) && srange == rhs.shapingRange; } return rhs.mask == mask && rhs.key == key; } catch (ClassCastException e) { } } return false; }
/** * Returns a contextual shaper for the provided Unicode range(s). The Latin-1 (EUROPEAN) digits * will be converted to the decimal digits corresponding to the range of the preceding text, if * the range is one of the provided ranges. The shaper uses {@code defaultContext} as the starting * context. * * @param ranges the specified Unicode ranges * @param defaultContext the starting context, such as {@code NumericShaper.Range.EUROPEAN} * @return a contextual shaper for the specified Unicode ranges. * @throws NullPointerException if {@code ranges} or {@code defaultContext} is {@code null} * @since 1.7 */ public static NumericShaper getContextualShaper(Set<Range> ranges, Range defaultContext) { if (defaultContext == null) { throw new NullPointerException(); } NumericShaper shaper = new NumericShaper(defaultContext, ranges); shaper.mask = CONTEXTUAL_MASK; return shaper; }
/** * Returns a contextual shaper for the provided Unicode range(s). The Latin-1 (EUROPEAN) digits * are converted to the decimal digits corresponding to the range of the preceding text, if the * range is one of the provided ranges. * * <p>The shaper assumes EUROPEAN as the starting context, that is, if EUROPEAN digits are * encountered before any strong directional text in the string, the context is presumed to be * EUROPEAN, and so the digits will not shape. * * @param ranges the specified Unicode ranges * @return a contextual shaper for the specified ranges * @throws NullPointerException if {@code ranges} is {@code null}. * @since 1.7 */ public static NumericShaper getContextualShaper(Set<Range> ranges) { NumericShaper shaper = new NumericShaper(Range.EUROPEAN, ranges); shaper.mask = CONTEXTUAL_MASK; return shaper; }
/** Initialize state, including fChars array, direction, and fBidi. */ private void initAll(AttributedCharacterIterator text) { fStart = text.getBeginIndex(); // extract chars fChars = new char[text.getEndIndex() - fStart]; int n = 0; for (char c = text.first(); c != CharacterIterator.DONE; c = text.next()) { fChars[n++] = c; } text.first(); fBidi = new Bidi(text); if (fBidi.isLeftToRight()) { fBidi = null; } text.first(); Map<? extends Attribute, ?> paragraphAttrs = text.getAttributes(); NumericShaper shaper = AttributeValues.getNumericShaping(paragraphAttrs); if (shaper != null) { shaper.shape(fChars, 0, fChars.length); } fParagraph = new StyledParagraph(text, fChars); // set paragraph attributes { // If there's an embedded graphic at the start of the // paragraph, look for the first non-graphic character // and use it and its font to initialize the paragraph. // If not, use the first graphic to initialize. fJustifyRatio = AttributeValues.getJustification(paragraphAttrs); boolean haveFont = TextLine.advanceToFirstFont(text); if (haveFont) { Font defaultFont = TextLine.getFontAtCurrentPos(text); int charsStart = text.getIndex() - text.getBeginIndex(); LineMetrics lm = defaultFont.getLineMetrics(fChars, charsStart, charsStart + 1, fFrc); fBaseline = (byte) lm.getBaselineIndex(); fBaselineOffsets = lm.getBaselineOffsets(); } else { // hmmm what to do here? Just try to supply reasonable // values I guess. GraphicAttribute graphic = (GraphicAttribute) paragraphAttrs.get(TextAttribute.CHAR_REPLACEMENT); fBaseline = TextLayout.getBaselineFromGraphic(graphic); Hashtable<Attribute, ?> fmap = new Hashtable<>(5, (float) 0.9); Font dummyFont = new Font(fmap); LineMetrics lm = dummyFont.getLineMetrics(" ", 0, 1, fFrc); fBaselineOffsets = lm.getBaselineOffsets(); } fBaselineOffsets = TextLine.getNormalizedOffsets(fBaselineOffsets, fBaseline); } invalidateComponents(); }