deweese 2002/08/12 13:34:35 Modified: sources/org/apache/batik/bridge BridgeEventSupport.java SVGLinearGradientElementBridge.java sources/org/apache/batik/gvt TextNode.java TextPainter.java sources/org/apache/batik/gvt/font AWTGVTGlyphVector.java GVTGlyphVector.java Glyph.java MultiGlyphVector.java SVGGVTGlyphVector.java sources/org/apache/batik/gvt/renderer BasicTextPainter.java StrokingTextPainter.java sources/org/apache/batik/gvt/text GlyphLayout.java TextSpanLayout.java Log: 1) SVG Font's not accounting for stroke inherited from text element is fixed (PR 9957) 2) The TextPainter & GlyphVector bounds menthod names have been rationalized > Summary of changes in TextPainter (similar changes in GlyphVector): > > Remove: > Shape getShape(TextNode node); > Shape getDecoratedShape(TextNode node); > Rectangle2D getBounds(TextNode node); > Rectangle2D getDecoratedBounds(TextNode node); > Rectangle2D getPaintedBounds(TextNode node); > > Add: > > Shape getOutline(TextNode node); // ~ current getDecoratedShape. > Rectangle2D getBounds2D(TextNode node); // ~ current getPaintedBounds > Rectangle2D getGeometryBounds(TextNode node); // ~ current getBounds PR: 9957 Revision Changes Path 1.43 +2 -2 xml-batik/sources/org/apache/batik/bridge/BridgeEventSupport.java Index: BridgeEventSupport.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/BridgeEventSupport.java,v retrieving revision 1.42 retrieving revision 1.43 diff -u -r1.42 -r1.43 --- BridgeEventSupport.java 19 Jun 2002 08:15:26 -0000 1.42 +++ BridgeEventSupport.java 12 Aug 2002 20:34:33 -0000 1.43 @@ -399,7 +399,7 @@ float x = (float)coords.getX(); float y = (float)coords.getY(); TextHit textHit = layout.hitTestChar(x, y); - if (textHit != null && layout.getBounds().contains(x, y)) { + if (textHit != null && layout.getBounds2D().contains(x, y)) { Object delimiter = aci.getAttribute (GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_DELIMITER); if (delimiter instanceof Element) { 1.8 +2 -1 xml-batik/sources/org/apache/batik/bridge/SVGLinearGradientElementBridge.java Index: SVGLinearGradientElementBridge.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGLinearGradientElementBridge.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- SVGLinearGradientElementBridge.java 20 Mar 2002 16:34:43 -0000 1.7 +++ SVGLinearGradientElementBridge.java 12 Aug 2002 20:34:33 -0000 1.8 @@ -125,6 +125,7 @@ SVG_Y2_ATTRIBUTE, coordSystemType, uctx); + // If x1 = x2 and y1 = y2, then the area to be painted will be painted // as a single color using the color and opacity of the last gradient // stop. 1.25 +5 -5 xml-batik/sources/org/apache/batik/gvt/TextNode.java Index: TextNode.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/TextNode.java,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- TextNode.java 29 Apr 2002 13:20:19 -0000 1.24 +++ TextNode.java 12 Aug 2002 20:34:34 -0000 1.25 @@ -220,7 +220,7 @@ public Rectangle2D getPrimitiveBounds(){ if (primitiveBounds == null) { if (aci != null) { - primitiveBounds = textPainter.getPaintedBounds(this); + primitiveBounds = textPainter.getBounds2D(this); } } return primitiveBounds; @@ -234,7 +234,7 @@ public Rectangle2D getGeometryBounds(){ if (geometryBounds == null){ if (aci != null) { - geometryBounds = textPainter.getBounds(this); + geometryBounds = textPainter.getGeometryBounds(this); } } return geometryBounds; @@ -246,7 +246,7 @@ public Shape getOutline() { if (outline == null) { if (aci != null) { - outline = textPainter.getDecoratedShape(this); + outline = textPainter.getOutline(this); } } return outline; @@ -409,7 +409,7 @@ float x = (float)p.getX(); float y = (float)p.getY(); TextHit textHit = layout.hitTestChar(x, y); - if (textHit != null && contains(p, layout.getBounds())) { + if (textHit != null && contains(p, layout.getBounds2D())) { return true; } } 1.16 +13 -44 xml-batik/sources/org/apache/batik/gvt/TextPainter.java Index: TextPainter.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/TextPainter.java,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- TextPainter.java 3 Oct 2001 16:08:19 -0000 1.15 +++ TextPainter.java 12 Aug 2002 20:34:34 -0000 1.16 @@ -66,7 +66,7 @@ */ Mark getMark(TextNode node, int index, boolean beforeGlyph); - /* + /** * Get an array of index pairs corresponding to the indices within an * AttributedCharacterIterator regions bounded by two Marks. * @@ -77,7 +77,7 @@ int[] getSelected(Mark start, Mark finish); - /* + /** * Get a Shape in userspace coords which encloses the textnode * glyphs bounded by two Marks. * Note that the instances of Mark passed to this function @@ -88,56 +88,25 @@ */ Shape getHighlightShape(Mark beginMark, Mark endMark); - /* - * Get a Shape in userspace coords which defines the textnode glyph outlines. + /** + * Get a Shape in userspace coords which defines the textnode + * glyph outlines. * @param node the TextNode to measure - * @param frc the font rendering context. - * @param includeDecoration whether to include text decoration - * outlines. - * @param includeStroke whether to create the "stroke shape outlines" - * instead of glyph outlines. */ - Shape getShape(TextNode node); + Shape getOutline(TextNode node); - /* - * Get a Shape in userspace coords which defines the textnode glyph outlines. - * @param node the TextNode to measure - * @param frc the font rendering context. - * @param includeDecoration whether to include text decoration - * outlines. - * @param includeStroke whether to create the "stroke shape outlines" - * instead of glyph outlines. - */ - Shape getDecoratedShape(TextNode node); - - /* + /** * Get a Rectangle2D in userspace coords which encloses the textnode - * glyphs composed from an AttributedCharacterIterator. + * glyphs rendered bounds (includes stroke etc). * @param node the TextNode to measure - * @param g2d the Graphics2D to use - * @param context rendering context. */ - Rectangle2D getBounds(TextNode node); + Rectangle2D getBounds2D(TextNode node); - /* + /** * Get a Rectangle2D in userspace coords which encloses the textnode - * glyphs composed from an AttributedCharacterIterator, inclusive of - * glyph decoration (underline, overline, strikethrough). + * glyphs just including the geometry info. * @param node the TextNode to measure - * @param g2d the Graphics2D to use - * @param context rendering context. */ - Rectangle2D getDecoratedBounds(TextNode node); - - /* - * Get a Rectangle2D in userspace coords which encloses the - * textnode glyphs (as-painted, inclusive of decoration and stroke, but - * exclusive of filters, etc.) composed from an AttributedCharacterIterator. - * @param node the TextNode to measure - * @param g2d the Graphics2D to use - * @param context rendering context. - */ - Rectangle2D getPaintedBounds(TextNode node); - + Rectangle2D getGeometryBounds(TextNode node); } 1.19 +55 -9 xml-batik/sources/org/apache/batik/gvt/font/AWTGVTGlyphVector.java Index: AWTGVTGlyphVector.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/font/AWTGVTGlyphVector.java,v retrieving revision 1.18 retrieving revision 1.19 diff -u -r1.18 -r1.19 --- AWTGVTGlyphVector.java 30 Apr 2002 19:08:47 -0000 1.18 +++ AWTGVTGlyphVector.java 12 Aug 2002 20:34:34 -0000 1.19 @@ -57,7 +57,9 @@ private boolean[] glyphVisible; private GVTGlyphMetrics [] glyphMetrics; private GeneralPath outline; + private Rectangle2D visualBounds; private Rectangle2D logicalBounds; + private Rectangle2D bounds2D; private float scaleFactor; private float ascent; private float descent; @@ -92,7 +94,9 @@ descent = lineMetrics.getDescent(); outline = null; + visualBounds = null; logicalBounds = null; + bounds2D = null; int numGlyphs = glyphVector.getNumGlyphs(); glyphPositions = new Point2D.Float [numGlyphs+1]; glyphTransforms = new AffineTransform[numGlyphs]; @@ -146,7 +150,44 @@ } /** + * Returns a tight bounds on the GylphVector including stroking. + */ + public Rectangle2D getBounds2D(AttributedCharacterIterator aci) { + if (bounds2D != null) + return bounds2D; + + Shape outline = null; + + aci.first(); + Paint fillP = (Paint)aci.getAttribute(TextAttribute.FOREGROUND); + if (fillP != null) { + outline = getOutline(); + bounds2D = outline.getBounds2D(); + } + + // check if we need to include the + // outline of this glyph + Stroke stroke = (Stroke) aci.getAttribute + (GVTAttributedCharacterIterator.TextAttribute.STROKE); + Paint paint = (Paint) aci.getAttribute + (GVTAttributedCharacterIterator.TextAttribute.STROKE_PAINT); + if ((stroke != null) && (paint != null)) { + if (outline == null) + outline = getOutline(); + Rectangle2D strokeBounds + = stroke.createStrokedShape(outline).getBounds2D(); + if (bounds2D == null) + bounds2D = strokeBounds; + else + bounds2D = bounds2D.createUnion(strokeBounds); + } + + return bounds2D; + } + + /** * Returns the logical bounds of this GlyphVector. + * This is a bound useful for hit detection and highlighting. */ public Rectangle2D getLogicalBounds() { if (logicalBounds == null) { @@ -554,14 +595,12 @@ return outline; } - private Rectangle2D visualBounds; - /** * Returns the visual bounds of this GlyphVector The visual bounds is the * tightest rectangle enclosing all non-background pixels in the rendered * representation of this GlyphVector. */ - public Rectangle2D getVisualBounds() { + public Rectangle2D getGeometricBounds() { if (visualBounds == null) { Shape outline = getOutline(); visualBounds = outline.getBounds2D(); @@ -583,6 +622,7 @@ outline = null; visualBounds = null; logicalBounds = null; + bounds2D = null; float shiftLeft = 0; int i=0; for (; i < getNumGlyphs(); i++) { @@ -617,9 +657,11 @@ public void setGlyphPosition(int glyphIndex, Point2D newPos) { glyphPositions[glyphIndex] = new Point2D.Float((float)newPos.getX(), (float)newPos.getY()); - outline = null; + outline = null; + visualBounds = null; logicalBounds = null; - visualBounds = null; + bounds2D = null; + if (glyphIndex != getNumGlyphs()) { glyphVisualBounds [glyphIndex] = null; glyphLogicalBounds[glyphIndex] = null; @@ -633,9 +675,11 @@ */ public void setGlyphTransform(int glyphIndex, AffineTransform newTX) { glyphTransforms[glyphIndex] = newTX; - outline = null; + outline = null; + visualBounds = null; logicalBounds = null; - visualBounds = null; + bounds2D = null; + glyphVisualBounds [glyphIndex] = null; glyphLogicalBounds[glyphIndex] = null; glyphOutlines [glyphIndex] = null; @@ -650,8 +694,10 @@ return; glyphVisible[glyphIndex] = visible; outline = null; - logicalBounds = null; visualBounds = null; + logicalBounds = null; + bounds2D = null; + glyphVisualBounds [glyphIndex] = null; glyphLogicalBounds[glyphIndex] = null; glyphOutlines [glyphIndex] = null; 1.9 +15 -4 xml-batik/sources/org/apache/batik/gvt/font/GVTGlyphVector.java Index: GVTGlyphVector.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/font/GVTGlyphVector.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- GVTGlyphVector.java 30 Apr 2002 19:08:47 -0000 1.8 +++ GVTGlyphVector.java 12 Aug 2002 20:34:34 -0000 1.9 @@ -57,7 +57,9 @@ /** * Returns the logical bounds of the specified glyph within this - * GlyphVector. + * GlyphVector. This is a good bound for hit detection and + * highlighting it is not tight in any sense, and in some (rare) + * cases may exclude parts of the glyph. */ Shape getGlyphLogicalBounds(int glyphIndex); @@ -96,7 +98,10 @@ Shape getGlyphVisualBounds(int glyphIndex); /** - * Returns the logical bounds of this GlyphVector. + * Returns the logical bounds of this GlyphVector. This is a + * good bound for hit detection and highlighting it is not tight + * in any sense, and in some (rare) * cases may exclude parts of + * the glyph. */ Rectangle2D getLogicalBounds(); @@ -122,7 +127,13 @@ * tightest rectangle enclosing all non-background pixels in the rendered * representation of this GlyphVector. */ - Rectangle2D getVisualBounds(); + Rectangle2D getGeometricBounds(); + + /** + * Returns a tight bounds on the GylphVector including stroking. + * @param aci Required to get painting attributes of glyphVector. + */ + Rectangle2D getBounds2D(AttributedCharacterIterator aci); /** * Assigns default positions to each glyph in this GlyphVector. 1.9 +44 -21 xml-batik/sources/org/apache/batik/gvt/font/Glyph.java Index: Glyph.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/font/Glyph.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- Glyph.java 18 Sep 2001 21:19:00 -0000 1.8 +++ Glyph.java 12 Aug 2002 20:34:34 -0000 1.9 @@ -47,6 +47,7 @@ private float kernScale; private Shape outline; // cache the glyph outline + private Rectangle2D bounds; // cache the glyph bounds private Paint fillPaint; private Paint strokePaint; @@ -97,6 +98,7 @@ this.glyphCode = glyphCode; this.position = new Point2D.Float(0,0); this.outline = null; + this.bounds = null; this.fillPaint = fillPaint; @@ -218,6 +220,7 @@ public void setTransform(AffineTransform transform) { this.transform = transform; outline = null; + bounds = null; } /** @@ -237,6 +240,7 @@ public void setPosition(Point2D position) { this.position = position; outline = null; + bounds = null; } /** @@ -247,9 +251,9 @@ public GVTGlyphMetrics getGlyphMetrics() { if (metrics == null) { metrics = new GVTGlyphMetrics(getHorizAdvX(), - getVertAdvY(), - getBounds(), - GlyphMetrics.COMPONENT); + getVertAdvY(), + getGeometryBounds(), + GlyphMetrics.COMPONENT); } return metrics; } @@ -266,31 +270,50 @@ public GVTGlyphMetrics getGlyphMetrics(float hkern, float vkern) { return new GVTGlyphMetrics(getHorizAdvX() - (hkern * kernScale), getVertAdvY() - (vkern * kernScale), - getBounds(), GlyphMetrics.COMPONENT); + getGeometryBounds(), + GlyphMetrics.COMPONENT); } - public Rectangle2D getBounds() { + public Rectangle2D getGeometryBounds() { + return getOutline().getBounds2D(); + } + + public Rectangle2D getBounds2D() { + if (bounds != null) + return bounds; - if (dShape != null && glyphChildrenNode == null) { - return dShape.getBounds2D(); + AffineTransform tr = + AffineTransform.getTranslateInstance(position.getX(), + position.getY()); + if (transform != null) { + tr.concatenate(transform); } - if (glyphChildrenNode != null && dShape == null) { - return glyphChildrenNode.getOutline().getBounds2D(); + + Rectangle2D bounds = null; + if (dShape != null) { + if (fillPaint != null) + bounds = tr.createTransformedShape(dShape).getBounds2D(); + + if ((stroke != null) && (strokePaint != null)) { + Shape s = stroke.createStrokedShape(dShape); + Rectangle2D r = tr.createTransformedShape(s).getBounds2D(); + if (bounds == null) bounds = r; + else bounds = r.createUnion(bounds); + } } - if (dShape != null && glyphChildrenNode != null) { - Rectangle2D dBounds = dShape.getBounds2D(); - Rectangle2D childrenBounds = - glyphChildrenNode.getOutline().getBounds2D(); + if (glyphChildrenNode != null) { + Rectangle2D r = glyphChildrenNode.getTransformedBounds(tr); + if (bounds == null) bounds = r; + else bounds = r.createUnion(bounds); + } + if (bounds == null) + bounds = new Rectangle2D.Double + (position.getX(), position.getY(), 0, 0); - return dBounds.createUnion(childrenBounds); - } else { - return new Rectangle2D.Double(0,0,0,0); - } + return bounds; } - - /** * Returns the outline of this glyph. This will be positioned correctly and 1.3 +24 -5 xml-batik/sources/org/apache/batik/gvt/font/MultiGlyphVector.java Index: MultiGlyphVector.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/font/MultiGlyphVector.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- MultiGlyphVector.java 30 Apr 2002 19:08:47 -0000 1.2 +++ MultiGlyphVector.java 12 Aug 2002 20:34:34 -0000 1.3 @@ -308,14 +308,33 @@ } /** - * Returns the visual bounds of this GlyphVector The visual bounds is the - * tightest rectangle enclosing all non-background pixels in the rendered - * representation of this GlyphVector. + * Returns the bounds of this GlyphVector. This includes + * stroking effects. */ - public Rectangle2D getVisualBounds() { + public Rectangle2D getBounds2D(AttributedCharacterIterator aci) { Rectangle2D ret = null; + int begin = aci.getBeginIndex(); for (int idx=0; idx<gvs.length; idx++) { - Rectangle2D b = gvs[idx].getVisualBounds(); + GVTGlyphVector gv = gvs[idx]; + int end = gv.getCharacterCount(0, gv.getNumGlyphs())+1; + Rectangle2D b = gvs[idx].getBounds2D + (new AttributedCharacterSpanIterator(aci, begin, end)); + if (ret == null) ret = b; + else ret = ret.createUnion(b); + begin = end; + } + return ret; + } + + /** + * Returns the geometric bounds of this GlyphVector. The geometric + * bounds is the bounds of the geometry of the glyph vector, + * disregarding stroking. + */ + public Rectangle2D getGeometricBounds() { + Rectangle2D ret = null; + for (int idx=0; idx<gvs.length; idx++) { + Rectangle2D b = gvs[idx].getGeometricBounds(); if (ret == null) ret = b; else ret = ret.createUnion(b); } 1.13 +36 -6 xml-batik/sources/org/apache/batik/gvt/font/SVGGVTGlyphVector.java Index: SVGGVTGlyphVector.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/font/SVGGVTGlyphVector.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- SVGGVTGlyphVector.java 30 Apr 2002 19:08:47 -0000 1.12 +++ SVGGVTGlyphVector.java 12 Aug 2002 20:34:34 -0000 1.13 @@ -38,6 +38,7 @@ private FontRenderContext frc; private GeneralPath outline; private Rectangle2D logicalBounds; + private Rectangle2D bounds2D; private Shape[] glyphLogicalBounds; private boolean[] glyphVisible; private Point2D endPos; @@ -56,6 +57,7 @@ this.glyphs = glyphs; this.frc = frc; outline = null; + bounds2D = null; logicalBounds = null; glyphLogicalBounds = new Shape[glyphs.length]; glyphVisible = new boolean[glyphs.length]; @@ -550,8 +552,32 @@ return glyphs[glyphIndex].getOutline(); } - /** + /** + * Returns a tight bounds on the GylphVector including stroking. + */ + public Rectangle2D getBounds2D(AttributedCharacterIterator aci) { + // System.out.println("GlyphVector.getBounds2D Called: " + this); + if (bounds2D != null) + return bounds2D; + + Rectangle2D b=null; + for (int i = 0; i < getNumGlyphs(); i++) { + if (!glyphVisible[i]) continue; + + Rectangle2D glyphBounds = glyphs[i].getBounds2D(); + // System.out.println("GB["+i+"]: " + glyphBounds); + if (glyphBounds == null) continue; + if (b == null) b=glyphBounds; + else b = glyphBounds.createUnion(b); + } + + bounds2D = b; + return bounds2D; + } + + /** * Returns the logical bounds of this GlyphVector. + * This is a bound useful for hit detection and highlighting. */ public Rectangle2D getLogicalBounds() { if (logicalBounds == null) { @@ -608,11 +634,11 @@ } /** - * Returns the visual bounds of this GlyphVector The visual bounds is the - * tightest rectangle enclosing all non-background pixels in the rendered - * representation of this GlyphVector. + * Returns the geometric bounds of this GlyphVector. The geometric + * bounds is the tightest rectangle enclosing the geometry of the + * glyph vector (not including stroke). */ - public Rectangle2D getVisualBounds() { + public Rectangle2D getGeometricBounds() { return getOutline().getBounds2D(); } @@ -630,6 +656,7 @@ currentX += glyphs[i].getHorizAdvX(); logicalBounds = null; outline = null; + bounds2D = null; } endPos = new Point2D.Float(currentX, currentY); } @@ -651,6 +678,7 @@ glyphs[glyphIndex].setPosition(newPos); glyphLogicalBounds[glyphIndex] = null; outline = null; + bounds2D = null; logicalBounds = null; } @@ -665,6 +693,7 @@ glyphs[glyphIndex].setTransform(newTX); glyphLogicalBounds[glyphIndex] = null; outline = null; + bounds2D = null; logicalBounds = null; } @@ -677,6 +706,7 @@ glyphVisible[glyphIndex] = visible; outline = null; + bounds2D = null; logicalBounds = null; glyphLogicalBounds[glyphIndex] = null; } 1.13 +5 -85 xml-batik/sources/org/apache/batik/gvt/renderer/BasicTextPainter.java Index: BasicTextPainter.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/renderer/BasicTextPainter.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- BasicTextPainter.java 3 Apr 2002 04:58:21 -0000 1.12 +++ BasicTextPainter.java 12 Aug 2002 20:34:35 -0000 1.13 @@ -85,100 +85,20 @@ } } - /** - * Gets a Rectangle2D in userspace coords which encloses the - * textnode glyphs composed from an AttributedCharacterIterator. - * - * @param node the TextNode to measure */ - public Rectangle2D getBounds(TextNode node) { - return getBounds(node, false, false); - } - - /** - * Gets a Rectangle2D in userspace coords which encloses the - * textnode glyphs composed from an AttributedCharacterIterator, - * inclusive of glyph decoration (underline, overline, - * strikethrough). - * - * @param node the TextNode to measure */ - public Rectangle2D getDecoratedBounds(TextNode node) { - return getBounds(node, true, false); - } - - /** - * Gets a Rectangle2D in userspace coords which encloses the textnode glyphs - * (as-painted, inclusive of decoration and stroke, but exclusive of - * filters, etc.) composed from an AttributedCharacterIterator. - * - * @param node the TextNode to measure - */ - public Rectangle2D getPaintedBounds(TextNode node) { - return getBounds(node, true, true); - } /** - * Gets a Shape in userspace coords which defines the textnode glyph - * outlines. - * + * Get a Rectangle2D in userspace coords which encloses the textnode + * glyphs just including the geometry info. * @param node the TextNode to measure */ - public Shape getShape(TextNode node) { - return getOutline(node, false); - } - - /** - * Gets a Shape in userspace coords which defines the decorated textnode - * glyph outlines. - * - * @param node the TextNode to measure - */ - public Shape getDecoratedShape(TextNode node) { - return getOutline(node, true); + public Rectangle2D getGeometryBounds(TextNode node) { + return getOutline(node).getBounds2D(); } - // ------------------------------------------------------------------------ - // Abstract methods - // ------------------------------------------------------------------------ - - /** - * Gets a Rectangle2D in userspace coords which encloses the textnode - * glyphs composed from an AttributedCharacterIterator. - * - * @param node the TextNode to measure - * @param includeDecoration whether to include text decoration in bounds - * computation. - * @param includeStrokeWidth whether to include the effect of stroke width - * in bounds computation. - */ - protected abstract Rectangle2D getBounds(TextNode node, - boolean includeDecoration, - boolean includeStrokeWidth); - - /** - * Gets a Shape in userspace coords which defines the textnode glyph - * outlines. - * - * @param node the TextNode to measure - * @param includeDecoration whether to include text decoration outlines - */ - protected abstract Shape getOutline(TextNode node, - boolean includeDecoration); - - /** - * Gets a Shape in userspace coords which defines the stroked textnode glyph - * outlines. - * - * @param node the TextNode to measure - * @param includeDecoration whether to include text decoration outlines - */ - protected abstract Shape getStrokeOutline(TextNode node, - boolean includeDecoration); - /** * Returns the mark for the specified parameters. */ protected abstract Mark hitTest(double x, double y, TextNode node); - // ------------------------------------------------------------------------ // Inner class - implementation of the Mark interface 1.37 +70 -124 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.36 retrieving revision 1.37 diff -u -r1.36 -r1.37 --- StrokingTextPainter.java 3 May 2002 13:29:24 -0000 1.36 +++ StrokingTextPainter.java 12 Aug 2002 20:34:35 -0000 1.37 @@ -684,6 +684,9 @@ Point2D visualAdvance; if (!doAdjust) { + // System.out.println("Adv: " + chunk.advance); + // System.out.println("LastBounds: " + lastBounds); + // System.out.println("LastMetrics.hadv: " + lastMetrics.getHorizontalAdvance()); visualAdvance = new Point2D.Float ((float)(chunk.advance.getX() + lastBounds.getWidth() - lastMetrics.getHorizontalAdvance()), @@ -954,35 +957,11 @@ } } - - /** - * Get a Rectangle2D in userspace coords which encloses the textnode - * glyphs composed from an AttributedCharacterIterator. - */ - protected Rectangle2D getBounds(TextNode node, - boolean includeDecoration, - boolean includeStrokeWidth) { - - Rectangle2D bounds = getOutline(node, includeDecoration).getBounds2D(); - - if (includeStrokeWidth) { - Shape strokeOutline = getStrokeOutline(node, includeDecoration); - - if (strokeOutline != null) { - bounds = bounds.createUnion(strokeOutline.getBounds2D()); - } - } - - return bounds; - } - /** * Get a Shape in userspace coords which defines the textnode glyph outlines. * @param node the TextNode to measure - * @param includeDecoration whether to include text decoration - * outlines. */ - protected Shape getOutline(TextNode node, boolean includeDecoration) { + public Shape getOutline(TextNode node) { GeneralPath outline = null; AttributedCharacterIterator aci = node.getAttributedCharacterIterator(); @@ -1008,61 +987,55 @@ } // append any decoration outlines - if (includeDecoration) { + Shape underline = getDecorationOutline + (textRuns, TextSpanLayout.DECORATION_UNDERLINE); - Shape underline = getDecorationOutline - (textRuns, TextSpanLayout.DECORATION_UNDERLINE); - - Shape strikeThrough = getDecorationOutline - (textRuns, TextSpanLayout.DECORATION_STRIKETHROUGH); - - Shape overline = getDecorationOutline - (textRuns, TextSpanLayout.DECORATION_OVERLINE); - - if (underline != null) { - if (outline == null) { - outline = new GeneralPath(underline); - } else { - outline.setWindingRule(GeneralPath.WIND_NON_ZERO); - outline.append(underline, false); - } + Shape strikeThrough = getDecorationOutline + (textRuns, TextSpanLayout.DECORATION_STRIKETHROUGH); + + Shape overline = getDecorationOutline + (textRuns, TextSpanLayout.DECORATION_OVERLINE); + + if (underline != null) { + if (outline == null) { + outline = new GeneralPath(underline); + } else { + outline.setWindingRule(GeneralPath.WIND_NON_ZERO); + outline.append(underline, false); } - if (strikeThrough != null) { - if (outline == null) { - outline = new GeneralPath(strikeThrough); - } else { - outline.setWindingRule(GeneralPath.WIND_NON_ZERO); - outline.append(strikeThrough, false); - } + } + if (strikeThrough != null) { + if (outline == null) { + outline = new GeneralPath(strikeThrough); + } else { + outline.setWindingRule(GeneralPath.WIND_NON_ZERO); + outline.append(strikeThrough, false); } - if (overline != null) { - if (outline == null) { - outline = new GeneralPath(overline); - } else { - outline.setWindingRule(GeneralPath.WIND_NON_ZERO); - outline.append(overline, false); - } + } + if (overline != null) { + if (outline == null) { + outline = new GeneralPath(overline); + } else { + outline.setWindingRule(GeneralPath.WIND_NON_ZERO); + outline.append(overline, false); } } return outline; } - /** - * Get a Shape in userspace coords which defines the - * stroked textnode glyph outlines. - * @param node the TextNode to measure - * @param includeDecoration whether to include text decoration - * outlines. - */ - protected Shape getStrokeOutline(TextNode node, boolean includeDecoration) { - GeneralPath outline = null; + /** + * Get a Rectangle2D in userspace coords which encloses the textnode + * glyphs including stroke etc. + */ + public Rectangle2D getBounds2D(TextNode node) { AttributedCharacterIterator aci = node.getAttributedCharacterIterator(); // get the list of text runs List textRuns = getTextRuns(node, aci); + Rectangle2D bounds = null; // for each text run, get its stroke outline and append it to the overall outline for (int i = 0; i < textRuns.size(); ++i) { Shape textRunStrokeOutline = null; @@ -1073,69 +1046,42 @@ TextSpanLayout textRunLayout = textRun.getLayout(); - Stroke stroke = (Stroke) textRunACI.getAttribute - (GVTAttributedCharacterIterator.TextAttribute.STROKE); - - Paint strokePaint = (Paint) textRunACI.getAttribute - (GVTAttributedCharacterIterator.TextAttribute.STROKE_PAINT); - - if (stroke != null && strokePaint != null) { - // this textRun is stroked - Shape textRunOutline = - textRunLayout.getOutline(); - textRunStrokeOutline = - stroke.createStrokedShape(textRunOutline); - } - - if (textRunStrokeOutline != null) { - if (outline == null) { - outline = new GeneralPath(textRunStrokeOutline); - } else { - outline.setWindingRule(GeneralPath.WIND_NON_ZERO); - outline.append(textRunStrokeOutline, false); - } - } + if (bounds == null) + bounds = textRunLayout.getBounds2D(); + else + bounds = bounds.createUnion(textRunLayout.getBounds2D()); } // append any stroked decoration outlines - if (includeDecoration) { - - Shape underline = getDecorationStrokeOutline - (textRuns, TextSpanLayout.DECORATION_UNDERLINE); + Shape underline = getDecorationStrokeOutline + (textRuns, TextSpanLayout.DECORATION_UNDERLINE); - Shape strikeThrough = getDecorationStrokeOutline - (textRuns, TextSpanLayout.DECORATION_STRIKETHROUGH); - - Shape overline = getDecorationStrokeOutline - (textRuns, TextSpanLayout.DECORATION_OVERLINE); - - if (underline != null) { - if (outline == null) { - outline = new GeneralPath(underline); - } else { - outline.setWindingRule(GeneralPath.WIND_NON_ZERO); - outline.append(underline, false); - } - } - if (strikeThrough != null) { - if (outline == null) { - outline = new GeneralPath(strikeThrough); - } else { - outline.setWindingRule(GeneralPath.WIND_NON_ZERO); - outline.append(strikeThrough, false); - } - } - if (overline != null) { - if (outline == null) { - outline = new GeneralPath(overline); - } else { - outline.setWindingRule(GeneralPath.WIND_NON_ZERO); - outline.append(overline, false); - } - } + if (underline != null) { + if (bounds == null) + bounds = underline.getBounds2D(); + else + bounds = bounds.createUnion(underline.getBounds2D()); + } + + Shape strikeThrough = getDecorationStrokeOutline + (textRuns, TextSpanLayout.DECORATION_STRIKETHROUGH); + if (strikeThrough != null) { + if (bounds == null) + bounds = strikeThrough.getBounds2D(); + else + bounds = bounds.createUnion(strikeThrough.getBounds2D()); + } + + Shape overline = getDecorationStrokeOutline + (textRuns, TextSpanLayout.DECORATION_OVERLINE); + if (overline != null) { + if (bounds == null) + bounds = overline.getBounds2D(); + else + bounds = bounds.createUnion(overline.getBounds2D()); } - return outline; + return bounds; } @@ -1388,7 +1334,7 @@ TextRun textRun = (TextRun)textRuns.get(i); TextSpanLayout layout = textRun.getLayout(); TextHit textHit = layout.hitTestChar((float) x, (float) y); - if (textHit != null && layout.getBounds().contains(x,y)) { + if (textHit != null && layout.getBounds2D().contains(x,y)) { return new BasicTextPainter.BasicMark(node, textHit); } } 1.44 +10 -8 xml-batik/sources/org/apache/batik/gvt/text/GlyphLayout.java Index: GlyphLayout.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/text/GlyphLayout.java,v retrieving revision 1.43 retrieving revision 1.44 diff -u -r1.43 -r1.44 --- GlyphLayout.java 20 Jun 2002 21:35:09 -0000 1.43 +++ GlyphLayout.java 12 Aug 2002 20:34:35 -0000 1.44 @@ -399,19 +399,21 @@ /** * Returns the rectangular bounds of the completed glyph layout. */ - public Rectangle2D getBounds() { + public Rectangle2D getBounds2D() { syncLayout(); - - return gv.getVisualBounds(); + return gv.getBounds2D(aci); } /** * Returns the rectangular bounds of the completed glyph layout, * inclusive of "decoration" (underline, overline, etc.) */ - public Rectangle2D getDecoratedBounds() { - return getBounds().createUnion - (getDecorationOutline(DECORATION_ALL).getBounds2D()); + public Rectangle2D getGeometricBounds() { + syncLayout(); + Rectangle2D gvB, decB; + gvB = gv.getGeometricBounds(); + decB = getDecorationOutline(DECORATION_ALL).getBounds2D(); + return gvB.createUnion(decB); } /** @@ -1454,7 +1456,7 @@ if ((xScale == 1) && (yScale==1)) return; - Rectangle2D bounds = gv.getVisualBounds(); + Rectangle2D bounds = gv.getGeometricBounds(); AffineTransform scaleAT = AffineTransform.getScaleInstance(xScale, yScale); 1.13 +13 -11 xml-batik/sources/org/apache/batik/gvt/text/TextSpanLayout.java Index: TextSpanLayout.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/text/TextSpanLayout.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- TextSpanLayout.java 24 Jan 2002 21:35:32 -0000 1.12 +++ TextSpanLayout.java 12 Aug 2002 20:34:35 -0000 1.13 @@ -46,12 +46,6 @@ public void draw(Graphics2D g2d); /** - * Returns the outline of the completed glyph layout, transformed - * by an AffineTransform. - */ - public Shape getOutline(); - - /** * Returns the outline of the specified decorations on the glyphs, * transformed by an AffineTransform. * @param decorationType an integer indicating the type(s) of decorations @@ -63,14 +57,22 @@ /** * Returns the rectangular bounds of the completed glyph layout. + * This includes stroking information, this does not include + * deocrations. */ - public Rectangle2D getBounds(); + public Rectangle2D getBounds2D(); /** - * Returns the rectangular bounds of the completed glyph layout, - * inclusive of "decoration" (underline, overline, etc.) + * Returns the bounds of the geometry (this is always the bounds + * of the outline). */ - public Rectangle2D getDecoratedBounds(); + public Rectangle2D getGeometricBounds(); + + /** + * Returns the outline of the completed glyph layout, transformed + * by an AffineTransform. + */ + public Shape getOutline(); /** * Returns the current text position at the completion
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]