You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-commits@xmlgraphics.apache.org by ca...@apache.org on 2006/12/30 07:18:35 UTC

svn commit: r491178 - in /xmlgraphics/batik/trunk/sources/org/apache/batik: anim/ bridge/ dom/svg/

Author: cam
Date: Fri Dec 29 22:18:34 2006
New Revision: 491178

URL: http://svn.apache.org/viewvc?view=rev&rev=491178
Log:
 1. Fixed bug with paced motion animation when the motion path contains
    move commands in the middle.
 2. Fixed bug with motion animation when keyPoints is omitted.
 3. Ignore keyTimes on animations with calcMode="paced".
 4. text elements are now motion animatable.
 5. Motion animation is now applied before the transform of an element,
    according to test animate-elem-24-t.
 6. Fixed inability to animate a line's x1/y1/x2/y2 attributes.
 7. Fixed bug in animateTransform from/to/by/values parsing.
 8. Fixed bug where a use element's x/y attributes where ignored when
    it has its transform or motion animated.
 9. Animations of attributes that can have only non-interpolable values
    now ignore calcMode and assume "discrete".
10. Insertions and removals of elements as children of switch elements now
    cause re-evaluation of which is rendered.  Updating the test attributes
    themselves still will not cause the switch to be re-evaluated.
11. Animation of the transform attribute of switch elements now works.

Modified:
    xmlgraphics/batik/trunk/sources/org/apache/batik/anim/MotionAnimation.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/anim/SimpleAnimation.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/AbstractGraphicsNodeBridge.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGAnimateElementBridge.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGAnimateTransformElementBridge.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGGElementBridge.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGSwitchElementBridge.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGUseElementBridge.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMElement.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMLineElement.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMTextElement.java

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/anim/MotionAnimation.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/anim/MotionAnimation.java?view=diff&rev=491178&r1=491177&r2=491178
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/anim/MotionAnimation.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/anim/MotionAnimation.java Fri Dec 29 22:18:34 2006
@@ -179,13 +179,21 @@
             } else { // CALC_MODE_PACED
                 // This corrects the keyTimes to be paced, so from now on
                 // it can be considered the same as CALC_MODE_LINEAR.
+                epi = path.getExtendedPathIterator();
                 this.keyTimes = new float[count];
-                this.keyTimes[0] = 0;
-                for (int i = 1; i < count - 1; i++) {
+                int j = 0;
+                for (int i = 0; i < count - 1; i++) {
+                    while (epi.currentSegment() ==
+                            ExtendedPathIterator.SEG_MOVETO) {
+                        j++;
+                        epi.next();
+                    }
                     this.keyTimes[i] =
-                        pathLength.getLengthAtSegment(i + 1) / totalLength;
+                        pathLength.getLengthAtSegment(j) / totalLength;
+                    j++;
+                    epi.next();
                 }
-                this.keyTimes[count - 1] = 1;
+                this.keyTimes[count - 1] = 1f;
             }
         }
 
@@ -197,10 +205,18 @@
                                     SMILConstants.SMIL_KEY_POINTS_ATTRIBUTE });
             }
         } else {
+            epi = path.getExtendedPathIterator();
             keyPoints = new float[count];
-            keyPoints[0] = 0f;
-            for (int i = 1; i < count - 1; i++) {
-                keyPoints[i] = pathLength.getLengthAtSegment(i) / totalLength;
+            int j = 0;
+            for (int i = 0; i < count - 1; i++) {
+                while (epi.currentSegment() ==
+                        ExtendedPathIterator.SEG_MOVETO) {
+                    j++;
+                    epi.next();
+                }
+                keyPoints[i] = pathLength.getLengthAtSegment(j) / totalLength;
+                j++;
+                epi.next();
             }
             keyPoints[count - 1] = 1f;
         }

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/anim/SimpleAnimation.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/anim/SimpleAnimation.java?view=diff&rev=491178&r1=491177&r2=491178
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/anim/SimpleAnimation.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/anim/SimpleAnimation.java Fri Dec 29 22:18:34 2006
@@ -106,7 +106,7 @@
         }
         this.values = values;
 
