summaryrefslogtreecommitdiff
path: root/libjava/classpath/java/awt/font/TextMeasurer.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/java/awt/font/TextMeasurer.java')
-rw-r--r--libjava/classpath/java/awt/font/TextMeasurer.java149
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;
}
}