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 be...@apache.org on 2001/08/02 09:50:11 UTC

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

bella       01/08/02 00:50:11

  Modified:    sources/org/apache/batik/gvt/font AltGlyphHandler.java
                        Glyph.java
               sources/org/apache/batik/gvt/text GlyphLayout.java
  Log:
  gradient fill of SVG fonts now works properly
  
  Revision  Changes    Path
  1.5       +4 -2      xml-batik/sources/org/apache/batik/gvt/font/AltGlyphHandler.java
  
  Index: AltGlyphHandler.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/font/AltGlyphHandler.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- AltGlyphHandler.java	2001/07/05 06:21:04	1.4
  +++ AltGlyphHandler.java	2001/08/02 07:50:11	1.5
  @@ -9,12 +9,13 @@
   package org.apache.batik.gvt.font;
   
   import java.awt.font.FontRenderContext;
  +import java.text.AttributedCharacterIterator;
   
   /**
    * An interface for handling altGlyphs.
    *
    * @author <a href="mailto:bella.robinson@cmis.csiro.au">Bella Robinson</a>
  - * @version $Id: AltGlyphHandler.java,v 1.4 2001/07/05 06:21:04 bella Exp $
  + * @version $Id: AltGlyphHandler.java,v 1.5 2001/08/02 07:50:11 bella Exp $
    */
   public interface AltGlyphHandler {
   
  @@ -26,6 +27,7 @@
        * @return The GVTGlyphVector containing the alternate glyphs, or null if
        * the alternate glyphs could not be found.
        */
  -    GVTGlyphVector createGlyphVector(FontRenderContext frc, float fontSize);
  +    GVTGlyphVector createGlyphVector(FontRenderContext frc, float fontSize,
  +                                     AttributedCharacterIterator aci);
   
   }
  
  
  
  1.6       +80 -42    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.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Glyph.java	2001/07/05 06:23:32	1.5
  +++ Glyph.java	2001/08/02 07:50:11	1.6
  @@ -14,9 +14,13 @@
   import java.awt.Graphics2D;
   import java.awt.geom.Point2D;
   import java.awt.geom.AffineTransform;
  +import java.awt.geom.GeneralPath;
  +import java.awt.geom.Rectangle2D;
   import java.awt.Shape;
   import java.awt.font.GlyphMetrics;
   import java.util.Vector;
  +import java.awt.Paint;
  +import java.awt.Stroke;
   
   
   /**
  @@ -24,11 +28,10 @@
    * attributes.
    *
    * @author <a href="mailto:bella.robinson@cmis.csiro.au">Bella Robinson</a>
  - * @version $Id: Glyph.java,v 1.5 2001/07/05 06:23:32 bella Exp $
  + * @version $Id: Glyph.java,v 1.6 2001/08/02 07:50:11 bella Exp $
    */
   public class Glyph {
   
  -    private GraphicsNode glyphNode;
       private String unicode;
       private Vector names;
       private String orientation;
  @@ -46,33 +49,23 @@
   
       private Shape outline; // cache the glyph outline
   
  +    private Paint fillPaint;
  +    private Paint strokePaint;
  +    private Stroke stroke;
  +    private Shape dShape;
  +    private GraphicsNode glyphChildrenNode;
   
  +
       /**
        * Constructs a Glyph with the specified parameters.
  -     *
  -     * @param glyphNode The graphics node for this glyph.
  -     * @param unicode The unicode char or chars that this glpyh represents.
  -     * @param names The list of names for this glyph.
  -     * @param orientation Indicates what inline-progression-direction this glyph
  -     * can be used in. Should be either "h" for horizontal only, "v" for vertical
  -     * only, or empty which indicates that the glpyh can be use in both.
  -     * @param arabicForm
  -     * @param lang
  -     * @param horizOrigin
  -     * @param vertOrigin
  -     * @param horizAdvX
  -     * @param vertAdvY
  -     * @param glyphCode
  -     * @param kernScale
        */
  -    public Glyph(GraphicsNode glyphNode, String unicode, Vector names,
  +    public Glyph(String unicode, Vector names,
                    String orientation, String arabicForm, String lang,
                    Point2D horizOrigin, Point2D vertOrigin, float horizAdvX,
  -                 float vertAdvY, int glyphCode, float kernScale) {
  +                 float vertAdvY, int glyphCode, float kernScale,
  +                 Paint fillPaint, Paint strokePaint, Stroke stroke,
  +                 Shape dShape, GraphicsNode glyphChildrenNode) {
   
  -        if (glyphNode == null) {
  -            throw new IllegalArgumentException();
  -        }
           if (unicode == null) {
               throw new IllegalArgumentException();
           }
  @@ -83,7 +76,6 @@
               throw new IllegalArgumentException();
           }
   
  -        this.glyphNode = glyphNode;
           this.unicode = unicode;
           this.names = names;
           this.orientation = orientation;
  @@ -106,15 +98,13 @@
           this.glyphCode = glyphCode;
           this.position = new Point2D.Float(0,0);
           this.outline = null;
  -    }
   
  -    /**
  -     * Returns the graphics node associated with this glyph.
  -     *
  -     * @return The glyph graphics node.
  -     */
  -    public GraphicsNode getGlyphNode() {
  -        return glyphNode;
  +
  +        this.fillPaint = fillPaint;
  +        this.strokePaint = strokePaint;
  +        this.stroke = stroke;
  +        this.dShape = dShape;
  +        this.glyphChildrenNode = glyphChildrenNode;
       }
   
       /**
  @@ -258,8 +248,7 @@
       public GVTGlyphMetrics getGlyphMetrics() {
           if (metrics == null) {
               metrics = new GVTGlyphMetrics(getHorizAdvX(), getVertAdvY(),
  -                                          glyphNode.getOutline(null).getBounds2D(),
  -                                          GlyphMetrics.COMPONENT);
  +                                          getBounds(), GlyphMetrics.COMPONENT);
           }
           return metrics;
       }
  @@ -274,12 +263,28 @@
       public GVTGlyphMetrics getGlyphMetrics(float hkern, float vkern) {
           return new GVTGlyphMetrics(getHorizAdvX() - (hkern * kernScale),
                                      getVertAdvY() - (vkern * kernScale),
  -                                   glyphNode.getOutline(null).getBounds2D(),
  -                                   GlyphMetrics.COMPONENT);
  +                                   getBounds(), GlyphMetrics.COMPONENT);
  +
  +    }
   
  +    public Rectangle2D getBounds() {
  +
  +        if (dShape != null && glyphChildrenNode == null) {
  +            return dShape.getBounds2D();
  +        }
  +        if (glyphChildrenNode != null && dShape == null) {
  +            return glyphChildrenNode.getOutline(null).getBounds2D();
  +        }
  +        if (dShape != null && glyphChildrenNode != null) {
  +            Rectangle2D dBounds = dShape.getBounds2D();
  +            Rectangle2D childrenBounds = glyphChildrenNode.getOutline(null).getBounds2D();
  +            return dBounds.createUnion(childrenBounds);
  +        }
  +        return new Rectangle2D.Double(0,0,0,0);
       }
   
   
  +
       /**
        * Returns the outline of this glyph. This will be positioned correctly and
        * any glyph transforms will have been applied.
  @@ -291,11 +296,22 @@
               AffineTransform tr = AffineTransform.getTranslateInstance(position.getX(), position.getY());
               if (transform != null) {
                   tr.concatenate(transform);
  +            }
  +            Shape glyphChildrenOutline = null;
  +            if (glyphChildrenNode != null) {
  +                glyphChildrenOutline = glyphChildrenNode.getOutline(null);
               }
  -            Shape glyphOutline = glyphNode.getOutline(null);
  -            AffineTransform glyphNodeTransform = glyphNode.getTransform();
  -            if (glyphNodeTransform != null) {
  -                glyphOutline = glyphNodeTransform.createTransformedShape(glyphOutline);
  +            GeneralPath glyphOutline = null;
  +            if (dShape != null && glyphChildrenOutline != null) {
  +                glyphOutline = new GeneralPath(dShape);
  +                glyphOutline.append(glyphChildrenOutline, false);
  +            } else if (dShape != null && glyphChildrenOutline == null) {
  +                glyphOutline = new GeneralPath(dShape);
  +            } else if (dShape == null && glyphChildrenOutline != null) {
  +                glyphOutline = new GeneralPath(glyphChildrenOutline);
  +            } else {
  +                // must be a whitespace glyph, return an empty shape
  +                glyphOutline = new GeneralPath();
               }
               outline = tr.createTransformedShape(glyphOutline);
           }
  @@ -309,12 +325,34 @@
        * @param context The current rendering context.
        */
       public void draw(Graphics2D graphics2D, GraphicsNodeRenderContext context) {
  -        AffineTransform tr = AffineTransform.getTranslateInstance(position.getX(), position.getY());
  +        AffineTransform tr
  +            = AffineTransform.getTranslateInstance(position.getX(),
  +                                                   position.getY());
           if (transform != null) {
               tr.concatenate(transform);
  +        }
  +
  +        // paint the dShape first
  +        if (dShape != null) {
  +            Shape tShape = tr.createTransformedShape(dShape);
  +            if (fillPaint != null) {
  +                graphics2D.setPaint(fillPaint);
  +                graphics2D.fill(tShape);
  +            }
  +
  +            // check if we need to draw the outline of this glyph
  +            if (stroke != null && strokePaint != null) {
  +                graphics2D.setStroke(stroke);
  +                graphics2D.setPaint(strokePaint);
  +                graphics2D.draw(tShape);
  +            }
  +        }
  +
  +        // paint the glyph children nodes
  +        if (glyphChildrenNode != null) {
  +            glyphChildrenNode.setTransform(tr);
  +            glyphChildrenNode.paint(graphics2D, context);
           }
  -        glyphNode.setTransform(tr);
  -        glyphNode.paint(graphics2D, context);
       }
   }
   
  
  
  
  1.19      +46 -11    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.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- GlyphLayout.java	2001/07/31 06:18:40	1.18
  +++ GlyphLayout.java	2001/08/02 07:50:11	1.19
  @@ -39,7 +39,7 @@
    * @see org.apache.batik.gvt.TextSpanLayout.
    *
    * @author <a href="bill.haneman@ireland.sun.com>Bill Haneman</a>
  - * @version $Id: GlyphLayout.java,v 1.18 2001/07/31 06:18:40 bella Exp $
  + * @version $Id: GlyphLayout.java,v 1.19 2001/08/02 07:50:11 bella Exp $
    */
   public class GlyphLayout implements TextSpanLayout {
   
  @@ -82,7 +82,7 @@
               GVTAttributedCharacterIterator.TextAttribute.ALT_GLYPH_HANDLER);
           if (altGlyphHandler != null) {
               // this must be an altGlyph text element, try and create the alternate glyphs
  -            this.gv = altGlyphHandler.createGlyphVector(frc, this.font.getSize());
  +            this.gv = altGlyphHandler.createGlyphVector(frc, this.font.getSize(), this.aci);
           }
           if (this.gv == null) {
               // either not an altGlyph or the altGlyphHandler failed to create a glyph vector
  @@ -831,6 +831,11 @@
           Point2D prevPos = gv.getGlyphPosition(0);
           float x = (float) prevPos.getX();
           float y = (float) prevPos.getY();
  +
  +        Point2D lastCharAdvance
  +            = new Point2D.Double(advance.getX() - (gv.getGlyphPosition(numGlyphs-1).getX() - x),
  +                                 advance.getY() - (gv.getGlyphPosition(numGlyphs-1).getY() - y));
  +
           try {
               // do letter spacing first
               if ((numGlyphs > 1) && (doLetterSpacing || !autoKern)) {
  @@ -838,7 +843,6 @@
                       Point2D gpos = gv.getGlyphPosition(i);
                       dx = (float)gpos.getX()-(float)prevPos.getX();
                       dy = (float)gpos.getY()-(float)prevPos.getY();
  -                    GVTGlyphMetrics gm = gv.getGlyphMetrics(i);
                       if (autoKern) {
                           if (isVertical()) dy += letterSpacingVal;
                           else dx += letterSpacingVal;
  @@ -860,6 +864,7 @@
                       newPositions[i] = new Point2D.Float(x, y);
                       prevPos = gpos;
                   }
  +
                   for (int i=1; i<numGlyphs; ++i) { // assign the new positions
                       if (newPositions[i] != null) {
                           gv.setGlyphPosition(i, newPositions[i]);
  @@ -867,6 +872,28 @@
                   }
               }
   
  +             // adjust the advance of the last character
  +            if (autoKern) {
  +                if (isVertical()) {
  +                    lastCharAdvance.setLocation(lastCharAdvance.getX(),
  +                            lastCharAdvance.getY() + letterSpacingVal);
  +                } else {
  +                    lastCharAdvance.setLocation(lastCharAdvance.getX()
  +                            + letterSpacingVal, lastCharAdvance.getY());
  +                }
  +            } else {
  +                if (isVertical()) {
  +                    lastCharAdvance.setLocation(lastCharAdvance.getX(),
  +                        gv.getGlyphMetrics(numGlyphs-2).getBounds2D().getHeight()+
  +                                kernVal + letterSpacingVal);
  +                } else {
  +                    lastCharAdvance.setLocation(
  +                        gv.getGlyphMetrics(numGlyphs-2).getBounds2D().getWidth()+
  +                                kernVal + letterSpacingVal, lastCharAdvance.getY());
  +                }
  +            }
  +
  +
               // now do word spacing
               dx = 0f;
               dy = 0f;
  @@ -875,7 +902,7 @@
               y = (float) prevPos.getY();
   
               if ((numGlyphs > 1) && (doWordSpacing)) {
  -                for (int i=1; i<numGlyphs; ++i) {
  +                for (int i = 1; i < numGlyphs; i++) {
                       Point2D gpos = gv.getGlyphPosition(i);
                       dx = (float)gpos.getX()-(float)prevPos.getX();
                       dy = (float)gpos.getY()-(float)prevPos.getY();
  @@ -886,15 +913,14 @@
                       GVTGlyphMetrics gm = gv.getGlyphMetrics(i);
   
                       // BUG: gm.isWhitespace() fails for latin SPACE glyph!
  -                    while ((gm.getBounds2D().getWidth()<0.01d) ||
  -                                                       gm.isWhitespace()) {
  -                        ++i;
  -                        ++endWS;
  +                    while ((gm.getBounds2D().getWidth()<0.01d) || gm.isWhitespace()) {
                           if (!inWS) inWS = true;
  -                        if (i>=numGlyphs) {
  -                            inWS = false;
  +                        if (i == numGlyphs-1) {
  +                            // white space at the end
                               break;
                           }
  +                        ++i;
  +                        ++endWS;
                           gpos = gv.getGlyphPosition(i);
                           gm = gv.getGlyphMetrics(i);
                       }
  @@ -924,16 +950,25 @@
                       }
                       prevPos = gpos;
                   }
  +
                   for (int i=1; i<numGlyphs; ++i) { // assign the new positions
                       if (newPositions[i] != null) {
                           gv.setGlyphPosition(i, newPositions[i]);
                       }
                   }
               }
  +
           } catch (Exception e) {
               e.printStackTrace();
           }
  -        Point2D newAdvance = advance;
  +
  +        // calculate the new advance
  +        double advX = gv.getGlyphPosition(numGlyphs-1).getX()
  +                     - gv.getGlyphPosition(0).getX();
  +        double advY = gv.getGlyphPosition(numGlyphs-1).getY()
  +                     - gv.getGlyphPosition(0).getY();
  +        Point2D newAdvance = new Point2D.Double(advX + lastCharAdvance.getX(),
  +                                                advY + lastCharAdvance.getY());
           return newAdvance;
       }
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: batik-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-dev-help@xml.apache.org