bella       01/07/30 23:20:10

  Modified:    sources/org/apache/batik/bridge SVGTextElementBridge.java
                        TextUtilities.java
  Log:
  text rotate attribute now handled properly
  
  Revision  Changes    Path
  1.29      +111 -72   
xml-batik/sources/org/apache/batik/bridge/SVGTextElementBridge.java
  
  Index: SVGTextElementBridge.java
  ===================================================================
  RCS file: 
/home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGTextElementBridge.java,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- SVGTextElementBridge.java 2001/07/05 06:56:09     1.28
  +++ SVGTextElementBridge.java 2001/07/31 06:20:10     1.29
  @@ -47,6 +47,7 @@
   
   import org.w3c.dom.Element;
   import org.w3c.dom.Node;
  +import org.w3c.dom.NodeList;
   import org.w3c.dom.css.CSSPrimitiveValue;
   import org.w3c.dom.css.CSSStyleDeclaration;
   import org.w3c.dom.css.CSSValue;
  @@ -56,7 +57,7 @@
    * Bridge class for the <text> element.
    *
    * @author <a href="[EMAIL PROTECTED]>Bill Haneman</a>
  - * @version $Id: SVGTextElementBridge.java,v 1.28 2001/07/05 06:56:09 bella Exp $
  + * @version $Id: SVGTextElementBridge.java,v 1.29 2001/07/31 06:20:10 bella Exp $
    */
   public class SVGTextElementBridge extends AbstractSVGBridge
       implements GraphicsNodeBridge, ErrorConstants {
  @@ -150,6 +151,8 @@
                                     GraphicsNode node) {
           e.normalize();
           AttributedString as = buildAttributedString(ctx, e, node);
  +        addGlyphPositionAttributes(as, e, ctx);
  +
           ((TextNode)node).setAttributedCharacterIterator(as.getIterator());
   
           // 'filter'
  @@ -341,11 +344,6 @@
                       as = createAttributedString(s, map, indexMap, preserve,
                                                   stripFirst, last && top);
                       if (as != null) {
  -                        // NOTE: we get position attributes from the
  -                        // surrounding text or tspan node, not the tref
  -                        // link target
  -                        addGlyphPositionAttributes
  -                            (as, true, indexMap, ctx, nodeElement);
                           stripLast = !preserve &&
                               (as.getIterator().first() == ' ');
                           if (stripLast) {
  @@ -372,10 +370,6 @@
                   as = createAttributedString
                       (s, m, indexMap, preserve, stripFirst, last && top);
                   if (as != null) {
  -                    if (first) {
  -                        addGlyphPositionAttributes
  -                            (as, !top, indexMap, ctx, element);
  -                    }
                       stripLast =
                           !preserve && (as.getIterator().first() == ' ');
                       if (stripLast && !result.isEmpty()) {
  @@ -499,102 +493,147 @@
           return as;
       }
   
  +    // returns true if node1 is an ancestor of node2
  +    private boolean nodeAncestorOf(Node node1, Node node2) {
  +        Node parent = node2.getParentNode();
  +        while (parent != null && parent != node1) {
  +            parent = parent.getParentNode();
  +        }
  +        if (parent == node1) {
  +            return true;
  +        }
  +        return false;
  +    }
  +
  +
       /**
        * Adds glyph position attributes to an AttributedString.
        */
       protected void addGlyphPositionAttributes(AttributedString as,
  -                                              boolean isChild,
  -                                              int[] indexMap,
  -                                              BridgeContext ctx,
  -                                              Element element) {
  -
  -        UnitProcessor.Context uctx
  -            = UnitProcessor.createContext(ctx, element);
  +                                              Element element,
  +                                              BridgeContext ctx) {
   
  -        int asLength = as.getIterator().getEndIndex();
  -        // AttributedStrings always start at index 0, we hope!
  +        // get all of the glyph position attribute values
  +        String xAtt = element.getAttributeNS(null, SVG_X_ATTRIBUTE);
  +        String yAtt = element.getAttributeNS(null, SVG_Y_ATTRIBUTE);
  +        String dxAtt = element.getAttributeNS(null, SVG_DX_ATTRIBUTE);
  +        String dyAtt = element.getAttributeNS(null, SVG_DY_ATTRIBUTE);
  +        String rotateAtt = element.getAttributeNS(null, SVG_ROTATE_ATTRIBUTE);
  +
  +        UnitProcessor.Context uctx = UnitProcessor.createContext(ctx, element);
  +        AttributedCharacterIterator aci = as.getIterator();
  +
  +        // calculate which chars in the string belong to this element
  +        int firstChar = 0;
  +        for (int i = 0; i < aci.getEndIndex(); i++) {
  +            aci.setIndex(i);
  +            Element delimeter = (Element)aci.getAttribute(
  +            GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_DELIMITER);
  +            if (delimeter == element || nodeAncestorOf(element, delimeter)) {
  +                firstChar = i;
  +                break;
  +            }
  +        }
  +        int lastChar = aci.getEndIndex()-1;
  +        for (int i = aci.getEndIndex()-1; i >= 0; i--) {
  +            aci.setIndex(i);
  +            Element delimeter = (Element)aci.getAttribute(
  +                
GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_DELIMITER);
  +            if (delimeter == element || nodeAncestorOf(element, delimeter)) {
  +                lastChar = i;
  +                break;
  +            }
  +        }
   
  -        // glyph and sub-element positions
  -        String s = element.getAttributeNS(null, SVG_X_ATTRIBUTE);
  -        if (s.length() != 0) {
  +        // process the x attribute
  +        if (xAtt.length() != 0) {
               float x[] = TextUtilities.svgHorizontalCoordinateArrayToUserSpace
  -                (element, SVG_X_ATTRIBUTE, s, ctx);
  -
  -            as.addAttribute(GVTAttributedCharacterIterator.TextAttribute.X,
  -                            new Float(Float.NaN), 0, asLength);
  +                        (element, SVG_X_ATTRIBUTE, xAtt, ctx);
   
  -            if ((x.length > 1) || (isChild)) {
  -                
as.addAttribute(GVTAttributedCharacterIterator.TextAttribute.EXPLICIT_LAYOUT, 
Boolean.TRUE, 0, asLength);
  -            }
  -
  -            for (int i=0; i<asLength; ++i) {
  -                if (i < x.length) {
  -                    as.addAttribute(GVTAttributedCharacterIterator.TextAttribute.X, 
new Float(x[i]), i, i+1);
  +            for (int i = 0; i < x.length; i++) {
  +                if (firstChar+i <= lastChar) {
  +                    as.addAttribute
  +                        (GVTAttributedCharacterIterator.TextAttribute.X,
  +                         new Float(x[i]), firstChar+i, firstChar+i+1);
                   }
               }
           }
   
  -        // parse the y attribute, (default is 0)
  -        s = element.getAttributeNS(null, SVG_Y_ATTRIBUTE);
  -
  -        if (s.length() != 0) {
  +       // process the y attribute
  +        if (yAtt.length() != 0) {
               float y[] = TextUtilities.svgVerticalCoordinateArrayToUserSpace
  -                (element, SVG_Y_ATTRIBUTE, s, ctx);
  +                (element, SVG_Y_ATTRIBUTE, yAtt, ctx);
   
  -            as.addAttribute(GVTAttributedCharacterIterator.TextAttribute.Y,
  -                            new Float(Float.NaN), 0, asLength);
  -
  -            if ((y.length > 1) || (isChild)) {
  -                as.addAttribute
  -                    (GVTAttributedCharacterIterator.TextAttribute.EXPLICIT_LAYOUT, 
Boolean.TRUE, 0, asLength);
  -            }
  -
  -            for (int i=0; i<asLength; ++i) {
  -                if (i < y.length) {
  +            for (int i = 0; i < y.length; i++) {
  +                if (firstChar+i <= lastChar) {
                       as.addAttribute
                           (GVTAttributedCharacterIterator.TextAttribute.Y,
  -                         new Float(y[i]), i, i+1);
  +                         new Float(y[i]), firstChar+i, firstChar+i+1);
                   }
               }
           }
   
  -        s = element.getAttributeNS(null, SVG_DX_ATTRIBUTE);
  -        if (s.length() != 0) {
  -            float x[] = TextUtilities.svgHorizontalCoordinateArrayToUserSpace
  -                (element, SVG_DX_ATTRIBUTE, s, ctx);
  +        // process dx attribute
  +        if (dxAtt.length() != 0) {
  +            float dx[] = TextUtilities.svgHorizontalCoordinateArrayToUserSpace
  +                (element, SVG_DX_ATTRIBUTE, dxAtt, ctx);
   
  -            as.addAttribute
  -                (GVTAttributedCharacterIterator.TextAttribute.DX,
  -                 new Float(Float.NaN), 0, asLength);
  -
  -            for (int i=0; i<asLength; ++i) {
  -                if (i < x.length) {
  +            for (int i = 0; i < dx.length; i++) {
  +                if (firstChar+i <= lastChar) {
                       as.addAttribute
                           (GVTAttributedCharacterIterator.TextAttribute.DX,
  -                         new Float(x[i]), i, i+1);
  +                         new Float(dx[i]), firstChar+i, firstChar+i+1);
                   }
               }
           }
   
  -        // parse the y attribute, (default is 0)
  -        s = element.getAttributeNS(null, SVG_DY_ATTRIBUTE);
  -        if (s.length() != 0) {
  -            float y[] = TextUtilities.svgVerticalCoordinateArrayToUserSpace
  -                (element, SVG_DY_ATTRIBUTE, s, ctx);
  +        // process dy attribute
  +        if (dyAtt.length() != 0) {
  +            float dy[] = TextUtilities.svgVerticalCoordinateArrayToUserSpace
  +                (element, SVG_DY_ATTRIBUTE, dyAtt, ctx);
   
  -            as.addAttribute
  -                (GVTAttributedCharacterIterator.TextAttribute.DY,
  -                 new Float(Float.NaN), 0, asLength);
  -
  -            for (int i=0; i<asLength; ++i) {
  -                if (i < y.length) {
  +            for (int i = 0; i < dy.length; i++) {
  +                if (firstChar+i <= lastChar) {
                       as.addAttribute
                           (GVTAttributedCharacterIterator.TextAttribute.DY,
  -                         new Float(y[i]), i, i+1);
  +                         new Float(dy[i]), firstChar+i, firstChar+i+1);
  +                }
  +            }
  +        }
  +
  +        // process rotate attribute
  +        if (rotateAtt.length() != 0) {
  +            float rotate[] = TextUtilities.svgRotateArrayToFloats
  +                (element, SVG_ROTATE_ATTRIBUTE, rotateAtt, ctx);
  +
  +            if (rotate.length == 1) {  // not a list
  +                // each char will have the same rotate value
  +                as.addAttribute
  +                    (GVTAttributedCharacterIterator.TextAttribute.ROTATION,
  +                    new Float(rotate[0]), firstChar, lastChar+1);
  +
  +            } else {  // its a list
  +                // set each rotate value from the list
  +                for (int i = 0; i < rotate.length; i++) {
  +                    if (firstChar+i <= lastChar) {
  +                        as.addAttribute
  +                            (GVTAttributedCharacterIterator.TextAttribute.ROTATION,
  +                            new Float(rotate[i]), firstChar+i, firstChar+i+1);
  +                    }
                   }
               }
           }
  +
  +        // do the same for each child element
  +        NodeList children = element.getChildNodes();
  +        for (int i = 0; i < children.getLength(); i++) {
  +            Node child = children.item(i);
  +            if (child.getNodeType() == Node.ELEMENT_NODE) {
  +                addGlyphPositionAttributes(as, (Element)child, ctx);
  +            }
  +        }
       }
  +
   
       /**
        * Returns the map to pass to the current characters.
  
  
  
  1.4       +29 -3     xml-batik/sources/org/apache/batik/bridge/TextUtilities.java
  
  Index: TextUtilities.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/TextUtilities.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TextUtilities.java        2001/03/18 18:18:18     1.3
  +++ TextUtilities.java        2001/07/31 06:20:10     1.4
  @@ -22,9 +22,9 @@
    * A collection of utility method for text.
    *
    * @author <a href="[EMAIL PROTECTED]>Bill Haneman</a>
  - * @version $Id: TextUtilities.java,v 1.3 2001/03/18 18:18:18 vhardy Exp $
  + * @version $Id: TextUtilities.java,v 1.4 2001/07/31 06:20:10 bella Exp $
    */
  -public abstract class TextUtilities implements CSSConstants {
  +public abstract class TextUtilities implements CSSConstants, ErrorConstants {
   
       /**
        * Returns the float array that represents a set of horizontal
  @@ -81,7 +81,7 @@
               values.add
                   (new Float(UnitProcessor.svgVerticalCoordinateToUserSpace
                              (st.nextToken(), attrName, uctx)));
  -            c++; 
  +            c++;
           }
           float[] floats = new float[c];
           for (int i=0; i<c; ++i) {
  @@ -89,6 +89,32 @@
           }
           return floats;
       }
  +
  +
  +    public static float[] svgRotateArrayToFloats(Element element,
  +                                                 String attrName,
  +                                                 String valueStr,
  +                                                 BridgeContext ctx) {
  +
  +        StringTokenizer st = new StringTokenizer(valueStr, ", ", false);
  +        float[] floats = new float[st.countTokens()];
  +        int c = 0;
  +        String s;
  +        while (st.hasMoreTokens()) {
  +            try {
  +                s = st.nextToken();
  +                floats[c] = (float)Math.toRadians(SVGUtilities.convertSVGNumber(s));
  +                c++;
  +            } catch (NumberFormatException ex) {
  +                throw new BridgeException
  +                    (element, ERR_ATTRIBUTE_VALUE_MALFORMED,
  +                     new Object [] {attrName, valueStr});
  +            }
  +        }
  +        return floats;
  +    }
  +
  +
   
       /**
        * Converts the font-size CSS value to a float value.
  
  
  

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

Reply via email to