/**
   * Updates the interal bitset from <code>iterator</code>. This will set <code>validMask</code> to
   * true if <code>iterator</code> is non-null.
   */
  private void updateMask(AttributedCharacterIterator iterator) {
    if (iterator != null) {
      validMask = true;
      this.iterator = iterator;

      // Update the literal mask
      if (literalMask == null) {
        literalMask = new BitSet();
      } else {
        for (int counter = literalMask.length() - 1; counter >= 0; counter--) {
          literalMask.clear(counter);
        }
      }

      iterator.first();
      while (iterator.current() != CharacterIterator.DONE) {
        Map attributes = iterator.getAttributes();
        boolean set = isLiteral(attributes);
        int start = iterator.getIndex();
        int end = iterator.getRunLimit();

        while (start < end) {
          if (set) {
            literalMask.set(start);
          } else {
            literalMask.clear(start);
          }
          start++;
        }
        iterator.setIndex(start);
      }
    }
  }
  public Format.Field[] getFields(final int offset) {
    if (format == null) {
      return null;
    }

    Object value = getFormattedTextField().getValue();
    if (value == null) {
      return null;
    }

    AttributedCharacterIterator iterator = format.formatToCharacterIterator(value);
    if (offset < iterator.getBeginIndex() || offset > iterator.getEndIndex()) {
      return new Format.Field[0];
    }

    iterator.setIndex(offset);
    Set keys = iterator.getAttributes().keySet();
    Set result = new HashSet();
    Iterator iter = keys.iterator();

    while (iter.hasNext()) {
      Object key = iter.next();
      if (key instanceof Format.Field) {
        result.add(key);
      }
    }

    return (Format.Field[]) result.toArray(new Format.Field[result.size()]);
  }
  /**
   * Return a StyledParagraph reflecting the insertion of a single character into the text. This
   * method will attempt to reuse the given paragraph, but may create a new paragraph.
   *
   * @param aci an iterator over the text. The text should be the same as the text used to create
   *     (or most recently update) oldParagraph, with the exception of inserting a single character
   *     at insertPos.
   * @param chars the characters in aci
   * @param insertPos the index of the new character in aci
   * @param oldParagraph a StyledParagraph for the text in aci before the insertion
   */
  public static StyledParagraph insertChar(
      AttributedCharacterIterator aci, char[] chars, int insertPos, StyledParagraph oldParagraph) {

    // If the styles at insertPos match those at insertPos-1,
    // oldParagraph will be reused.  Otherwise we create a new
    // paragraph.

    char ch = aci.setIndex(insertPos);
    int relativePos = Math.max(insertPos - aci.getBeginIndex() - 1, 0);

    Map attributes = addInputMethodAttrs(aci.getAttributes());
    Decoration d = Decoration.getDecoration(attributes);
    if (!oldParagraph.getDecorationAt(relativePos).equals(d)) {
      return new StyledParagraph(aci, chars);
    }
    Object f = getGraphicOrFont(attributes);
    if (f == null) {
      FontResolver resolver = FontResolver.getInstance();
      int fontIndex = resolver.getFontIndex(ch);
      f = resolver.getFont(fontIndex, attributes);
    }
    if (!oldParagraph.getFontOrGraphicAt(relativePos).equals(f)) {
      return new StyledParagraph(aci, chars);
    }

    // insert into existing paragraph
    oldParagraph.length += 1;
    if (oldParagraph.decorations != null) {
      insertInto(relativePos, oldParagraph.decorationStarts, oldParagraph.decorations.size());
    }
    if (oldParagraph.fonts != null) {
      insertInto(relativePos, oldParagraph.fontStarts, oldParagraph.fonts.size());
    }
    return oldParagraph;
  }
  protected String style(final AttributedCharacterIterator aci) {
    final StringBuilder builder = new StringBuilder();

    Map<AttributedCharacterIterator.Attribute, Object> map = null;
    char chr = aci.current();

    while (aci.getIndex() < aci.getEndIndex()) {
      if (!aci.getAttributes().equals(map)) {
        style(aci.getAttributes(), builder);
        map = aci.getAttributes();
      }

      builder.append(StringEscapeUtils.escapeHtml(String.valueOf(chr)));
      chr = aci.next();
    }

    return builder.toString();
  }
