deweese 01/12/05 09:38:12 Modified: sources/org/apache/batik/gvt/renderer StrokingTextPainter.java Log: Now handles tspans/text with explicit glyph positioning (X&Y with lists) and text-anchor middle and end properly. Revision Changes Path 1.25 +89 -49 xml-batik/sources/org/apache/batik/gvt/renderer/StrokingTextPainter.java Index: StrokingTextPainter.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/renderer/StrokingTextPainter.java,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- StrokingTextPainter.java 2001/11/29 23:11:02 1.24 +++ StrokingTextPainter.java 2001/12/05 17:38:12 1.25 @@ -60,7 +60,7 @@ * @see org.apache.batik.gvt.text.GVTAttributedCharacterIterator * * @author <a href="[EMAIL PROTECTED]>Bill Haneman</a> - * @version $Id: StrokingTextPainter.java,v 1.24 2001/11/29 23:11:02 deweese Exp $ + * @version $Id: StrokingTextPainter.java,v 1.25 2001/12/05 17:38:12 deweese Exp $ */ public class StrokingTextPainter extends BasicTextPainter { @@ -80,6 +80,22 @@ AttributedCharacterIterator.Attribute BIDI_LEVEL = GVTAttributedCharacterIterator.TextAttribute.BIDI_LEVEL; + public static final + AttributedCharacterIterator.Attribute XPOS + = GVTAttributedCharacterIterator.TextAttribute.X; + + public static final + AttributedCharacterIterator.Attribute YPOS + = GVTAttributedCharacterIterator.TextAttribute.Y; + + public static final + AttributedCharacterIterator.Attribute TEXTPATH + = GVTAttributedCharacterIterator.TextAttribute.TEXTPATH; + + public static final + AttributedCharacterIterator.Attribute ANCHOR_TYPE + = GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE; + static Set extendedAtts = new HashSet(); static { @@ -200,53 +216,81 @@ (AttributedCharacterIterator aci) { List aciVector = new ArrayList(); - aci.first(); + int chunkStartIndex = aci.getBeginIndex(); + while (aci.setIndex(chunkStartIndex) != CharacterIterator.DONE) { + TextPath prevTextPath = null; + for (int start=chunkStartIndex, end=0; + aci.setIndex(start) != CharacterIterator.DONE; start=end) { - while (aci.current() != CharacterIterator.DONE) { + TextPath textPath = (TextPath) aci.getAttribute(TEXTPATH); - int chunkStartIndex = aci.getIndex(); - boolean inChunk = true; - boolean isChunkStart = true; - TextPath prevTextPath = null; + if (start != chunkStartIndex) { + // If we aren't the first composite in a chunck see + // if we need to form a new TextChunk... + Float runX = (Float) aci.getAttribute(XPOS); + Float runY = (Float) aci.getAttribute(YPOS); + + // Check if we have an absolute location + if ( ((runX != null) && !runX.isNaN()) + ||((runY != null) && !runY.isNaN())) + break; // If so end of chunk... + + // do additional check for the start of a textPath + if ((prevTextPath == null) && (textPath != null)) + break; // If so end of chunk. + } + + prevTextPath = textPath; - while (inChunk) { - int start = aci.getRunStart(TEXT_COMPOUND_DELIMITER); - int end = aci.getRunLimit(TEXT_COMPOUND_DELIMITER); + // find end of compound. + end = aci.getRunLimit(TEXT_COMPOUND_DELIMITER); + + if (start != chunkStartIndex) + // If we aren't starting a new chunk then we know + // we don't have any absolute positioning so there + // is no reason to consider spliting the chunk further. + continue; - // Go to start of compound. - aci.setIndex(start); - Float runX = (Float) aci.getAttribute - (GVTAttributedCharacterIterator.TextAttribute.X); - Float runY = (Float) aci.getAttribute - (GVTAttributedCharacterIterator.TextAttribute.Y); - TextPath textPath = (TextPath) aci.getAttribute - (GVTAttributedCharacterIterator.TextAttribute.TEXTPATH); - - inChunk = ( (isChunkStart) - || ( (runX == null || runX.isNaN()) - && (runY == null || runY.isNaN()))); - - // do additional check for the start of a textPath - if (prevTextPath == null && textPath != null && !isChunkStart) - inChunk = false; - - if (inChunk) { - prevTextPath = textPath; - aci.setIndex(end); - if (aci.current() == CharacterIterator.DONE) break; + // We are starting a new chunk + // So check if we need to split it further... + TextNode.Anchor anchor; + anchor = (TextNode.Anchor) aci.getAttribute(ANCHOR_TYPE); + if (anchor == TextNode.Anchor.START) + continue; + + // We need to check if we have a list of X's & Y's if + // so we need to create TextChunk ACI's for each char + // (technically we have to do this for + // text-anchor:start as well but since that is the + // default layout it doesn't matter in that case. + Float runX = (Float) aci.getAttribute(XPOS); + Float runY = (Float) aci.getAttribute(YPOS); + if (((runX == null) || runX.isNaN()) && + ((runY == null) || runY.isNaN())) + // No absolute positioning in this compound so continue. + continue; + + // Splitting the compound into one char chunks until + // we run out of Xs. + for (int i=start+1; i< end; i++) { + aci.setIndex(i); + runX = (Float) aci.getAttribute(XPOS); + runY = (Float) aci.getAttribute(YPOS); + if (((runX == null) || runX.isNaN()) && + ((runY == null) || runY.isNaN())) + break; + aciVector.add + (new AttributedCharacterSpanIterator(aci, i-1, i)); + chunkStartIndex = i; } - isChunkStart = false; } // found the end of a text chunck int chunkEndIndex = aci.getIndex(); - AttributedCharacterIterator chunkACI = - new AttributedCharacterSpanIterator - (aci, chunkStartIndex, chunkEndIndex); - // need to setIndex because creating the new ACI, - // looses the current index. - aci.setIndex(chunkEndIndex); - aciVector.add(chunkACI); + aciVector.add(new AttributedCharacterSpanIterator + (aci, chunkStartIndex, chunkEndIndex)); + + chunkStartIndex = chunkEndIndex; } // copy the text chunks into an array @@ -292,14 +336,10 @@ runaci = new AttributedCharacterSpanIterator(aci, start, end); runaci.first(); - Float runX = (Float) runaci.getAttribute - (GVTAttributedCharacterIterator.TextAttribute.X); + Float runX = (Float) runaci.getAttribute(XPOS); + Float runY = (Float) runaci.getAttribute(YPOS); - Float runY = (Float) runaci.getAttribute - (GVTAttributedCharacterIterator.TextAttribute.Y); - - TextPath textPath = (TextPath) runaci.getAttribute - (GVTAttributedCharacterIterator.TextAttribute.TEXTPATH); + TextPath textPath = (TextPath) runaci.getAttribute(TEXTPATH); Point2D offset; if (textPath == null) { @@ -310,9 +350,9 @@ ((float)prevTextPathAdvance.getX(), (float)prevTextPathAdvance.getY()); } else { - offset = new Point2D.Float( - (float) (location.getX()+advance.getX()), - (float) (location.getY()+advance.getY())); + offset = new Point2D.Float + ((float) (location.getX()+advance.getX()), + (float) (location.getY()+advance.getY())); } } else { // is on a text path so ignore the text node's location
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]