diff options
Diffstat (limited to 'libjava/classpath/java/awt/font/TextMeasurer.java')
-rw-r--r-- | libjava/classpath/java/awt/font/TextMeasurer.java | 149 |
1 files changed, 118 insertions, 31 deletions
diff --git a/libjava/classpath/java/awt/font/TextMeasurer.java b/libjava/classpath/java/awt/font/TextMeasurer.java index 18c286c57c1..00cab8a878d 100644 --- a/libjava/classpath/java/awt/font/TextMeasurer.java +++ b/libjava/classpath/java/awt/font/TextMeasurer.java @@ -1,5 +1,5 @@ /* TextMeasurer.java - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,67 +38,154 @@ exception statement from your version. */ package java.awt.font; -import gnu.classpath.NotImplementedException; - import java.text.AttributedCharacterIterator; +import java.text.AttributedString; +import java.awt.Shape; /** - * @author Michael Koch + * TextMeasurer is a small utility class for measuring the length of laid-out + * text objects. + * + * @author Sven de Marothy * @since 1.3 */ public final class TextMeasurer implements Cloneable { - private AttributedCharacterIterator ci; + private AttributedCharacterIterator text; private FontRenderContext frc; - + private TextLayout totalLayout; + private int numChars; + + /** + * Creates a TextMeasurer from a given text in the form of an + * <code>AttributedCharacterIterator</code> and a + * <code>FontRenderContext</code>. + */ public TextMeasurer (AttributedCharacterIterator text, FontRenderContext frc) { - this.ci = text; + this.text = text; this.frc = frc; + totalLayout = new TextLayout( text, frc ); + numChars = totalLayout.getCharacterCount(); } + /** + * Clones the TextMeasurer object + */ protected Object clone () { - try - { - return super.clone (); - } - catch (CloneNotSupportedException e) - { - // This may never occur - throw new InternalError (); - } + return new TextMeasurer( text, frc ); } + /** + * Update the text if a character is deleted at the position deletePos + * @param newParagraph - the updated paragraph. + * @param deletePos - the deletion position + */ public void deleteChar (AttributedCharacterIterator newParagraph, int deletePos) - throws NotImplementedException { - throw new Error ("not implemented"); + totalLayout = new TextLayout(newParagraph, frc); + if( deletePos < 0 || deletePos > totalLayout.getCharacterCount() ) + throw new NullPointerException("Invalid deletePos:"+deletePos); + numChars = totalLayout.getCharacterCount(); + text = newParagraph; + } + + /** + * Update the text if a character is inserted at the position insertPos + * @param newParagraph - the updated paragraph. + * @param insertPos - the insertion position + */ + public void insertChar (AttributedCharacterIterator newParagraph, + int insertPos) + { + totalLayout = new TextLayout(newParagraph, frc); + if( insertPos < 0 || insertPos > totalLayout.getCharacterCount() ) + throw new NullPointerException("Invalid insertPos:"+insertPos); + numChars = totalLayout.getCharacterCount(); + text = newParagraph; } + /*** + * Returns the total advance between two positions in the paragraph. + * Characters from start to limit-1 (inclusive) are included in this count. + * + * @param start - the starting character index. + * @param limit - the limiting index. + */ public float getAdvanceBetween (int start, int limit) - throws NotImplementedException { - throw new Error ("not implemented"); + Shape s = totalLayout.getLogicalHighlightShape( start, limit ); + return (float)s.getBounds2D().getWidth(); } + /** + * Returns a <code>TextLayout</code> object corresponding to the characters + * from text to limit. + * @param start - the starting character index. + * @param limit - the limiting index. + */ public TextLayout getLayout (int start, int limit) - throws NotImplementedException { - throw new Error ("not implemented"); + if( start >= limit ) + throw new IllegalArgumentException("Start position must be < limit."); + return new TextLayout( totalLayout, start, limit ); } + /** + * Returns the line-break index from a given starting index and a maximum + * advance. The index returned is the first character outside the given + * advance (or the limit of the string, if all remaining characters fit.) + * + * @param start - the starting index. + * @param maxAdvance - the maximum advance allowed. + * @return the index of the first character beyond maxAdvance, or the + * index of the last character + 1. + */ public int getLineBreakIndex (int start, float maxAdvance) - throws NotImplementedException - { - throw new Error ("not implemented"); - } + { + if( start < 0 ) + throw new IllegalArgumentException("Start parameter must be > 0."); + + double remainingLength = getAdvanceBetween( start, numChars ); + + int guessOffset = (int)( ( (double)maxAdvance / (double)remainingLength) + * ( (double)numChars - (double)start ) ); + guessOffset += start; + if( guessOffset > numChars ) + guessOffset = numChars; + + double guessLength = getAdvanceBetween( start, guessOffset ); + boolean makeSmaller = ( guessLength > maxAdvance ); + int inc = makeSmaller ? -1 : 1; + boolean keepGoing = true; + + do + { + guessOffset = guessOffset + inc; + if( guessOffset <= start || guessOffset > numChars ) + { + keepGoing = false; + } + else + { + guessLength = getAdvanceBetween( start, guessOffset ); + if( makeSmaller && ( guessLength <= maxAdvance) ) + keepGoing = false; + if( !makeSmaller && ( guessLength >= maxAdvance) ) + keepGoing = false; + } + } + while( keepGoing ); - public void insertChar (AttributedCharacterIterator newParagraph, - int insertPos) - throws NotImplementedException - { - throw new Error ("not implemented"); + // Return first index that doesn't fit. + if( !makeSmaller ) + guessOffset--; + + if( guessOffset > numChars ) + return numChars; + + return guessOffset; } } |