You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-dev@xmlgraphics.apache.org by de...@apache.org on 2002/08/12 22:34:36 UTC

cvs commit: xml-batik/sources/org/apache/batik/gvt/text GlyphLayout.java TextSpanLayout.java

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: batik-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-dev-help@xml.apache.org