/**
  * 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;
 }
Example #4
0
  /** 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();
  }