Here's LineBreakMeasurer. The rest of you can't quite use it yet because
the CVS TextLayout isn't up to snuff. So you'll just have to take my
word for it. :) 

2006-06-12  Sven de Marothy  <[EMAIL PROTECTED]>

        * java/awt/font/LineBreakMeasurer.java): Implement.


Index: java/awt/font/LineBreakMeasurer.java
===================================================================
RCS file: /sources/classpath/classpath/java/awt/font/LineBreakMeasurer.java,v
retrieving revision 1.3
diff -U3 -r1.3 LineBreakMeasurer.java
--- java/awt/font/LineBreakMeasurer.java	22 Mar 2006 19:15:24 -0000	1.3
+++ java/awt/font/LineBreakMeasurer.java	13 Jun 2006 00:12:13 -0000
@@ -1,5 +1,5 @@
 /* LineBreakMeasurer.java
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -38,84 +38,161 @@
 
 package java.awt.font;
 
-import gnu.classpath.NotImplementedException;
-
 import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
 import java.text.BreakIterator;
+import java.awt.font.TextLayout;
+import java.awt.font.FontRenderContext;
+import java.awt.Shape;
 
 public final class LineBreakMeasurer
 {
-  private AttributedCharacterIterator ci;
+  private AttributedCharacterIterator text;
+  private int position;
   private FontRenderContext frc;
-  private BreakIterator bi;
+  private TextLayout totalLayout;
+  private int numChars;
 
-  /**
-   * Constructs a <code>LineBreakMeasurer</code> object.
-   */
-  public LineBreakMeasurer (AttributedCharacterIterator text,
-                            FontRenderContext frc)
+  public LineBreakMeasurer(AttributedCharacterIterator text, 
+			   BreakIterator breakIter, FontRenderContext frc)
   {
-    this (text, null, frc);
+    this.text = text;
+    this.frc = frc;
+    position = 0;
+    totalLayout = new TextLayout(text, frc);
+    numChars = totalLayout.getCharacterCount();
   }
 
-  /**
-   * Constructs a <code>LineBreakMeasurer</code> object.
-   */
-  public LineBreakMeasurer (AttributedCharacterIterator text,
-                            BreakIterator breakIter, FontRenderContext frc) 
+  public LineBreakMeasurer(AttributedCharacterIterator text, 
+			   FontRenderContext frc)
   {
-    this.ci = text;
-    this.bi = breakIter;
+    this.text = text;
     this.frc = frc;
+    position = 0;
+    totalLayout = new TextLayout(text, frc);
+    numChars = totalLayout.getCharacterCount();
   }
 
-  public void deleteChar (AttributedCharacterIterator newParagraph,
-                          int deletePos)
-    throws NotImplementedException
+  public void deleteChar(AttributedCharacterIterator newParagraph, 
+			 int deletePos)
   {
-    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;
+    position = 0;
   }
 
-  public int getPosition ()
+  public void insertChar(AttributedCharacterIterator newParagraph, 
+			 int insertPos)
   {
-    return ci.getIndex ();
+    totalLayout = new TextLayout(newParagraph, frc);
+    if( insertPos < 0 || insertPos > totalLayout.getCharacterCount() )
+      throw new NullPointerException("Invalid insertPos:"+insertPos);
+    numChars = totalLayout.getCharacterCount();
+    text = newParagraph;
+    position = 0;
   }
 
-  public void insertChar (AttributedCharacterIterator newParagraph,
-                          int insertPos)
-    throws NotImplementedException
+  public TextLayout nextLayout(float wrappingWidth)
   {
-    throw new Error ("not implemented");
+    return nextLayout( wrappingWidth, numChars, false );
   }
 
-  public TextLayout nextLayout (float wrappingWidth)
-    throws NotImplementedException
+  public TextLayout nextLayout(float wrappingWidth, int offsetLimit, 
+			       boolean requireNextWord)
   {
-    throw new Error ("not implemented");
+    int next = nextOffset( wrappingWidth, offsetLimit, requireNextWord );
+    AttributedCharacterIterator aci = (new AttributedString( text, 
+							     position, next )
+				       ).getIterator();
+    position = next;
+    return new TextLayout( aci, frc );
   }
 
-  public TextLayout nextLayout (float wrappingWidth, int offsetLimit,
-                                boolean requireNextWord)
-    throws NotImplementedException
+  public int nextOffset(float wrappingWidth)
   {
-    throw new Error ("not implemented");
+    return nextOffset( wrappingWidth, numChars, false );
   }
 
-  public int nextOffset (float wrappingWidth)
-    throws NotImplementedException
+  public int nextOffset(float wrappingWidth, int offsetLimit, 
+			boolean requireNextWord)
   {
-    throw new Error ("not implemented");
+    Shape s = totalLayout.getBlackBoxBounds( position, offsetLimit );
+    double remainingLength = s.getBounds2D().getWidth();
+
+    int guessOffset = (int)( ( (double)wrappingWidth / (double)remainingLength)
+			     * ( (double)numChars - (double)position ) );
+    guessOffset += position;
+    if( guessOffset > offsetLimit )
+      guessOffset = offsetLimit;
+
+    s = totalLayout.getBlackBoxBounds( position, guessOffset );
+    double guessLength = s.getBounds2D().getWidth();
+
+    boolean makeSmaller = ( guessLength > wrappingWidth );
+    int inc = makeSmaller ? -1 : 1;
+    boolean keepGoing = true;
+
+    do
+      {
+	guessOffset = guessOffset + inc;
+	if( guessOffset <= position || guessOffset > offsetLimit )
+	  {
+	    keepGoing = false;
+	  }
+	else
+	  {
+	    s = totalLayout.getBlackBoxBounds( position, guessOffset );
+	    guessLength = s.getBounds2D().getWidth();
+	    if( makeSmaller && ( guessLength <= wrappingWidth) )	  
+	      keepGoing = false;
+	    if( !makeSmaller && ( guessLength >= wrappingWidth) )
+	      keepGoing = false;
+	  }
+      }
+    while( keepGoing );
+
+    if( !makeSmaller )
+      guessOffset--;
+
+    if( guessOffset >= offsetLimit )
+      return offsetLimit;
+
+    text.setIndex( guessOffset );
+    if( !requireNextWord )
+      {
+	char c = text.previous();
+	while( !Character.isWhitespace( c ) && c != '-' && 
+	       guessOffset > position )
+	  { 
+	    guessOffset--; 
+	    c = text.previous();
+	  }
+      }
+    else
+      {
+	char c = text.next();
+	while( !Character.isWhitespace( c ) && c != '-' && 
+	       guessOffset < offsetLimit )
+	  {
+	    guessOffset++;
+	    c = text.next();
+	  }
+      }
+
+    return guessOffset;
   }
 
-  public int nextOffset (float wrappingWidth, int offsetLimit,
-                         boolean requireNextWord)
-    throws NotImplementedException
+  public void setPosition(int newPosition)
   {
-    throw new Error ("not implemented");
+    position = newPosition;
   }
 
-  public void setPosition (int newPosition)
+  public int getPosition()
   {
-    ci.setIndex (newPosition);
+    return position;
   }
 }
+

Reply via email to