[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[commit-cp] classpath ChangeLog gnu/java/awt/peer/gtk/Freet...
From: |
Sven de Marothy |
Subject: |
[commit-cp] classpath ChangeLog gnu/java/awt/peer/gtk/Freet... |
Date: |
Sun, 18 Jun 2006 00:54:48 +0000 |
CVSROOT: /sources/classpath
Module name: classpath
Changes by: Sven de Marothy <smarothy> 06/06/18 00:54:47
Modified files:
. : ChangeLog
gnu/java/awt/peer/gtk: FreetypeGlyphVector.java
java/awt/font : LineBreakMeasurer.java TextLayout.java
TextMeasurer.java
java/text : AttributedString.java
Log message:
2006-06-18 Sven de Marothy <address@hidden>
* gnu/java/awt/peer/gtk/FreetypeGlyphVector.java
(FreetypeGlyphVector, clone): Implement cloning.
(getGlyphLogicalBounds): Bounds should be offset to the glyph
position.
* java/awt/font/TextMeasurer.java: Implement.
* java/awt/font/LineBreakMeasurer.java:
Reimplement to use TextMeasurer.
* java/awt/font/TextLayout.java
New constructors.
(getBlackboxBounds, getLogicalHighlightShape): Reimplement.
(getText, getFont): New private static methods.
(setCharIndices): New method.
* java/text/AttributedString.java
(AttributedString): Fix constructor to stop at end point.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/ChangeLog?cvsroot=classpath&r1=1.7861&r2=1.7862
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java?cvsroot=classpath&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/classpath/java/awt/font/LineBreakMeasurer.java?cvsroot=classpath&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/classpath/java/awt/font/TextLayout.java?cvsroot=classpath&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/classpath/java/awt/font/TextMeasurer.java?cvsroot=classpath&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/classpath/java/text/AttributedString.java?cvsroot=classpath&r1=1.15&r2=1.16
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/classpath/classpath/ChangeLog,v
retrieving revision 1.7861
retrieving revision 1.7862
diff -u -b -r1.7861 -r1.7862
--- ChangeLog 17 Jun 2006 23:58:41 -0000 1.7861
+++ ChangeLog 18 Jun 2006 00:54:46 -0000 1.7862
@@ -1,4 +1,20 @@
-2006-0-12 Mario torre <neugens at limasoftware.net>
+2006-06-18 Sven de Marothy <address@hidden>
+
+ * gnu/java/awt/peer/gtk/FreetypeGlyphVector.java
+ (FreetypeGlyphVector, clone): Implement cloning.
+ (getGlyphLogicalBounds): Bounds should be offset to the glyph position.
+ * java/awt/font/TextMeasurer.java: Implement.
+ * java/awt/font/LineBreakMeasurer.java:
+ Reimplement to use TextMeasurer.
+ * java/awt/font/TextLayout.java
+ New constructors.
+ (getBlackboxBounds, getLogicalHighlightShape): Reimplement.
+ (getText, getFont): New private static methods.
+ (setCharIndices): New method.
+ * java/text/AttributedString.java
+ (AttributedString): Fix constructor to stop at end point.
+
+2006-06-12 Mario torre <neugens at limasoftware.net>
* gnu/java/util/prefs/GConfBasedPreferences.java: new class.
* gnu/java/util/prefs/GConfBasedFactory.java: new class.
Index: gnu/java/awt/peer/gtk/FreetypeGlyphVector.java
===================================================================
RCS file:
/sources/classpath/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- gnu/java/awt/peer/gtk/FreetypeGlyphVector.java 11 Jun 2006 08:29:57
-0000 1.6
+++ gnu/java/awt/peer/gtk/FreetypeGlyphVector.java 18 Jun 2006 00:54:47
-0000 1.7
@@ -137,6 +137,35 @@
}
/**
+ * Cloning constructor
+ */
+ private FreetypeGlyphVector( FreetypeGlyphVector gv )
+ {
+ font = gv.font;
+ peer = gv.peer;
+ frc = gv.frc;
+ s = gv.s;
+ nGlyphs = gv.nGlyphs;
+ logicalBounds = gv.logicalBounds.getBounds2D();
+
+ if( gv.metricsCache != null )
+ {
+ metricsCache = new GlyphMetrics[ nGlyphs ];
+ System.arraycopy(gv.metricsCache, 0, metricsCache, 0, nGlyphs);
+ }
+
+ glyphCodes = new int[ nGlyphs ];
+ glyphPositions = new float[ nGlyphs ];
+ glyphTransforms = new AffineTransform[ nGlyphs ];
+ for(int i = 0; i < nGlyphs; i++ )
+ {
+ glyphTransforms[ i ] = new AffineTransform( gv.glyphTransforms[ i ] );
+ glyphCodes[i] = gv.glyphCodes[ i ];
+ glyphPositions[i] = gv.glyphPositions[ i ];
+ }
+ }
+
+ /**
* Create the array of glyph codes.
*/
private void getGlyphs()
@@ -172,6 +201,12 @@
private native GeneralPath getGlyphOutlineNative(int glyphIndex);
+
+ public Object clone()
+ {
+ return new FreetypeGlyphVector( this );
+ }
+
/**
* Duh, compares two instances.
*/
@@ -260,8 +295,11 @@
if( gm == null )
return null;
Rectangle2D r = gm.getBounds2D();
- return new Rectangle2D.Double( r.getX() - gm.getLSB(), r.getY(),
- gm.getAdvanceX(), r.getHeight() );
+ Point2D p = getGlyphPosition( glyphIndex );
+ return new Rectangle2D.Double( p.getX() + r.getX() - gm.getLSB(),
+ p.getY() + r.getY(),
+ gm.getAdvanceX(),
+ r.getHeight() );
}
/*
@@ -385,8 +423,6 @@
for( int i = 1; i < nGlyphs; i++ )
{
Rectangle2D r2 = (Rectangle2D)getGlyphLogicalBounds( i );
- Point2D p = getGlyphPosition( i );
- r2.setRect( p.getX(), p.getY(), r2.getWidth(), r2.getHeight() );
rect = rect.createUnion( r2 );
}
Index: java/awt/font/LineBreakMeasurer.java
===================================================================
RCS file: /sources/classpath/classpath/java/awt/font/LineBreakMeasurer.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- java/awt/font/LineBreakMeasurer.java 13 Jun 2006 00:14:27 -0000
1.4
+++ java/awt/font/LineBreakMeasurer.java 18 Jun 2006 00:54:47 -0000
1.5
@@ -41,57 +41,41 @@
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 text;
private int position;
- private FontRenderContext frc;
- private TextLayout totalLayout;
+ private TextMeasurer tm;
private int numChars;
public LineBreakMeasurer(AttributedCharacterIterator text,
BreakIterator breakIter, FontRenderContext frc)
{
- this.text = text;
- this.frc = frc;
- position = 0;
- totalLayout = new TextLayout(text, frc);
- numChars = totalLayout.getCharacterCount();
+ this( text, frc );
}
public LineBreakMeasurer(AttributedCharacterIterator text,
FontRenderContext frc)
{
this.text = text;
- this.frc = frc;
position = 0;
- totalLayout = new TextLayout(text, frc);
- numChars = totalLayout.getCharacterCount();
+ numChars = text.getEndIndex();
+ tm = new TextMeasurer( text, frc );
}
public void deleteChar(AttributedCharacterIterator newParagraph,
int deletePos)
{
- totalLayout = new TextLayout(newParagraph, frc);
- if( deletePos < 0 || deletePos > totalLayout.getCharacterCount() )
- throw new NullPointerException("Invalid deletePos:"+deletePos);
- numChars = totalLayout.getCharacterCount();
- text = newParagraph;
+ tm.deleteChar( newParagraph, deletePos );
position = 0;
}
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;
+ tm.insertChar( newParagraph, insertPos );
position = 0;
}
@@ -104,11 +88,9 @@
boolean requireNextWord)
{
int next = nextOffset( wrappingWidth, offsetLimit, requireNextWord );
- AttributedCharacterIterator aci = (new AttributedString( text,
- position, next )
- ).getIterator();
+ TextLayout tl = tm.getLayout( position, next );
position = next;
- return new TextLayout( aci, frc );
+ return tl;
}
public int nextOffset(float wrappingWidth)
@@ -119,69 +101,40 @@
public int nextOffset(float wrappingWidth, int offsetLimit,
boolean requireNextWord)
{
- Shape s = totalLayout.getBlackBoxBounds( position, offsetLimit );
- double remainingLength = s.getBounds2D().getWidth();
+ int guessOffset = tm.getLineBreakIndex(position, wrappingWidth);
+ if( offsetLimit > numChars )
+ offsetLimit = numChars;
- 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;
- }
+ text.setIndex( offsetLimit );
+ return offsetLimit;
}
- while( keepGoing );
- if( !makeSmaller )
- guessOffset--;
+ text.setIndex( guessOffset );
- if( guessOffset >= offsetLimit )
- return offsetLimit;
+ // If we're on a breaking character, return directly
+ if( Character.isWhitespace( text.current() ) )
+ return guessOffset;
- text.setIndex( guessOffset );
+ // Otherwise jump forward or backward to the last such char.
if( !requireNextWord )
- {
- char c = text.previous();
- while( !Character.isWhitespace( c ) && c != '-' &&
+ while( !Character.isWhitespace( text.previous() ) &&
guessOffset > position )
- {
guessOffset--;
- c = text.previous();
- }
- }
else
- {
- char c = text.next();
- while( !Character.isWhitespace( c ) && c != '-' &&
+ while( !Character.isWhitespace( text.next() ) &&
guessOffset < offsetLimit )
- {
guessOffset++;
- c = text.next();
- }
+
+ if( guessOffset > offsetLimit )
+ {
+ text.setIndex( offsetLimit );
+ return offsetLimit;
}
+ text.setIndex( guessOffset );
+
return guessOffset;
}
Index: java/awt/font/TextLayout.java
===================================================================
RCS file: /sources/classpath/classpath/java/awt/font/TextLayout.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- java/awt/font/TextLayout.java 16 Jun 2006 15:14:56 -0000 1.12
+++ java/awt/font/TextLayout.java 18 Jun 2006 00:54:47 -0000 1.13
@@ -47,6 +47,7 @@
import java.awt.geom.Rectangle2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
+import java.text.CharacterIterator;
import java.text.AttributedCharacterIterator;
import java.text.Bidi;
import java.util.Map;
@@ -71,6 +72,12 @@
private int[][] runIndices;
/**
+ * Character indices.
+ * Fixt index is the glyphvector, second index is the (first) glyph.
+ */
+ private int[][] charIndices;
+
+ /**
* Base directionality, determined from the first char.
*/
private boolean leftToRight;
@@ -137,6 +144,7 @@
Font.LAYOUT_LEFT_TO_RIGHT :
Font.LAYOUT_RIGHT_TO_LEFT );
}
+ setCharIndices();
}
public TextLayout (String string, Map attributes, FontRenderContext frc)
@@ -145,9 +153,97 @@
}
public TextLayout (AttributedCharacterIterator text, FontRenderContext frc)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ // FIXME: Very rudimentary.
+ this(getText(text), getFont(text), frc);
+ }
+
+ /**
+ * Package-private constructor to make a textlayout from an existing one.
+ * This is used by TextMeasurer for returning sub-layouts, and it
+ * saves a lot of time in not having to relayout the text.
+ */
+ TextLayout(TextLayout t, int startIndex, int endIndex)
+ {
+ font = t.font;
+ frc = t.frc;
+ boundsCache = null;
+ lm = t.lm;
+ leftToRight = t.leftToRight;
+
+ if( endIndex > t.getCharacterCount() )
+ endIndex = t.getCharacterCount();
+ string = t.string.substring( startIndex, endIndex );
+
+ int startingRun = t.charIndices[startIndex][0];
+ int nRuns = 1 + t.charIndices[endIndex - 1][0] - startingRun;
+ runIndices = new int[ nRuns ][2];
+
+ runs = new GlyphVector[ nRuns ];
+ for( int i = 0; i < nRuns; i++ )
+ {
+ GlyphVector run = t.runs[ i + startingRun ];
+ // Copy only the relevant parts of the first and last runs.
+ int beginGlyphIndex = (i > 0) ? 0 : t.charIndices[startIndex][1];
+ int numEntries = ( i < nRuns - 1) ? run.getNumGlyphs() :
+ 1 + t.charIndices[endIndex - 1][1] - beginGlyphIndex;
+
+ int[] codes = run.getGlyphCodes(beginGlyphIndex, numEntries, null);
+ runs[ i ] = font.createGlyphVector( frc, codes );
+ runIndices[ i ][0] = t.runIndices[i + startingRun][0] - startIndex;
+ runIndices[ i ][1] = t.runIndices[i + startingRun][1] - startIndex;
+ }
+ runIndices[ nRuns - 1 ][1] = endIndex - 1;
+
+ setCharIndices();
+ determineWhiteSpace();
+ }
+
+ private void setCharIndices()
+ {
+ charIndices = new int[ getCharacterCount() ][2];
+ int i = 0;
+ int currentChar = 0;
+ for(int run = 0; run < runs.length; run++)
+ {
+ currentChar = -1;
+ for( int gi = 0; gi < runs[ run ].getNumGlyphs(); gi++)
+ {
+ if( runs[ run ].getGlyphCharIndex( gi ) != currentChar )
+ {
+ charIndices[ i ][0] = run;
+ charIndices[ i ][1] = gi;
+ currentChar = runs[ run ].getGlyphCharIndex( gi );
+ i++;
+ }
+ }
+ }
+ }
+
+ private static String getText(AttributedCharacterIterator iter)
+ {
+ StringBuffer sb = new StringBuffer();
+ int idx = iter.getIndex();
+ for(char c = iter.first(); c != CharacterIterator.DONE; c = iter.next())
+ sb.append(c);
+ iter.setIndex( idx );
+ return sb.toString();
+ }
+
+ private static Font getFont(AttributedCharacterIterator iter)
+ {
+ Font f = (Font)iter.getAttribute(TextAttribute.FONT);
+ if( f == null )
+ {
+ int size;
+ Float i = (Float)iter.getAttribute(TextAttribute.SIZE);
+ if( i != null )
+ size = (int)i.floatValue();
+ else
+ size = 14;
+ f = new Font("Dialog", Font.PLAIN, size );
+ }
+ return f;
}
/**
@@ -177,10 +273,14 @@
gotDirection = true;
break;
}
+ determineWhiteSpace();
+ }
+ private void determineWhiteSpace()
+ {
// Determine if there's whitespace in the thing.
// Ignore trailing chars.
- i = string.length() - 1;
+ int i = string.length() - 1;
hasWhitespace = false;
while( i >= 0 && Character.isWhitespace( string.charAt(i) ) )
i--;
@@ -249,56 +349,42 @@
public Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint)
{
- if( firstEndpoint < 0 || secondEndpoint > getCharacterCount() )
+ if( secondEndpoint - firstEndpoint <= 0 )
+ return new Rectangle2D.Float(); // Hmm?
+
+ if( firstEndpoint < 0 || secondEndpoint > getCharacterCount())
return new Rectangle2D.Float();
GeneralPath gp = new GeneralPath();
- int i = 0; // run index
+
+ int ri = charIndices[ firstEndpoint ][0];
+ int gi = charIndices[ firstEndpoint ][1];
+
double advance = 0;
- // go to first run
- while( runIndices[i + 1][1] < firstEndpoint )
- {
+ for( int i = 0; i < ri; i++ )
advance += runs[i].getLogicalBounds().getWidth();
- i++;
- }
- int j = 0; // index into the run.
- if( runIndices[i][1] - runIndices[i][0] > 1 )
+ for( int i = ri; i <= charIndices[ secondEndpoint - 1 ][0]; i++ )
{
- while( runs[i].getGlyphCharIndex( j + 1 ) <
- (firstEndpoint - runIndices[i][0] ) )j++;
- }
-
- gp.append(runs[i].getGlyphVisualBounds( j ), false);
- boolean keepGoing = true;;
+ int dg;
+ if( i == charIndices[ secondEndpoint - 1 ][0] )
+ dg = charIndices[ secondEndpoint - 1][1];
+ else
+ dg = runs[i].getNumGlyphs() - 1;
- do
- {
- while( j < runs[i].getNumGlyphs() &&
- runs[i].getGlyphCharIndex( j ) + runIndices[i][0] <
- secondEndpoint )
+ for( int j = 0; j <= dg; j++ )
{
Rectangle2D r2 = (runs[i].getGlyphVisualBounds( j )).
getBounds2D();
Point2D p = runs[i].getGlyphPosition( j );
- r2.setRect( advance + p.getX(), r2.getY(),
+ r2.setRect( advance + r2.getX(), r2.getY(),
r2.getWidth(), r2.getHeight() );
gp.append(r2, false);
- j++;
}
- if( j >= runs[i].getNumGlyphs() )
- {
advance += runs[i].getLogicalBounds().getWidth();
- i++;
- j = 0;
- }
- else
- keepGoing = false;
}
- while( keepGoing );
-
return gp;
}
@@ -382,55 +468,42 @@
public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint,
Rectangle2D bounds)
{
- if( firstEndpoint < 0 || secondEndpoint > getCharacterCount() )
+ if( secondEndpoint - firstEndpoint <= 0 )
+ return new Rectangle2D.Float(); // Hmm?
+
+ if( firstEndpoint < 0 || secondEndpoint > getCharacterCount())
return new Rectangle2D.Float();
- int i = 0; // run index
+ Rectangle2D r = null;
+ int ri = charIndices[ firstEndpoint ][0];
+ int gi = charIndices[ firstEndpoint ][1];
+
double advance = 0;
- // go to first run
- if( i > 0 )
- while( runIndices[i + 1][1] < firstEndpoint )
- {
+ for( int i = 0; i < ri; i++ )
advance += runs[i].getLogicalBounds().getWidth();
- i++;
- }
- int j = 0; // index into the run.
- if( runIndices[i][1] - runIndices[i][0] > 1 )
+ for( int i = ri; i <= charIndices[ secondEndpoint - 1 ][0]; i++ )
{
- while( runs[i].getGlyphCharIndex( j + 1 ) <
- (firstEndpoint - runIndices[i][0] ) )j++;
- }
-
- Rectangle2D r = (runs[i].getGlyphLogicalBounds( j )).getBounds2D();
- boolean keepGoing = true;;
+ int dg; // last index in this run to use.
+ if( i == charIndices[ secondEndpoint - 1 ][0] )
+ dg = charIndices[ secondEndpoint - 1][1];
+ else
+ dg = runs[i].getNumGlyphs() - 1;
- do
+ for(; gi <= dg; gi++ )
{
- while( j < runs[i].getNumGlyphs() &&
- runs[i].getGlyphCharIndex( j ) + runIndices[i][0] <
- secondEndpoint )
- {
- Rectangle2D r2 = (runs[i].getGlyphLogicalBounds( j )).
+ Rectangle2D r2 = (runs[i].getGlyphLogicalBounds( gi )).
getBounds2D();
- Point2D p = runs[i].getGlyphPosition( j );
- r2.setRect( advance + p.getX(), r2.getY(),
- r2.getWidth(), r2.getHeight() );
- r = r.createUnion( r2 );
- j++;
+ if( r == null )
+ r = r2;
+ else
+ r = r.createUnion(r2);
}
+ gi = 0; // reset glyph index into run for next run.
- if( j >= runs[i].getNumGlyphs() )
- {
advance += runs[i].getLogicalBounds().getWidth();
- i++;
- j = 0;
- }
- else
- keepGoing = false;
}
- while( keepGoing );
return r;
}
Index: java/awt/font/TextMeasurer.java
===================================================================
RCS file: /sources/classpath/classpath/java/awt/font/TextMeasurer.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- java/awt/font/TextMeasurer.java 22 Mar 2006 19:15:24 -0000 1.3
+++ java/awt/font/TextMeasurer.java 18 Jun 2006 00:54:47 -0000 1.4
@@ -38,67 +38,156 @@
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;
}
- public float getAdvanceBetween (int start, int limit)
- throws NotImplementedException
+ /**
+ * 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)
{
- throw new Error ("not implemented");
+ totalLayout = new TextLayout(newParagraph, frc);
+ if( insertPos < 0 || insertPos > totalLayout.getCharacterCount() )
+ throw new NullPointerException("Invalid insertPos:"+insertPos);
+ numChars = totalLayout.getCharacterCount();
+ text = newParagraph;
}
- public TextLayout getLayout (int start, int limit)
- throws NotImplementedException
+ /***
+ * 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)
{
- 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)
+ {
+// AttributedCharacterIterator aci = (new AttributedString( text,
+// start, limit
+// ) ).getIterator();
+// return new TextLayout( aci, frc );
+ 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.");
- public void insertChar (AttributedCharacterIterator newParagraph,
- int insertPos)
- throws NotImplementedException
+ 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
{
- throw new Error ("not implemented");
+ 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 );
+
+ // Return first index that doesn't fit.
+ if( !makeSmaller )
+ guessOffset--;
+
+ if( guessOffset > numChars )
+ return numChars;
+
+ return guessOffset;
}
}
Index: java/text/AttributedString.java
===================================================================
RCS file: /sources/classpath/classpath/java/text/AttributedString.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- java/text/AttributedString.java 24 Oct 2005 10:04:22 -0000 1.15
+++ java/text/AttributedString.java 18 Jun 2006 00:54:47 -0000 1.16
@@ -221,16 +221,13 @@
// If the attribute run starts before the beginning index, we
// need to junk it if it is an Annotation.
Object attrib_obj = aci.getAttribute(attrib);
- if (rs < begin)
+ rs -= begin;
+ if (rs < 0)
{
if (attrib_obj instanceof Annotation)
continue;
- rs = begin;
- }
- else
- {
- rs -= begin;
+ rs = 0;
}
// Create a map object. Yes this will only contain one attribute
@@ -243,7 +240,7 @@
c = aci.next();
}
- while(c != CharacterIterator.DONE);
+ while( aci.getIndex() < end );
attribs = new AttributeRange[accum.size()];
attribs = (AttributeRange[]) accum.toArray(attribs);