/** * 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(); }
/** * 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); } }