bella       01/07/26 19:23:38

  Modified:    sources/org/apache/batik/gvt/font AWTGVTGlyphVector.java
                        GVTGlyphMetrics.java GVTGlyphVector.java
                        SVGGVTGlyphVector.java
               sources/org/apache/batik/gvt/text GlyphLayout.java
  Log:
  vertical text on a path now implemented
  
  Revision  Changes    Path
  1.7       +1 -16     
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.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- AWTGVTGlyphVector.java    2001/07/05 06:23:31     1.6
  +++ AWTGVTGlyphVector.java    2001/07/27 02:23:37     1.7
  @@ -31,7 +31,7 @@
    * This is a wrapper class for a java.awt.font.GlyphVector instance.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Bella Robinson</a>
  - * @version $Id: AWTGVTGlyphVector.java,v 1.6 2001/07/05 06:23:31 bella Exp $
  + * @version $Id: AWTGVTGlyphVector.java,v 1.7 2001/07/27 02:23:37 bella Exp $
    */
   public final class AWTGVTGlyphVector implements GVTGlyphVector {
   
  @@ -40,7 +40,6 @@
       private CharacterIterator ci;
   
       private Point2D[] glyphPositions;
  -    private Point2D[] defaultGlyphPositions;
   
       // need to keep track of the glyphTransforms since GlyphVector doesn't seem to
       private AffineTransform[] glyphTransforms;
  @@ -80,7 +79,6 @@
           logicalBounds = null;
           glyphTransforms = new AffineTransform[numGlyphs];
           glyphPositions = new Point2D.Float[numGlyphs];
  -        defaultGlyphPositions = new Point2D.Float[numGlyphs];
           glyphOutlines = new Shape[numGlyphs];
           glyphVisualBounds = new Shape[numGlyphs];
           glyphLogicalBounds = new Shape[numGlyphs];
  @@ -337,18 +335,6 @@
       }
   
       /**
  -     * Returns the default position of the glyph. This will be the position that
  -     * is set when the performDefaultLayout method is run.
  -     */
  -    public Point2D getDefaultGlyphPosition(int glyphIndex) {
  -        if (defaultGlyphPositions[glyphIndex] == null) {
  -            performDefaultLayout();
  -        }
  -        return defaultGlyphPositions[glyphIndex];
  -    }
  -
  -
  -    /**
        * Returns an array of glyph positions for the specified glyphs
        */
       public float[] getGlyphPositions(int beginGlyphIndex, int numEntries,
  @@ -464,7 +450,6 @@
               Point2D glyphPos = awtGlyphVector.getGlyphPosition(i);
               glyphPositions[i] = new 
Point2D.Float((float)((glyphPos.getX()-shiftLeft) * scaleFactor),
                                                     (float)(glyphPos.getY() * 
scaleFactor));
  -            defaultGlyphPositions[i] = glyphPositions[i];
               glyphTransforms[i] = null;
               glyphVisualBounds[i] = null;
               glyphLogicalBounds[i] = null;
  
  
  
  1.2       +49 -3     xml-batik/sources/org/apache/batik/gvt/font/GVTGlyphMetrics.java
  
  Index: GVTGlyphMetrics.java
  ===================================================================
  RCS file: 
/home/cvs/xml-batik/sources/org/apache/batik/gvt/font/GVTGlyphMetrics.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- GVTGlyphMetrics.java      2001/06/12 23:49:41     1.1
  +++ GVTGlyphMetrics.java      2001/07/27 02:23:37     1.2
  @@ -16,66 +16,112 @@
    * with the addition of horizontal and vertical advance values.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Bella Robinson</a>
  - * @version $Id: GVTGlyphMetrics.java,v 1.1 2001/06/12 23:49:41 bella Exp $
  + * @version $Id: GVTGlyphMetrics.java,v 1.2 2001/07/27 02:23:37 bella Exp $
    */
   public class GVTGlyphMetrics {
   
  -
       private GlyphMetrics gm;
       private float verticalAdvance;
   
  +    /**
  +     * Constructs a new GVTGlyphMetrics object based upon the specified
  +     * GlyphMetrics object and an additional vertical advance value.
  +     *
  +     * @param gm The glyph metrics.
  +     * @param verticalAdvance The vertical advance of the glyph.
  +     */
       public GVTGlyphMetrics(GlyphMetrics gm, float verticalAdvance) {
           this.gm = gm;
           this.verticalAdvance = verticalAdvance;
       }
  -
   
  +    /**
  +     * Constructs a new GVTGlyphMetrics object using the specified parameters.
  +     *
  +     * @param horizontalAdvance The horizontal advance of the glyph.
  +     * @param verticalAdvance The vertical advance of the glyph.
  +     * @param bounds The black box bounds of the glyph.
  +     * @param glyphType The type of the glyph.
  +     */
       public GVTGlyphMetrics(float horizontalAdvance, float verticalAdvance,
                              Rectangle2D bounds, byte glyphType) {
           this.gm = new GlyphMetrics(horizontalAdvance, bounds, glyphType);
           this.verticalAdvance = verticalAdvance;
       }
   
  +    /**
  +     * Returns the horizontal advance of the glyph.
  +     */
       public float getHorizontalAdvance() {
           return gm.getAdvance();
       }
   
  +    /**
  +     * Returns the vertical advance of the glyph.
  +     */
       public float getVerticalAdvance() {
           return verticalAdvance;
       }
   
  +    /**
  +     * Returns the black box bounds of the glyph.
  +     */
       public Rectangle2D getBounds2D() {
           return gm.getBounds2D();
       }
   
  +    /**
  +     * Returns the left (top) side bearing of the glyph.
  +     */
       public float getLSB() {
           return gm.getLSB();
       }
   
  +    /**
  +     * Returns the right (bottom) side bearing of the glyph.
  +     */
       public float getRSB() {
           return gm.getRSB();
       }
   
  +    /**
  +     * Returns the raw glyph type code.
  +     */
       public int getType() {
           return gm.getType();
       }
   
  +    /**
  +     * Returns true if this is a combining glyph.
  +     */
       public boolean isCombining() {
           return gm.isCombining();
       }
   
  +    /**
  +     * Returns true if this is a component glyph.
  +     */
       public boolean isComponent() {
           return gm.isComponent();
       }
   
  +    /**
  +     * Returns true if this is a ligature glyph.
  +     */
       public boolean isLigature() {
           return gm.isLigature();
       }
   
  +    /**
  +     * Returns true if this is a standard glyph.
  +     */
       public boolean isStandard() {
           return gm.isStandard();
       }
   
  +    /**
  +     * Returns true if this is a whitespace glyph.
  +     */
       public boolean isWhitespace() {
           return gm.isWhitespace();
       }
  
  
  
  1.5       +1 -7      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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- GVTGlyphVector.java       2001/06/12 23:49:41     1.4
  +++ GVTGlyphVector.java       2001/07/27 02:23:37     1.5
  @@ -23,7 +23,7 @@
    * An interface for all GVT GlyphVector classes.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Bella Robinson</a>
  - * @version $Id: GVTGlyphVector.java,v 1.4 2001/06/12 23:49:41 bella Exp $
  + * @version $Id: GVTGlyphVector.java,v 1.5 2001/07/27 02:23:37 bella Exp $
    */
   public interface GVTGlyphVector {
   
  @@ -76,12 +76,6 @@
        * Returns the position of the specified glyph within this GlyphVector.
        */
       public Point2D getGlyphPosition(int glyphIndex);
  -
  -    /**
  -     * Returns the default position of the glyph. This will be the position that
  -     * is set when the performDefaultLayout method is run.
  -     */
  -    public Point2D getDefaultGlyphPosition(int glyphIndex);
   
       /**
        * Returns an array of glyph positions for the specified glyphs
  
  
  
  1.7       +1 -15     
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.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- SVGGVTGlyphVector.java    2001/07/05 06:23:32     1.6
  +++ SVGGVTGlyphVector.java    2001/07/27 02:23:37     1.7
  @@ -31,7 +31,7 @@
    * A GVTGlyphVector class for SVG fonts.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Bella Robinson</a>
  - * @version $Id: SVGGVTGlyphVector.java,v 1.6 2001/07/05 06:23:32 bella Exp $
  + * @version $Id: SVGGVTGlyphVector.java,v 1.7 2001/07/27 02:23:37 bella Exp $
    */
   public final class SVGGVTGlyphVector implements GVTGlyphVector {
   
  @@ -40,7 +40,6 @@
       private FontRenderContext frc;
       private GeneralPath outline;
       private Rectangle2D logicalBounds;
  -    private Point2D[] defaultGlyphPositions;
       private Shape[] glyphLogicalBounds;
       private boolean[] glyphVisible;
   
  @@ -58,7 +57,6 @@
           this.frc = frc;
           outline = null;
           logicalBounds = null;
  -        defaultGlyphPositions = new Point2D.Float[glyphs.length];
           glyphLogicalBounds = new Shape[glyphs.length];
           glyphVisible = new boolean[glyphs.length];
           for (int i = 0; i < glyphs.length; i++) {
  @@ -354,17 +352,6 @@
           return glyphs[glyphIndex].getPosition();
       }
   
  -    /**
  -     * Returns the default position of the glyph. This will be the position that
  -     * is set when the performDefaultLayout method is run.
  -     */
  -    public Point2D getDefaultGlyphPosition(int glyphIndex) {
  -        if (defaultGlyphPositions[glyphIndex] == null) {
  -            performDefaultLayout();
  -        }
  -        return defaultGlyphPositions[glyphIndex];
  -    }
  -
   
       /**
        * Returns an array of glyph positions for the specified glyphs
  @@ -494,7 +481,6 @@
           for (int i = 0; i < glyphs.length; i++) {
               glyphs[i].setPosition(new Point2D.Float(currentX, currentY));
               glyphs[i].setTransform(null);
  -            defaultGlyphPositions[i] = getGlyphPosition(i);
               glyphLogicalBounds[i] = null;
               currentX += glyphs[i].getHorizAdvX();
               logicalBounds = null;
  
  
  
  1.17      +176 -78   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.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- GlyphLayout.java  2001/07/05 06:31:46     1.16
  +++ GlyphLayout.java  2001/07/27 02:23:37     1.17
  @@ -39,7 +39,7 @@
    * @see org.apache.batik.gvt.TextSpanLayout.
    *
    * @author <a href="[EMAIL PROTECTED]>Bill Haneman</a>
  - * @version $Id: GlyphLayout.java,v 1.16 2001/07/05 06:31:46 bella Exp $
  + * @version $Id: GlyphLayout.java,v 1.17 2001/07/27 02:23:37 bella Exp $
    */
   public class GlyphLayout implements TextSpanLayout {
   
  @@ -93,7 +93,7 @@
           this.gv.performDefaultLayout();
           doExplicitGlyphLayout(false);
           adjustTextSpacing();
  -        doPathLayout();
  +        doPathLayout(false);
       }
   
       /**
  @@ -145,7 +145,7 @@
           this.gv.performDefaultLayout();
           doExplicitGlyphLayout(true);
           adjustTextSpacing();
  -        doPathLayout();
  +        doPathLayout(true);
       }
   
       /**
  @@ -467,8 +467,11 @@
       /**
        * If this layout is on a text path, positions the characters along the
        * path.
  +     *
  +     * @param offsetApplied Indicates whether or not the text position offset
  +     *        has already been applied.
        */
  -    protected void doPathLayout() {
  +    protected void doPathLayout(boolean offsetApplied) {
   
           aci.first();
           textPath =  (TextPath) aci.getAttribute(
  @@ -479,16 +482,28 @@
               return;
           }
   
  +        boolean horizontal = !isVertical();
  +
  +        boolean glyphOrientationAuto = isGlyphOrientationAuto();
  +        int glyphOrientationAngle = 0;
  +        if (!glyphOrientationAuto) {
  +            glyphOrientationAngle = getGlyphOrientationAngle();
  +        }
  +
           float pathLength = textPath.lengthOfPath();
           float startOffset = textPath.getStartOffset();
   
  -        // make sure all glyphs visible again, this maybe just a change in offset
  -        // so they may have been made invisible in a previous pathLayout call
  +        // make sure all glyphs visible again, this maybe just a change in
  +        // offset so they may have been made invisible in a previous
  +        // pathLayout call
           for (int i = 0; i < gv.getNumGlyphs(); i++) {
               gv.setGlyphVisible(i, true);
           }
  +
  +        // calculate the total length of the glyphs, this will become be
  +        // the length along the path that is used by the text
           float glyphsLength;
  -        if (!isVertical()) {
  +        if (horizontal) {
               glyphsLength = (float) gv.getLogicalBounds().getWidth();
           } else {
               glyphsLength = (float) gv.getLogicalBounds().getHeight();
  @@ -501,43 +516,79 @@
   
           // the current start point of the character on the path
           float currentPosition;
  -        if (!isVertical()) {
  +        if (horizontal) {
               currentPosition = (float)offset.getX() + startOffset;
           } else {
               currentPosition = (float)offset.getY() + startOffset;
           }
           int currentChar = aci.getBeginIndex();
   
  +        // calculate the offset of the first glyph
  +        // the offset will be 0 if the glyph is on the path (ie. not adjusted by
  +        // a dy or dx)
  +        Point2D firstGlyphPosition = gv.getGlyphPosition(0);
  +        float glyphOffset = 0;   // offset perpendicular to path
  +        if (offsetApplied) {
  +            if (horizontal) {
  +                glyphOffset = (float)firstGlyphPosition.getY();
  +            } else {
  +                glyphOffset = (float)firstGlyphPosition.getX();
  +            }
  +        }
  +
  +        char ch = aci.first();
  +        int lastGlyphDrawn = -1;
  +        float lastGlyphAdvance = 0;
  +
           // iterate through the GlyphVector placing each glyph
           for (int i = 0; i < gv.getNumGlyphs(); i++) {
   
               Point2D currentGlyphPosition = gv.getGlyphPosition(i);
  -            Point2D defaultGlyphPosition = gv.getDefaultGlyphPosition(i);
  -
  -            float offsetX = (float)(currentGlyphPosition.getX()
  -                            - (defaultGlyphPosition.getX() + offset.getX()));
  -            float offsetY = (float)(currentGlyphPosition.getY()
  -                            - defaultGlyphPosition.getY());
   
  -            GVTGlyphMetrics gm = gv.getGlyphMetrics(i);
  +            // calculate the advance and offset for the next glyph, do it
  +            // now before we modify the current glyph position
   
  -            float glyphAdvance = 0;
  +            float glyphAdvance = 0;  // along path
  +            float nextGlyphOffset = 0;  // perpendicular to path eg dy or dx
               if (i < gv.getNumGlyphs()-1) {
  +
                   Point2D nextGlyphPosition = gv.getGlyphPosition(i+1);
  -                if (!isVertical()) {
  +                if (horizontal) {
                       glyphAdvance = (float)(nextGlyphPosition.getX() - 
currentGlyphPosition.getX());
  +                    nextGlyphOffset = (float)(nextGlyphPosition.getY() - 
currentGlyphPosition.getY());
                   } else {
                       glyphAdvance = (float)(nextGlyphPosition.getY() - 
currentGlyphPosition.getY());
  +                    nextGlyphOffset = (float)(nextGlyphPosition.getX() - 
currentGlyphPosition.getX());
                   }
  +            } else {
  +                // last glyph, use the glyph metrics
  +                GVTGlyphMetrics gm = gv.getGlyphMetrics(i);
  +                if (horizontal) {
  +                    glyphAdvance = gm.getHorizontalAdvance();
  +                } else {
  +                    if (glyphOrientationAuto) {
  +                        if (isLatinChar(ch)) {
  +                            glyphAdvance = gm.getHorizontalAdvance();
  +                        } else {
  +                            glyphAdvance = gm.getVerticalAdvance();
  +                        }
  +                    } else {
  +                        if (glyphOrientationAngle == 0 || glyphOrientationAngle == 
180) {
  +                            glyphAdvance = gm.getVerticalAdvance();
  +                        } else { // 90 || 270
  +                            glyphAdvance = gm.getHorizontalAdvance();
  +                        }
  +                    }
  +                }
               }
  -
  -            Shape glyph = gv.getGlyphOutline(i);
   
  -            float glyphWidth = (float) glyph.getBounds2D().getWidth();
  -            float glyphHeight = (float) glyph.getBounds2D().getHeight();
  +            // calculate the center line position for the glyph
  +            Rectangle2D glyphBounds = gv.getGlyphOutline(i).getBounds2D();
  +            float glyphWidth = (float) glyphBounds.getWidth();
  +            float glyphHeight = (float) glyphBounds.getHeight();
   
               float charMidPos;
  -            if (!isVertical()) {
  +            if (horizontal) {
                   charMidPos = currentPosition + glyphWidth / 2f;
               } else {
                   charMidPos = currentPosition + glyphHeight / 2f;
  @@ -556,23 +607,40 @@
                   AffineTransform glyphPathTransform = new AffineTransform();
   
                   // rotate midline of glyph to be normal to path
  -                glyphPathTransform.rotate(angle);
  +                if (horizontal) {
  +                    glyphPathTransform.rotate(angle);
  +                } else {
  +                    glyphPathTransform.rotate(angle-(Math.PI/2));
  +                }
   
                   // re-apply any offset eg from tspan, or spacing adjust
  -                if (!isVertical()) {
  -                    glyphPathTransform.translate(0, offsetY);
  +                if (horizontal) {
  +                    glyphPathTransform.translate(0, glyphOffset);
                   } else {
  -                    glyphPathTransform.translate(offsetX, 0);
  +                    glyphPathTransform.translate(glyphOffset, 0);
                   }
   
                   // translate glyph backwards so we rotate about the
                   // center of the glyph
  -                if (!isVertical()) {
  +                if (horizontal) {
                       glyphPathTransform.translate(glyphWidth / -2f, 0f);
                   } else {
  -                    glyphPathTransform.translate(glyphHeight/-2f, 0f);
  +                    if (glyphOrientationAuto) {
  +                        if (isLatinChar(ch)) {
  +                           glyphPathTransform.translate(0f, -glyphHeight/2f);
  +                        } else {
  +                            glyphPathTransform.translate(0f, glyphHeight/2f);
  +                        }
  +                    } else {
  +                        if (glyphOrientationAngle == 0 ) {
  +                            glyphPathTransform.translate(0f, glyphHeight/2f);
  +                        } else { // 90 || 180
  +                            glyphPathTransform.translate(0f, -glyphHeight/2f);
  +                        }
  +                    }
                   }
   
  +                // set the new glyph position and transform
                   AffineTransform glyphTransform = gv.getGlyphTransform(i);
                   if (glyphTransform != null) {
                       glyphPathTransform.concatenate(glyphTransform);
  @@ -581,22 +649,33 @@
                   gv.setGlyphTransform(i, glyphPathTransform);
                   gv.setGlyphPosition(i, new Point2D.Double(charMidPoint.getX(),
                                                             charMidPoint.getY()));
  +                // keep track of the last glyph drawn to make calculating the
  +                // textPathAdvance value easier later
  +                lastGlyphDrawn = i;
  +                lastGlyphAdvance = glyphAdvance;
  +
               } else {
                   // not on path so don't render
                   gv.setGlyphVisible(i, false);
               }
               currentPosition += glyphAdvance;
  +            glyphOffset += nextGlyphOffset;
               currentChar += gv.getCharacterCount(i,i);
  +            ch = aci.setIndex(aci.getBeginIndex() + i + gv.getCharacterCount(i,i));
           }
   
           // store the position where a following glyph should be drawn,
  -        // note: this will only be used if the following text layout is not on a 
text path
  -        Point2D lastGlyphPos = gv.getGlyphPosition(getGlyphCount()-1);
  -        GVTGlyphMetrics lastGlyphMetrics = gv.getGlyphMetrics(getGlyphCount()-1);
  -        if (!isVertical()) {
  -            textPathAdvance = new 
Point2D.Double(lastGlyphPos.getX()+lastGlyphMetrics.getHorizontalAdvance(), 
lastGlyphPos.getY());
  +        // note: this will only be used if the following text layout is not
  +        //       on a text path
  +        if (lastGlyphDrawn > -1) {
  +            Point2D lastGlyphPos = gv.getGlyphPosition(lastGlyphDrawn);
  +            if (horizontal) {
  +                textPathAdvance = new 
Point2D.Double(lastGlyphPos.getX()+lastGlyphAdvance, lastGlyphPos.getY());
  +            } else {
  +                textPathAdvance = new Point2D.Double(lastGlyphPos.getX(), 
lastGlyphPos.getY()+lastGlyphAdvance);
  +            }
           } else {
  -            textPathAdvance = new Point2D.Double(lastGlyphPos.getX(), 
lastGlyphPos.getY()+lastGlyphMetrics.getVerticalAdvance());
  +            textPathAdvance = new Point2D.Double(0,0);
           }
       }
   
  @@ -907,6 +986,56 @@
       }
   
       /**
  +     * Returns whether or not the vertical glyph orientation value is "auto".
  +     */
  +    protected boolean isGlyphOrientationAuto() {
  +        boolean glyphOrientationAuto = true;
  +        aci.first();
  +        if 
(aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.VERTICAL_ORIENTATION) 
!= null) {
  +            glyphOrientationAuto = 
(aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.VERTICAL_ORIENTATION)
  +                                     == 
GVTAttributedCharacterIterator.TextAttribute.ORIENTATION_AUTO);
  +        }
  +        return glyphOrientationAuto;
  +    }
  +
  +    /**
  +     * Returns the value of the vertical glyph orientation angle. This will be
  +     * one of 0, 90, 180 or 270.
  +     */
  +    protected int getGlyphOrientationAngle() {
  +
  +        int glyphOrientationAngle = 0;
  +
  +        aci.first();
  +        Float angle = (Float)aci.getAttribute(GVTAttributedCharacterIterator.
  +            TextAttribute.VERTICAL_ORIENTATION_ANGLE);
  +        if (angle != null) {
  +            glyphOrientationAngle = (int)angle.floatValue();
  +        }
  +        // if not one of 0, 90, 180 or 270, round to nearest value
  +        if (glyphOrientationAngle != 0 || glyphOrientationAngle != 90
  +            || glyphOrientationAngle != 180 || glyphOrientationAngle != 270) {
  +            while (glyphOrientationAngle < 0) {
  +                glyphOrientationAngle += 360;
  +            }
  +            while (glyphOrientationAngle >= 360) {
  +                glyphOrientationAngle -= 360;
  +            }
  +            if (glyphOrientationAngle <= 45 || glyphOrientationAngle > 315) {
  +                glyphOrientationAngle = 0;
  +            } else if (glyphOrientationAngle > 45 && glyphOrientationAngle <= 135) {
  +                glyphOrientationAngle = 90;
  +            } else if (glyphOrientationAngle > 135 && glyphOrientationAngle <= 225) 
{
  +                glyphOrientationAngle = 180;
  +            } else {
  +                glyphOrientationAngle = 270;
  +            }
  +        }
  +        return glyphOrientationAngle;
  +    }
  +
  +
  +    /**
        * Explicitly lays out each of the glyphs in the glyph vector. This will
        * handle any glyph position adjustments such as dx, dy and baseline offsets.
        * It will also handle vertical layouts.
  @@ -936,39 +1065,10 @@
           float verticalFirstOffset = 0f;
           float largestAdvanceY = 0;
   
  -        boolean glyphOrientationAuto = true;
  +        boolean glyphOrientationAuto = isGlyphOrientationAuto();
           int glyphOrientationAngle = 0;
  -
  -        if 
(aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.VERTICAL_ORIENTATION) 
!= null) {
  -            glyphOrientationAuto = 
(aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.VERTICAL_ORIENTATION)
  -                                     == 
GVTAttributedCharacterIterator.TextAttribute.ORIENTATION_AUTO);
  -
  -            if (!glyphOrientationAuto) {
  -                Float angle = 
(Float)aci.getAttribute(GVTAttributedCharacterIterator.
  -                                           
TextAttribute.VERTICAL_ORIENTATION_ANGLE);
  -                if (angle != null) {
  -                    glyphOrientationAngle = (int)angle.floatValue();
  -                }
  -                // if not one of 0, 90, 180 or 270, round to nearest value
  -                if (glyphOrientationAngle != 0 || glyphOrientationAngle != 90
  -                    || glyphOrientationAngle != 180 || glyphOrientationAngle != 
270) {
  -                    while (glyphOrientationAngle < 0) {
  -                        glyphOrientationAngle += 360;
  -                    }
  -                    while (glyphOrientationAngle >= 360) {
  -                        glyphOrientationAngle -= 360;
  -                    }
  -                    if (glyphOrientationAngle <= 45 || glyphOrientationAngle > 315) 
{
  -                        glyphOrientationAngle = 0;
  -                    } else if (glyphOrientationAngle > 45 && glyphOrientationAngle 
<= 135) {
  -                        glyphOrientationAngle = 90;
  -                    } else if (glyphOrientationAngle > 135 && glyphOrientationAngle 
<= 225) {
  -                        glyphOrientationAngle = 180;
  -                    } else {
  -                        glyphOrientationAngle = 270;
  -                    }
  -                }
  -            }
  +        if (!glyphOrientationAuto) {
  +            glyphOrientationAngle = getGlyphOrientationAngle();
           }
   
           while (i < numGlyphs) {
  @@ -985,10 +1085,8 @@
                   } else {
                       if (glyphOrientationAngle == 0) {
                           verticalFirstOffset = (float) 
gv.getGlyphMetrics(i).getBounds2D().getHeight();
  -                    } else if (glyphOrientationAngle == 90 || glyphOrientationAngle 
== 180){
  +                    } else {
                           verticalFirstOffset = 0f;
  -                    } else { // 270
  -                        verticalFirstOffset = (float) 
gv.getGlyphMetrics(i).getBounds2D().getWidth();
                       }
                   }
               } else {
  @@ -1151,15 +1249,15 @@
                           } else if (glyphOrientationAngle == 90) {
                               advanceY = gm.getHorizontalAdvance();
                           } else { // 270
  -                            if (i < gv.getNumGlyphs()-1) {
  -                                GVTGlyphMetrics nextGm = gv.getGlyphMetrics(i+1);
  -                                advanceY = nextGm.getHorizontalAdvance();
  -                            } else {
  -                                // need to estimate here, use the vertical advance
  -                                // value because it should be bigger than the
  -                                // width of any glyph that follows
  -                                advanceY = gm.getVerticalAdvance();
  +                            advanceY = gm.getHorizontalAdvance();
  +                            // need to translate backwards so that the spacing
  +                            // between chars is correct
  +                            AffineTransform glyphTransform = 
gv.getGlyphTransform(i);
  +                            if (glyphTransform == null) {
  +                                glyphTransform = new AffineTransform();
                               }
  +                            glyphTransform.translate(-advanceY, 0);
  +                            gv.setGlyphTransform(i, glyphTransform);
                           }
                       }
                       curr_y_pos += advanceY;
  @@ -1167,8 +1265,8 @@
                       curr_x_pos += gm.getHorizontalAdvance();
                   }
               }
  +            ch = aci.setIndex(aci.getBeginIndex() + i + gv.getCharacterCount(i,i));
               i++;
  -            ch = aci.setIndex(aci.getBeginIndex() + i);
               firstChar = false;
   
           }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to