-        if (this.keyTimes != null) {
+        if (this.keyTimes != null && calcMode != CALC_MODE_PACED) {
             if (this.keyTimes.length != values.length) {
                 throw timedElement.createException
                     ("attribute.malformed",

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/AbstractGraphicsNodeBridge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/AbstractGraphicsNodeBridge.java?view=diff&rev=491178&r1=491177&r2=491178
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/AbstractGraphicsNodeBridge.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/AbstractGraphicsNodeBridge.java Fri Dec 29 22:18:34 2006
@@ -26,11 +26,13 @@
 import org.apache.batik.css.engine.CSSEngineEvent;
 import org.apache.batik.css.engine.SVGCSSEngine;
 import org.apache.batik.dom.events.AbstractEvent;
+import org.apache.batik.dom.svg.AbstractSVGTransformList;
 import org.apache.batik.dom.svg.AnimatedLiveAttributeValue;
 import org.apache.batik.dom.svg.LiveAttributeException;
 import org.apache.batik.dom.svg.SVGContext;
 import org.apache.batik.dom.svg.SVGMotionAnimatableElement;
 import org.apache.batik.dom.svg.SVGOMElement;
+import org.apache.batik.dom.svg.SVGOMAnimatedTransformList;
 import org.apache.batik.ext.awt.geom.SegmentList;
 import org.apache.batik.gvt.CanvasGraphicsNode;
 import org.apache.batik.gvt.CompositeGraphicsNode;
@@ -42,8 +44,6 @@
 import org.w3c.dom.events.EventTarget;
 import org.w3c.dom.events.MutationEvent;
 import org.w3c.dom.svg.SVGFitToViewBox;
-import org.w3c.dom.svg.SVGMatrix;
-import org.w3c.dom.svg.SVGTransformList;
 import org.w3c.dom.svg.SVGTransformable;
 
 /**
@@ -109,7 +109,7 @@
         GraphicsNode node = instantiateGraphicsNode();
 
         // 'transform'
-        setTransform(node, e);
+        setTransform(node, e, ctx);
 
         // 'visibility'
         node.setVisible(CSSUtilities.convertVisibility(e));
@@ -159,36 +159,48 @@
     }
 
     /**
-     * Sets the graphics node's transform to the current animated transform
-     * value.
+     * Returns an {@link AffineTransform} that is the transformation to
+     * be applied to the node.
      */
-    protected void setTransform(GraphicsNode n, Element e) {
-        SVGTransformable te = (SVGTransformable) e;
+    protected AffineTransform computeTransform(SVGTransformable te,
+                                               BridgeContext ctx) {
         try {
-            // 'transform'
-            AffineTransform at = new AffineTransform();
-            SVGTransformList tl = te.getTransform().getAnimVal();
-            int count = tl.getNumberOfItems();
-            for (int i = 0; i < count; i++) {
-                SVGMatrix m = tl.getItem(i).getMatrix();
-                at.concatenate(new AffineTransform(m.getA(), m.getB(),
-                                                   m.getC(), m.getD(),
-                                                   m.getE(), m.getF()));
-            }
+            // motion animation
+            AffineTransform at;
             if (e instanceof SVGMotionAnimatableElement) {
                 SVGMotionAnimatableElement mae = (SVGMotionAnimatableElement) e;
-                AffineTransform motion = mae.getMotionTransform();
-                if (motion != null) {
-                    at.concatenate(motion);
+                at = mae.getMotionTransform();
+                if (at == null) {
+                    at = new AffineTransform();
                 }
+            } else {
+                at = new AffineTransform();
             }
-            n.setTransform(at);
+
+            // 'transform'
+            SVGOMAnimatedTransformList atl =
+                (SVGOMAnimatedTransformList) te.getTransform();
+            if (atl.isSpecified()) {
+                AbstractSVGTransformList tl =
+                    (AbstractSVGTransformList) te.getTransform().getAnimVal();
+                at.concatenate(tl.getAffineTransform());
+            }
+
+            return at;
         } catch (LiveAttributeException ex) {
             throw new BridgeException(ctx, ex);
         }
     }
 
     /**
+     * Sets the graphics node's transform to the current animated transform
+     * value.
+     */
+    protected void setTransform(GraphicsNode n, Element e, BridgeContext ctx) {
+        n.setTransform(computeTransform((SVGTransformable) e, ctx));
+    }
+
+    /**
      * Associates the {@link SVGContext} with the element.  This method should
      * be called even for static documents, since some bridges will need to
      * access animated attribute values even during the first build.
@@ -278,6 +290,14 @@
      * Invoked when an MutationEvent of type 'DOMNodeRemoved' is fired.
      */
     public void handleDOMNodeRemovedEvent(MutationEvent evt) {
+        Node parent = e.getParentNode();
+        if (parent instanceof SVGOMElement) {
+            SVGContext bridge = ((SVGOMElement) parent).getSVGContext();
+            if (bridge instanceof SVGSwitchElementBridge) {
+                ((SVGSwitchElementBridge) bridge).handleChildElementRemoved(e);
+                return;
+            }
+        }
         CompositeGraphicsNode gn = node.getParent();
         gn.remove(node);
         disposeTree(e);
@@ -386,7 +406,7 @@
             (AnimatedLiveAttributeValue alav) {
         if (alav.getNamespaceURI() == null
                 && alav.getLocalName().equals(SVG_TRANSFORM_ATTRIBUTE)) {
-            setTransform(node, e);
+            setTransform(node, e, ctx);
             handleGeometryChanged();
         }
     }
@@ -396,7 +416,7 @@
      */
     public void handleOtherAnimationChanged(String type) {
         if (type.equals("motion")) {
-            setTransform(node, e);
+            setTransform(node, e, ctx);
             handleGeometryChanged();
         }
     }

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGAnimateElementBridge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGAnimateElementBridge.java?view=diff&rev=491178&r1=491177&r2=491178
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGAnimateElementBridge.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGAnimateElementBridge.java Fri Dec 29 22:18:34 2006
@@ -73,6 +73,16 @@
      * Returns the parsed 'calcMode' attribute from the animation element.
      */
     protected int parseCalcMode() {
+        // If the attribute being animated has only non-additive values, take
+        // the animation as having calcMode="discrete".
+        if (animationType == AnimationEngine.ANIM_TYPE_CSS
+                && !targetElement.isPropertyAdditive(attributeLocalName)
+            || animationType == AnimationEngine.ANIM_TYPE_XML
+                && !targetElement.isAttributeAdditive(attributeNamespaceURI,
+                                                      attributeLocalName)) {
+            return SimpleAnimation.CALC_MODE_DISCRETE;
+        }
+
         String calcModeString = element.getAttributeNS(null,
                                                        SVG_CALC_MODE_ATTRIBUTE);
         if (calcModeString.length() == 0) {

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGAnimateTransformElementBridge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGAnimateTransformElementBridge.java?view=diff&rev=491178&r1=491177&r2=491178
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGAnimateTransformElementBridge.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGAnimateTransformElementBridge.java Fri Dec 29 22:18:34 2006
@@ -129,7 +129,6 @@
         }
         int count = 1;
         if (i < len && c == ' ' && canComma) {
-            i++;
             while (i < len) {
                 c = s.charAt(i);
                 if (c != ' ') {

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGGElementBridge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGGElementBridge.java?view=diff&rev=491178&r1=491177&r2=491178
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGGElementBridge.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGGElementBridge.java Fri Dec 29 22:18:34 2006
@@ -103,19 +103,21 @@
      * Invoked when an MutationEvent of type 'DOMNodeInserted' is fired.
      */
     public void handleDOMNodeInsertedEvent(MutationEvent evt) {
-        if ( evt.getTarget() instanceof Element ){
+        if (evt.getTarget() instanceof Element) {
             handleElementAdded((CompositeGraphicsNode)node, 
                                e, 
                                (Element)evt.getTarget());
+        } else {
+            super.handleDOMNodeInsertedEvent(evt);
         }
     }
 
     /**
      * Invoked when an MutationEvent of type 'DOMNodeInserted' is fired.
      */
-    public void handleElementAdded(CompositeGraphicsNode gn, 
-                                   Node parent, 
-                                   Element childElt) {
+    protected void handleElementAdded(CompositeGraphicsNode gn, 
+                                      Node parent, 
+                                      Element childElt) {
         // build the graphics node
         GVTBuilder builder = ctx.getGVTBuilder();
         GraphicsNode childNode = builder.build(ctx, childElt);

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGSwitchElementBridge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGSwitchElementBridge.java?view=diff&rev=491178&r1=491177&r2=491178
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGSwitchElementBridge.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGSwitchElementBridge.java Fri Dec 29 22:18:34 2006
@@ -20,6 +20,7 @@
 
 import org.apache.batik.gvt.CompositeGraphicsNode;
 import org.apache.batik.gvt.GraphicsNode;
+
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.svg.SVGTests;
@@ -30,8 +31,13 @@
  * @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a>
  * @version $Id$
  */
-public class SVGSwitchElementBridge extends AbstractSVGBridge
-    implements GraphicsNodeBridge {
+public class SVGSwitchElementBridge extends SVGGElementBridge {
+
+    /**
+     * The child element that was chosen for rendering according to the
+     * test attributes.
+     */
+    protected Element selectedChild;
 
     /**
      * Constructs a new bridge for the &lt;switch> element.
@@ -45,8 +51,11 @@
         return SVG_SWITCH_TAG;
     }
 
-    public Bridge getInstance(){
-        return this;
+    /**
+     * Returns a new instance of this bridge.
+     */
+    public Bridge getInstance() {
+        return new SVGSwitchElementBridge();
     }
 
     /**
@@ -59,60 +68,110 @@
     public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) {
         GraphicsNode refNode = null;
         GVTBuilder builder = ctx.getGVTBuilder();
+        selectedChild = null;
         for (Node n = e.getFirstChild(); n != null; n = n.getNextSibling()) {
             if (n.getNodeType() == Node.ELEMENT_NODE) {
                 Element ref = (Element)n;
-                if (n instanceof SVGTests
-                    && SVGUtilities.matchUserAgent(ref, ctx.getUserAgent())) {
+                if (n instanceof SVGTests &&
+                        SVGUtilities.matchUserAgent(ref, ctx.getUserAgent())) {
+                    selectedChild = ref;
                     refNode = builder.build(ctx, ref);
                     break;
                 }
             }
         }
+
         if (refNode == null) {
             return null;
         }
-        CompositeGraphicsNode group = new CompositeGraphicsNode();
-        group.add(refNode);
-        // 'transform'
-        String s = e.getAttributeNS(null, SVG_TRANSFORM_ATTRIBUTE);
-        if (s.length() != 0) {
-            group.setTransform
-                (SVGUtilities.convertTransform(e, SVG_TRANSFORM_ATTRIBUTE, s,
-                                               ctx));
+
+        CompositeGraphicsNode group =
+            (CompositeGraphicsNode) super.createGraphicsNode(ctx, e);
+        if (group == null) {
+            return null;
         }
+
+        group.add(refNode);
+
         return group;
     }
 
     /**
-     * Builds using the specified BridgeContext and element, the
-     * specified graphics node.
-     *
-     * @param ctx the bridge context to use
-     * @param e the element that describes the graphics node to build
-     * @param node the graphics node to build
+     * Returns true as the &lt;switch> element is not a container.
      */
-    public void buildGraphicsNode(BridgeContext ctx,
-                                  Element e,
-                                  GraphicsNode node) {
-        // bind the specified element and its associated graphics node if needed
-        if (ctx.isInteractive()) {
-            ctx.bind(e, node);
-        }
+    public boolean isComposite() {
+        return false;
     }
 
+    // BridgeUpdateHandler implementation //////////////////////////////////
+
     /**
-     * Returns true if the graphics node has to be displayed, false
-     * otherwise.
+     * Disposes this BridgeUpdateHandler and releases all resources.
      */
-    public boolean getDisplay(Element e) {
-        return CSSUtilities.convertDisplay(e);
+    public void dispose() {
+        selectedChild = null;
+        super.dispose();
     }
 
     /**
-     * Returns false as the &lt;switch> element is not a container.
+     * Responds to the insertion of a child element by re-evaluating the
+     * test attributes.
      */
-    public boolean isComposite() {
-        return false;
+    protected void handleElementAdded(CompositeGraphicsNode gn, 
+                                      Node parent, 
+                                      Element childElt) {
+        for (Node n = childElt.getPreviousSibling(); n
+                != null;
+                n = n.getPreviousSibling()) {
+            if (n == childElt) {
+                return;
+            }
+        }
+        if (childElt instanceof SVGTests
+                && SVGUtilities.matchUserAgent(childElt, ctx.getUserAgent())) {
+            if (selectedChild != null) {
+                gn.remove(0);
+                disposeTree(selectedChild);
+            }
+            selectedChild = childElt;
+            GVTBuilder builder = ctx.getGVTBuilder();
+            GraphicsNode refNode = builder.build(ctx, childElt);
+            if (refNode != null) {
+                gn.add(refNode);
+            }
+        }
+    }
+
+    /**
+     * Responds to the removal of a child element by re-evaluating the
+     * test attributes.
+     */
+    protected void handleChildElementRemoved(Element e) {
+        CompositeGraphicsNode gn = (CompositeGraphicsNode) node;
+        if (selectedChild == e) {
+            gn.remove(0);
+            disposeTree(selectedChild);
+            selectedChild = null;
+            GraphicsNode refNode = null;
+            GVTBuilder builder = ctx.getGVTBuilder();
+            for (Node n = e.getNextSibling();
+                    n != null;
+                    n = n.getNextSibling()) {
+                if (n.getNodeType() == Node.ELEMENT_NODE) {
+                    Element ref = (Element) n;
+                    if (n instanceof SVGTests &&
+                            SVGUtilities.matchUserAgent
+                                (ref, ctx.getUserAgent())) {
+                        refNode = builder.build(ctx, ref);
+                        selectedChild = ref;
+                        break;
+                    }
+                }
+            }
+
+            if (refNode != null) {
+                gn.add(refNode);
+            }
+        }
     }
 }

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGUseElementBridge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGUseElementBridge.java?view=diff&rev=491178&r1=491177&r2=491178
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGUseElementBridge.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGUseElementBridge.java Fri Dec 29 22:18:34 2006
@@ -24,11 +24,9 @@
 import java.awt.geom.Rectangle2D;
 
 import org.apache.batik.dom.events.NodeEventTarget;
-import org.apache.batik.dom.svg.AbstractSVGTransformList;
 import org.apache.batik.dom.svg.AnimatedLiveAttributeValue;
 import org.apache.batik.dom.svg.LiveAttributeException;
 import org.apache.batik.dom.svg.SVGOMAnimatedLength;
-import org.apache.batik.dom.svg.SVGOMAnimatedTransformList;
 import org.apache.batik.dom.svg.SVGOMDocument;
 import org.apache.batik.dom.svg.SVGOMUseElement;
 import org.apache.batik.dom.svg.SVGOMUseShadowRoot;
@@ -42,6 +40,7 @@
 import org.w3c.dom.Node;
 import org.w3c.dom.events.Event;
 import org.w3c.dom.events.EventListener;
+import org.w3c.dom.svg.SVGTransformable;
 import org.w3c.dom.svg.SVGUseElement;
 
 /**
@@ -219,7 +218,7 @@
 
         gn.getChildren().add(refNode);
 
-        gn.setTransform(computeTransform(e, ctx));
+        gn.setTransform(computeTransform((SVGTransformable) e, ctx));
 
         // set an affine transform to take into account the (x, y)
         // coordinates of the <use> element
@@ -327,30 +326,23 @@
     }
 
     /**
-     * Computes the AffineTransform for the node
+     * Returns an {@link AffineTransform} that is the transformation to
+     * be applied to the node.
      */
-    protected AffineTransform computeTransform(Element e, BridgeContext ctx) {
+    protected AffineTransform computeTransform(SVGTransformable e,
+                                               BridgeContext ctx) {
+        AffineTransform at = super.computeTransform(e, ctx);
+        SVGUseElement ue = (SVGUseElement) e;
         try {
-            SVGUseElement ue = (SVGUseElement) e;
-
             // 'x' attribute - default is 0
             float x = ue.getX().getAnimVal().getValue();
 
             // 'y' attribute - default is 0
             float y = ue.getY().getAnimVal().getValue();
 
-            AffineTransform at = AffineTransform.getTranslateInstance(x, y);
-
-            // 'transform'
-            SVGOMAnimatedTransformList atl =
-                (SVGOMAnimatedTransformList) ue.getTransform();
-            if (atl.isSpecified()) {
-                AbstractSVGTransformList tl =
-                    (AbstractSVGTransformList) atl.getAnimVal();
-                at.preConcatenate(tl.getAffineTransform());
-            }
-
-            return at;
+            AffineTransform xy = AffineTransform.getTranslateInstance(x, y);
+            xy.preConcatenate(at);
+            return xy;
         } catch (LiveAttributeException ex) {
             throw new BridgeException(ctx, ex);
         }
@@ -454,7 +446,7 @@
                     && (ln.equals(SVG_X_ATTRIBUTE)
                         || ln.equals(SVG_Y_ATTRIBUTE)
                         || ln.equals(SVG_TRANSFORM_ATTRIBUTE))) {
-                node.setTransform(computeTransform(e, ctx));
+                node.setTransform(computeTransform((SVGTransformable) e, ctx));
                 handleGeometryChanged();
             } else if (ns == null
                     && (ln.equals(SVG_WIDTH_ATTRIBUTE)

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMElement.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMElement.java?view=diff&rev=491178&r1=491177&r2=491178
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMElement.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMElement.java Fri Dec 29 22:18:34 2006
@@ -609,7 +609,7 @@
      * Returns whether the given XML attribute is additive.
      */
     public boolean isAttributeAdditive(String ns, String ln) {
-        return false;
+        return true;
     }
 
     /**

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMLineElement.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMLineElement.java?view=diff&rev=491178&r1=491177&r2=491178
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMLineElement.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMLineElement.java Fri Dec 29 22:18:34 2006
@@ -43,13 +43,13 @@
     static {
         DoublyIndexedTable t =
             new DoublyIndexedTable(SVGGraphicsElement.xmlTraitInformation);
-        t.put(null, SVG_X_ATTRIBUTE,
+        t.put(null, SVG_X1_ATTRIBUTE,
                 new TraitInformation(true, SVGTypes.TYPE_LENGTH, PERCENTAGE_VIEWPORT_WIDTH));
-        t.put(null, SVG_Y_ATTRIBUTE,
+        t.put(null, SVG_Y1_ATTRIBUTE,
                 new TraitInformation(true, SVGTypes.TYPE_LENGTH, PERCENTAGE_VIEWPORT_HEIGHT));
-        t.put(null, SVG_WIDTH_ATTRIBUTE,
+        t.put(null, SVG_X2_ATTRIBUTE,
                 new TraitInformation(true, SVGTypes.TYPE_LENGTH, PERCENTAGE_VIEWPORT_WIDTH));
-        t.put(null, SVG_HEIGHT_ATTRIBUTE,
+        t.put(null, SVG_Y2_ATTRIBUTE,
                 new TraitInformation(true, SVGTypes.TYPE_LENGTH, PERCENTAGE_VIEWPORT_HEIGHT));
         xmlTraitInformation = t;
     }

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMTextElement.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMTextElement.java?view=diff&rev=491178&r1=491177&r2=491178
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMTextElement.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMTextElement.java Fri Dec 29 22:18:34 2006
@@ -18,6 +18,10 @@
  */
 package org.apache.batik.dom.svg;
 
+import java.awt.geom.AffineTransform;
+
+import org.apache.batik.anim.values.AnimatableMotionPointValue;
+import org.apache.batik.anim.values.AnimatableValue;
 import org.apache.batik.dom.AbstractDocument;
 import org.apache.batik.dom.util.DoublyIndexedTable;
 import org.apache.batik.util.SVGTypes;
@@ -38,7 +42,8 @@
  */
 public class SVGOMTextElement
     extends    SVGOMTextPositioningElement
-    implements SVGTextElement {
+    implements SVGTextElement,
+               SVGMotionAnimatableElement {
 
     // Default values for attributes on a text element
     protected static final String X_DEFAULT_VALUE = "0";
@@ -62,6 +67,11 @@
     protected SVGOMAnimatedTransformList transform;
 
     /**
+     * Supplemental transformation due to motion animation.
+     */
+    protected AffineTransform motionTransform;
+
+    /**
      * Creates a new SVGOMTextElement object.
      */
     protected SVGOMTextElement() {
@@ -185,5 +195,39 @@
      */
     protected DoublyIndexedTable getTraitInformationTable() {
         return xmlTraitInformation;
+    }
+
+    // SVGMotionAnimatableElement ////////////////////////////////////////////
+
+    /**
+     * Returns the {@link AffineTransform} representing the current motion
+     * animation for this element.
+     */
+    public AffineTransform getMotionTransform() {
+        return motionTransform;
+    }
+
+    // AnimationTarget ///////////////////////////////////////////////////////
+
+    /**
+     * Updates a 'other' animation value in this target.
+     */
+    public void updateOtherValue(String type, AnimatableValue val) {
+        if (type.equals("motion")) {
+            if (motionTransform == null) {
+                motionTransform = new AffineTransform();
+            }
+            if (val == null) {
+                motionTransform.setToIdentity();
+            } else {
+                AnimatableMotionPointValue p = (AnimatableMotionPointValue) val;
+                motionTransform.setToTranslation(p.getX(), p.getY());
+                motionTransform.rotate(p.getAngle());
+            }
+            SVGOMDocument d = (SVGOMDocument) ownerDocument;
+            d.getAnimatedAttributeListener().otherAnimationChanged(this, type);
+        } else {
+            super.updateOtherValue(type, val);
+        }
     }
 }