Exemple #5
0
  /**
   * This routine goes through the attributes and sets the font before calling the actual string
   * drawing routine
   *
   * @param iter
   */
  protected void doAttributes(AttributedCharacterIterator iter) {
    underline = false;
    Set set = iter.getAttributes().keySet();
    for (Iterator iterator = set.iterator(); iterator.hasNext(); ) {
      TextAttribute textattribute = (TextAttribute) iterator.next();
      if (textattribute.equals(TextAttribute.FONT)) {
        Font font = (Font) iter.getAttributes().get(textattribute);
        setFont(font);
      } else if (textattribute.equals(TextAttribute.UNDERLINE)) {
        if (iter.getAttributes().get(textattribute) == TextAttribute.UNDERLINE_ON) underline = true;
      } else if (textattribute.equals(TextAttribute.SUPERSCRIPT)) {
        /*
        iter.getAttributes().get(textattribute);
        Integer _tmp = TextAttribute.SUPERSCRIPT_SUPER;
        subscript = true;
         */
      } else if (textattribute.equals(TextAttribute.SIZE)) {
        Object obj = iter.getAttributes().get(textattribute);
        Font font1 = null;
        /* ssteward: no deriveFont method for java.awt.Font in libgcj 3.4.2
                      if(obj instanceof Integer) {
                          int i = ((Integer)obj).intValue();
                          font1 = getFont().deriveFont(getFont().getStyle(), i);
                      }
                      else if(obj instanceof Float) {
                          float f = ((Float)obj).floatValue();
                          font1 = getFont().deriveFont(getFont().getStyle(), f);
                      }
                      else {
                          //System.out.println("Unknown type for attribute SIZE");
                          return;
                      }
        */
        return;

        // setFont(font1); // ssteward
      } else {
        String s = "only FONT/SIZE/UNDERLINE/SUPERSCRIPT supported";
        throw new RuntimeException(s);
      }
    }
  }
  /** Returns a Set of the attribute identifiers at <code>index</code>. */
  Map getAttributes(int index) {
    if (isValidMask()) {
      AttributedCharacterIterator iterator = getIterator();

      if (index >= 0 && index <= iterator.getEndIndex()) {
        iterator.setIndex(index);
        return iterator.getAttributes();
      }
    }
    return null;
  }
    public void actionPerformed(ActionEvent ae) {

      if (getFormattedTextField().isEditable()) {
        if (getAllowsInvalid()) {
          // This will work if the currently edited value is valid.
          updateMask();
        }

        boolean validEdit = false;

        if (isValidMask()) {
          int start = getFormattedTextField().getSelectionStart();

          if (start != -1) {
            AttributedCharacterIterator iterator = getIterator();

            iterator.setIndex(start);

            Map attributes = iterator.getAttributes();
            Object field = getAdjustField(start, attributes);

            if (canIncrement(field, start)) {
              try {
                Object value = stringToValue(getFormattedTextField().getText());
                int fieldTypeCount = getFieldTypeCountTo(field, start);

                value = adjustValue(value, attributes, field, direction);
                if (value != null && isValidValue(value, false)) {
                  resetValue(value);
                  updateMask();

                  if (isValidMask()) {
                    selectField(field, fieldTypeCount);
                  }
                  validEdit = true;
                }
              } catch (ParseException pe) {
              } catch (BadLocationException ble) {
              }
            }
          }
        }
        if (!validEdit) {
          invalidEdit();
        }
      }
    }
 /**
  * This routine goes through the attributes and sets the font before calling the actual string
  * drawing routine
  *
  * @param iter
  */
 protected void doAttributes(AttributedCharacterIterator iter) {
   underline = false;
   Set set = iter.getAttributes().keySet();
   for (Iterator iterator = set.iterator(); iterator.hasNext(); ) {
     AttributedCharacterIterator.Attribute attribute =
         (AttributedCharacterIterator.Attribute) iterator.next();
     if (!(attribute instanceof TextAttribute)) continue;
     TextAttribute textattribute = (TextAttribute) attribute;
     if (textattribute.equals(TextAttribute.FONT)) {
       Font font = (Font) iter.getAttributes().get(textattribute);
       setFont(font);
     } else if (textattribute.equals(TextAttribute.UNDERLINE)) {
       if (iter.getAttributes().get(textattribute) == TextAttribute.UNDERLINE_ON) underline = true;
     } else if (textattribute.equals(TextAttribute.SIZE)) {
       Object obj = iter.getAttributes().get(textattribute);
       if (obj instanceof Integer) {
         int i = ((Integer) obj).intValue();
         setFont(getFont().deriveFont(getFont().getStyle(), i));
       } else if (obj instanceof Float) {
         float f = ((Float) obj).floatValue();
         setFont(getFont().deriveFont(getFont().getStyle(), f));
       }
     } else if (textattribute.equals(TextAttribute.FOREGROUND)) {
       setColor((Color) iter.getAttributes().get(textattribute));
     } else if (textattribute.equals(TextAttribute.FAMILY)) {
       Font font = getFont();
       Map fontAttributes = font.getAttributes();
       fontAttributes.put(TextAttribute.FAMILY, iter.getAttributes().get(textattribute));
       setFont(font.deriveFont(fontAttributes));
     } else if (textattribute.equals(TextAttribute.POSTURE)) {
       Font font = getFont();
       Map fontAttributes = font.getAttributes();
       fontAttributes.put(TextAttribute.POSTURE, iter.getAttributes().get(textattribute));
       setFont(font.deriveFont(fontAttributes));
     } else if (textattribute.equals(TextAttribute.WEIGHT)) {
       Font font = getFont();
       Map fontAttributes = font.getAttributes();
       fontAttributes.put(TextAttribute.WEIGHT, iter.getAttributes().get(textattribute));
       setFont(font.deriveFont(fontAttributes));
     }
   }
 }
  protected void exportStyledText(JRStyledText styledText, Locale locale, boolean startedHyperlink)
      throws IOException {
    String text = styledText.getText();

    int runLimit = 0;

    AttributedCharacterIterator iterator = styledText.getAttributedString().getIterator();

    while (runLimit < styledText.length()
        && (runLimit = iterator.getRunLimit()) <= styledText.length()) {
      exportStyledTextRun(
          iterator.getAttributes(),
          text.substring(iterator.getIndex(), runLimit),
          locale,
          startedHyperlink);

      iterator.setIndex(runLimit);
    }
  }
  /**
   * finds attributes with regards to char index in this AttributedCharacterIterator, and puts them
   * in a vector
   *
   * @param iterator
   * @return a vector, each entry in this vector are of type FieldContainer , which stores start and
   *     end indexes and an attribute this range has
   */
  private static List<FieldContainer> findFields(AttributedCharacterIterator iterator) {
    List<FieldContainer> result = new ArrayList<FieldContainer>();
    while (iterator.getIndex() != iterator.getEndIndex()) {
      int start = iterator.getRunStart();
      int end = iterator.getRunLimit();

      Iterator it = iterator.getAttributes().keySet().iterator();
      while (it.hasNext()) {
        AttributedCharacterIterator.Attribute attribute =
            (AttributedCharacterIterator.Attribute) it.next();
        Object value = iterator.getAttribute(attribute);
        result.add(new FieldContainer(start, end, attribute, value));
        // System.out.println(start + " " + end + ": " + attribute + ",
        // " + value );
        // System.out.println("v.add(new FieldContainer(" + start +"," +
        // end +"," + attribute+ "," + value+ "));");
      }
      iterator.setIndex(end);
    }
    return result;
  }
  /**
   * Create a new StyledParagraph over the given styled text.
   *
   * @param aci an iterator over the text
   * @param chars the characters extracted from aci
   */
  public StyledParagraph(AttributedCharacterIterator aci, char[] chars) {

    int start = aci.getBeginIndex();
    int end = aci.getEndIndex();
    length = end - start;

    int index = start;
    aci.first();

    do {
      final int nextRunStart = aci.getRunLimit();
      final int localIndex = index - start;

      Map attributes = aci.getAttributes();
      attributes = addInputMethodAttrs(attributes);
      Decoration d = Decoration.getDecoration(attributes);
      addDecoration(d, localIndex);

      Object f = getGraphicOrFont(attributes);
      if (f == null) {
        addFonts(chars, attributes, localIndex, nextRunStart - start);
      } else {
        addFont(f, localIndex);
      }

      aci.setIndex(nextRunStart);
      index = nextRunStart;

    } while (index < end);

    // Add extra entries to starts arrays with the length
    // of the paragraph.  'this' is used as a dummy value
    // in the Vector.
    if (decorations != null) {
      decorationStarts = addToVector(this, length, decorations, decorationStarts);
    }
    if (fonts != null) {
      fontStarts = addToVector(this, length, fonts, fontStarts);
    }
  }
  /** 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();
  }
  public void drawString(AttributedCharacterIterator iterator, float x, float y) {

    // TextLayout draws the iterator as glyph vector
    // thats why we use it only in the case of TEXT_AS_SHAPES,
    // otherwise tagged strings are always written as glyphs
    if (isProperty(TEXT_AS_SHAPES)) {
      // draws all attributes
      TextLayout tl = new TextLayout(iterator, getFontRenderContext());
      tl.draw(this, x, y);
    } else {
      // reset to that font at the end
      Font font = getFont();

      // initial attributes, we us TextAttribute.equals() rather
      // than Font.equals() because using Font.equals() we do
      // not get a 'false' if underline etc. is changed
      Map<? extends Attribute, Object> attributes = FontUtilities.getAttributes(font);

      // stores all characters which are written with the same font
      // if font is changed the buffer will be written and cleared
      // after it
      StringBuffer sb = new StringBuffer();

      for (char c = iterator.first(); c != AttributedCharacterIterator.DONE; c = iterator.next()) {

        // append c if font is not changed
        if (attributes.equals(iterator.getAttributes())) {
          sb.append(c);

        } else {
          // TextLayout does not like 0 length strings
          if (sb.length() > 0) {
            // draw sb if font is changed
            drawString(sb.toString(), x, y);

            // change the x offset for the next drawing
            // FIXME: change y offset for vertical text
            TextLayout tl = new TextLayout(sb.toString(), attributes, getFontRenderContext());

            // calculate real width
            x = x + Math.max(tl.getAdvance(), (float) tl.getBounds().getWidth());
          }

          // empty sb
          sb = new StringBuffer();
          sb.append(c);

          // change the font
          attributes = iterator.getAttributes();
          setFont(new Font(attributes));
        }
      }

      // draw the rest
      if (sb.length() > 0) {
        drawString(sb.toString(), x, y);
      }

      // use the old font for the next string drawing
      setFont(font);
    }
  }