/** * 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 deleting a single character * at deletePos. * @param chars the characters in aci * @param deletePos the index where a character was removed * @param oldParagraph a StyledParagraph for the text in aci before the insertion */ public static StyledParagraph deleteChar( AttributedCharacterIterator aci, char[] chars, int deletePos, StyledParagraph oldParagraph) { // We will reuse oldParagraph unless there was a length-1 run // at deletePos. We could do more work and check the individual // Font and Decoration runs, but we don't right now... deletePos -= aci.getBeginIndex(); if (oldParagraph.decorations == null && oldParagraph.fonts == null) { oldParagraph.length -= 1; return oldParagraph; } if (oldParagraph.getRunLimit(deletePos) == deletePos + 1) { if (deletePos == 0 || oldParagraph.getRunLimit(deletePos - 1) == deletePos) { return new StyledParagraph(aci, chars); } } oldParagraph.length -= 1; if (oldParagraph.decorations != null) { deleteFrom(deletePos, oldParagraph.decorationStarts, oldParagraph.decorations.size()); } if (oldParagraph.fonts != null) { deleteFrom(deletePos, oldParagraph.fontStarts, oldParagraph.fonts.size()); } return oldParagraph; }
/** * 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; }
/** * Updates the <code>TextMeasurer</code> after a single character has been deleted from the * paragraph currently represented by this <code>TextMeasurer</code>. After this call, this <code> * TextMeasurer</code> is equivalent to a new <code>TextMeasurer</code> created from the text; * however, it will usually be more efficient to update an existing <code>TextMeasurer</code> than * to create a new one from scratch. * * @param newParagraph the text of the paragraph after performing the deletion. Cannot be null. * @param deletePos the position in the text where the character was removed. Must not be less * than the start of <code>newParagraph</code>, and must not be greater than the end of <code> * newParagraph</code>. * @throws IndexOutOfBoundsException if <code>deletePos</code> is less than the start of <code> * newParagraph</code> or greater than the end of <code>newParagraph</code> * @throws NullPointerException if <code>newParagraph</code> is <code>null</code> */ public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos) { fStart = newParagraph.getBeginIndex(); int end = newParagraph.getEndIndex(); if (end - fStart != fChars.length - 1) { initAll(newParagraph); } char[] newChars = new char[end - fStart]; int changedIndex = deletePos - fStart; System.arraycopy(fChars, 0, newChars, 0, deletePos - fStart); System.arraycopy(fChars, changedIndex + 1, newChars, changedIndex, end - deletePos); fChars = newChars; if (fBidi != null) { fBidi = new Bidi(newParagraph); if (fBidi.isLeftToRight()) { fBidi = null; } } fParagraph = StyledParagraph.deleteChar(newParagraph, fChars, deletePos, fParagraph); invalidateComponents(); }
/** * Updates the <code>TextMeasurer</code> after a single character has been inserted into the * paragraph currently represented by this <code>TextMeasurer</code>. After this call, this <code> * TextMeasurer</code> is equivalent to a new <code>TextMeasurer</code> created from the text; * however, it will usually be more efficient to update an existing <code>TextMeasurer</code> than * to create a new one from scratch. * * @param newParagraph the text of the paragraph after performing the insertion. Cannot be null. * @param insertPos the position in the text where the character was inserted. Must not be less * than the start of <code>newParagraph</code>, and must be less than the end of <code> * newParagraph</code>. * @throws IndexOutOfBoundsException if <code>insertPos</code> is less than the start of <code> * newParagraph</code> or greater than or equal to the end of <code>newParagraph</code> * @throws NullPointerException if <code>newParagraph</code> is <code>null</code> */ public void insertChar(AttributedCharacterIterator newParagraph, int insertPos) { if (collectStats) { printStats(); } if (wantStats) { collectStats = true; } fStart = newParagraph.getBeginIndex(); int end = newParagraph.getEndIndex(); if (end - fStart != fChars.length + 1) { initAll(newParagraph); } char[] newChars = new char[end - fStart]; int newCharIndex = insertPos - fStart; System.arraycopy(fChars, 0, newChars, 0, newCharIndex); char newChar = newParagraph.setIndex(insertPos); newChars[newCharIndex] = newChar; System.arraycopy(fChars, newCharIndex, newChars, newCharIndex + 1, end - insertPos - 1); fChars = newChars; if (fBidi != null || Bidi.requiresBidi(newChars, newCharIndex, newCharIndex + 1) || newParagraph.getAttribute(TextAttribute.BIDI_EMBEDDING) != null) { fBidi = new Bidi(newParagraph); if (fBidi.isLeftToRight()) { fBidi = null; } } fParagraph = StyledParagraph.insertChar(newParagraph, fChars, insertPos, fParagraph); invalidateComponents(); }