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/07/11 07:16:06 UTC

svn commit: r420729 - in /xmlgraphics/batik/branches/anim/sources/org/apache/batik: anim/ anim/timing/ bridge/ dom/svg/

Author: cam
Date: Mon Jul 10 22:16:05 2006
New Revision: 420729

URL: http://svn.apache.org/viewvc?rev=420729&view=rev
Log:
1. Animation priority is fixed now, so that begin times affect animation
   priority, and if begin times are equal, the document order is used.
2. Animations can now be removed and added to the document any time
   while the document is running.
3. An implicit unresolved end time is now used when the end timing specifier
   list contains eventbase, accesskey or repeat timing specifiers.

Added:
    xmlgraphics/batik/branches/anim/sources/org/apache/batik/dom/svg/SVGAnimationContext.java   (with props)
Modified:
    xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/AbstractAnimation.java
    xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/AnimationEngine.java
    xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/AccesskeyTimingSpecifier.java
    xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/EventbaseTimingSpecifier.java
    xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/IndefiniteTimingSpecifier.java
    xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/MediaMarkerTimingSpecifier.java
    xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/OffsetTimingSpecifier.java
    xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/SyncbaseTimingSpecifier.java
    xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/TimedElement.java
    xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/TimingSpecifier.java
    xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/WallclockTimingSpecifier.java
    xmlgraphics/batik/branches/anim/sources/org/apache/batik/bridge/SVGAnimationElementBridge.java
    xmlgraphics/batik/branches/anim/sources/org/apache/batik/bridge/SVGAnimationEngine.java

Modified: xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/AbstractAnimation.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/AbstractAnimation.java?rev=420729&r1=420728&r2=420729&view=diff
==============================================================================
--- xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/AbstractAnimation.java (original)
+++ xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/AbstractAnimation.java Mon Jul 10 22:16:05 2006
@@ -73,6 +73,13 @@
     protected boolean isFrozen;
 
     /**
+     * The time at which this animation became active.  Used for ensuring the
+     * sandwich order is correct when multiple animations become active
+     * simultaneously.
+     */
+    protected float beginTime;
+
+    /**
      * The value of this animation.
      */
     protected AnimatableValue value;

Modified: xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/AnimationEngine.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/AnimationEngine.java?rev=420729&r1=420728&r2=420729&view=diff
==============================================================================
--- xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/AnimationEngine.java (original)
+++ xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/AnimationEngine.java Mon Jul 10 22:16:05 2006
@@ -22,6 +22,7 @@
 import java.util.Map;
 
 import org.apache.batik.anim.timing.TimedDocumentRoot;
+import org.apache.batik.anim.timing.TimedElement;
 import org.apache.batik.anim.values.AnimatableValue;
 import org.apache.batik.dom.util.DoublyIndexedTable;
 
@@ -78,8 +79,6 @@
         animInfo.target = target;
         animations.put(anim, animInfo);
 
-//         getSandwich(target, pn);
-//         TargetInfo targetInfo = getTargetInfo(target);
         Sandwich sandwich;
         if (isCSS) {
             sandwich = getSandwich(target, an);
@@ -99,6 +98,37 @@
     }
 
     /**
+     * Removes an animation from the document.
+     */
+    public void removeAnimation(AbstractAnimation anim) {
+        org.apache.batik.anim.timing.Trace.enter(this, "removeAnimation", new Object[] { anim } ); try {
+        timedDocumentRoot.removeChild(anim.getTimedElement());
+        AnimationInfo animInfo = getAnimationInfo(anim);
+        AbstractAnimation nextHigher = anim.higherAnimation;
+        if (nextHigher != null) {
+            nextHigher.markDirty();
+        }
+        moveToBottom(anim);
+        if (anim.higherAnimation != null) {
+            anim.higherAnimation.lowerAnimation = null;
+        }
+        Sandwich sandwich;
+        if (animInfo.isCSS) {
+            sandwich = getSandwich(animInfo.target,
+                                   animInfo.attributeLocalName);
+        } else {
+            sandwich = getSandwich(animInfo.target,
+                                   animInfo.attributeNamespaceURI,
+                                   animInfo.attributeLocalName);
+        }
+        if (sandwich.animation == anim) {
+            sandwich.animation = null;
+            sandwich.shouldUpdate = true;
+        }
+        } finally { org.apache.batik.anim.timing.Trace.exit(); }
+    }
+
+    /**
      * Returns the Sandwich for the given CSS property and animation target.
      */
     protected Sandwich getSandwich(AnimationTarget target, String pn) {
@@ -169,9 +199,7 @@
                 Sandwich sandwich = (Sandwich) e2.getValue();
                 if (sandwich.shouldUpdate || sandwich.animation.isDirty) {
                     AnimatableValue av = sandwich.animation.getComposedValue();
-                    // if (av == null || av.hasChanged()) {
-                        target.updateAttributeValue(namespaceURI, localName, av);
-                    // }
+                    target.updateAttributeValue(namespaceURI, localName, av);
                     sandwich.shouldUpdate = false;
                     sandwich.animation.isDirty = false;
                 }
@@ -188,15 +216,13 @@
                     //     needed, to avoid clearing the property value before
                     //     getting the composed value.
                     AnimatableValue av = sandwich.animation.getComposedValue();
-                    // if (av == null || av.hasChanged()) {
-                        boolean hasAdditive = true;
-                        if (hasAdditive) {
-                            target.updatePropertyValue(propertyName, null);
-                        }
-                        if (!(hasAdditive && av == null)) {
-                            target.updatePropertyValue(propertyName, av);
-                        }
-                    // }
+                    boolean hasAdditive = true;
+                    if (hasAdditive) {
+                        target.updatePropertyValue(propertyName, null);
+                    }
+                    if (!(hasAdditive && av == null)) {
+                        target.updatePropertyValue(propertyName, av);
+                    }
                     sandwich.shouldUpdate = false;
                     sandwich.animation.isDirty = false;
                 }
@@ -211,14 +237,63 @@
      * @param begin the time the element became active, in document simple time
      */
     public void toActive(AbstractAnimation anim, float begin) {
-        // XXX Animation should not always be moved to the very top; it
-        //     should be based on the document order if it became active
-        //     at the same time as another.
-        // XXX is this the right amount of dirty marking?
         moveToTop(anim);
         anim.isActive = true;
+        anim.beginTime = begin;
         anim.isFrozen = false;
+        // Move the animation down, in case it began at the same time as another
+        // animation in the sandwich and it's earlier in document order.
+        pushDown(anim);
         anim.markDirty();
+    }
+
+    /**
+     * Moves the animation down the sandwich such that it is in the right
+     * position according to begin time and document order.
+     */
+    protected void pushDown(AbstractAnimation anim) {
+        TimedElement e = anim.getTimedElement();
+        AbstractAnimation top = null;
+        boolean moved = false;
+        while (anim.lowerAnimation != null
+                && (anim.lowerAnimation.isActive
+                    || anim.lowerAnimation.isFrozen)
+                && (anim.lowerAnimation.beginTime > anim.beginTime
+                    || anim.lowerAnimation.beginTime == anim.beginTime
+                        && e.isBefore(anim.lowerAnimation.getTimedElement()))) {
+            AbstractAnimation higher = anim.higherAnimation;
+            AbstractAnimation lower = anim.lowerAnimation;
+            AbstractAnimation lowerLower = lower.lowerAnimation;
+            if (higher != null) {
+                higher.lowerAnimation = lower;
+            }
+            if (lowerLower != null) {
+                lowerLower.higherAnimation = anim;
+            }
+            lower.lowerAnimation = anim;
+            lower.higherAnimation = higher;
+            anim.lowerAnimation = lowerLower;
+            anim.higherAnimation = lower;
+            if (!moved) {
+                top = lower;
+                moved = true;
+            }
+        }
+        if (moved) {
+            AnimationInfo animInfo = getAnimationInfo(anim);
+            Sandwich sandwich;
+            if (animInfo.isCSS) {
+                sandwich = getSandwich(animInfo.target,
+                                       animInfo.attributeLocalName);
+            } else {
+                sandwich = getSandwich(animInfo.target,
+                                       animInfo.attributeNamespaceURI,
+                                       animInfo.attributeLocalName);
+            }
+            if (sandwich.animation == anim) {
+                sandwich.animation = top;
+            }
+        }
     }
 
     /**

Modified: xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/AccesskeyTimingSpecifier.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/AccesskeyTimingSpecifier.java?rev=420729&r1=420728&r2=420729&view=diff
==============================================================================
--- xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/AccesskeyTimingSpecifier.java (original)
+++ xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/AccesskeyTimingSpecifier.java Mon Jul 10 22:16:05 2006
@@ -116,6 +116,14 @@
         }
     }
 
+    /**
+     * Returns whether this timing specifier is event-like (i.e., if it is
+     * an eventbase, accesskey or a repeat timing specifier).
+     */
+    public boolean isEventCondition() {
+        return true;
+    }
+
     // EventListener /////////////////////////////////////////////////////////
 
     /**

Modified: xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/EventbaseTimingSpecifier.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/EventbaseTimingSpecifier.java?rev=420729&r1=420728&r2=420729&view=diff
==============================================================================
--- xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/EventbaseTimingSpecifier.java (original)
+++ xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/EventbaseTimingSpecifier.java Mon Jul 10 22:16:05 2006
@@ -106,6 +106,14 @@
             (eventNamespaceURI, eventType, this, false);
     }
 
+    /**
+     * Returns whether this timing specifier is event-like (i.e., if it is
+     * an eventbase, accesskey or a repeat timing specifier).
+     */
+    public boolean isEventCondition() {
+        return true;
+    }
+
     // EventListener /////////////////////////////////////////////////////////
 
     /**

Modified: xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/IndefiniteTimingSpecifier.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/IndefiniteTimingSpecifier.java?rev=420729&r1=420728&r2=420729&view=diff
==============================================================================
--- xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/IndefiniteTimingSpecifier.java (original)
+++ xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/IndefiniteTimingSpecifier.java Mon Jul 10 22:16:05 2006
@@ -52,4 +52,12 @@
             owner.addInstanceTime(instance, isBegin);
         }
     }
+
+    /**
+     * Returns whether this timing specifier is event-like (i.e., if it is
+     * an eventbase, accesskey or a repeat timing specifier).
+     */
+    public boolean isEventCondition() {
+        return false;
+    }
 }

Modified: xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/MediaMarkerTimingSpecifier.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/MediaMarkerTimingSpecifier.java?rev=420729&r1=420728&r2=420729&view=diff
==============================================================================
--- xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/MediaMarkerTimingSpecifier.java (original)
+++ xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/MediaMarkerTimingSpecifier.java Mon Jul 10 22:16:05 2006
@@ -63,4 +63,12 @@
     public String toString() {
         return syncbaseID + ".marker(" + markerName + ")";
     }
+
+    /**
+     * Returns whether this timing specifier is event-like (i.e., if it is
+     * an eventbase, accesskey or a repeat timing specifier).
+     */
+    public boolean isEventCondition() {
+        return false;
+    }
 }

Modified: xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/OffsetTimingSpecifier.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/OffsetTimingSpecifier.java?rev=420729&r1=420728&r2=420729&view=diff
==============================================================================
--- xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/OffsetTimingSpecifier.java (original)
+++ xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/OffsetTimingSpecifier.java Mon Jul 10 22:16:05 2006
@@ -54,4 +54,12 @@
         InstanceTime instance = new InstanceTime(this, offset, null, false);
         owner.addInstanceTime(instance, isBegin);
     }
+
+    /**
+     * Returns whether this timing specifier is event-like (i.e., if it is
+     * an eventbase, accesskey or a repeat timing specifier).
+     */
+    public boolean isEventCondition() {
+        return false;
+    }
 }

Modified: xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/SyncbaseTimingSpecifier.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/SyncbaseTimingSpecifier.java?rev=420729&r1=420728&r2=420729&view=diff
==============================================================================
--- xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/SyncbaseTimingSpecifier.java (original)
+++ xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/SyncbaseTimingSpecifier.java Mon Jul 10 22:16:05 2006
@@ -81,6 +81,14 @@
     }
 
     /**
+     * Returns whether this timing specifier is event-like (i.e., if it is
+     * an eventbase, accesskey or a repeat timing specifier).
+     */
+    public boolean isEventCondition() {
+        return false;
+    }
+
+    /**
      * Called by the timebase element when it creates a new Interval.
      */
     void newInterval(Interval interval) {

Modified: xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/TimedElement.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/TimedElement.java?rev=420729&r1=420728&r2=420729&view=diff
==============================================================================
--- xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/TimedElement.java (original)
+++ xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/TimedElement.java Mon Jul 10 22:16:05 2006
@@ -655,6 +655,19 @@
     }
 
     /**
+     * Returns whether the end timing specifier list contains any eventbase,
+     * accesskey or repeat timing specifiers.
+     */
+    protected boolean endHasEventConditions() {
+        for (int i = 0; i < endTimes.length; i++) {
+            if (endTimes[i].isEventCondition()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
      * Computes an interval from the begin and end instance time lists.
      * @param first indicates whether this is the first interval to compute
      * @param fixedBegin if true, specifies that the value given for
@@ -717,6 +730,10 @@
                                 && tempEnd == currentInterval.getEnd()) {
                         for (;;) {
                             if (!endIterator.hasNext()) {
+                                if (endHasEventConditions()) {
+                                    tempEnd = UNRESOLVED;
+                                    break;
+                                }
                                 return null;
                             }
                             endInstanceTime = (InstanceTime) endIterator.next();
@@ -732,6 +749,10 @@
                             break;
                         }
                         if (!endIterator.hasNext()) {
+                            if (endHasEventConditions()) {
+                                tempEnd = UNRESOLVED;
+                                break;
+                            }
                             return null;
                         }
                         endInstanceTime = (InstanceTime) endIterator.next();
@@ -743,7 +764,8 @@
                     tempEnd = tempBegin + ad;
                 }
             }
-            if (!first || tempEnd > 0) {
+            if (!first || tempEnd > 0 || tempBegin == 0 && tempEnd == 0
+                    || isUnresolved(tempEnd)) {
                 if (restartMode == RESTART_ALWAYS && beginIterator.hasNext()) {
                     InstanceTime nextBeginInstance =
                         (InstanceTime) beginIterator.next();
@@ -1157,6 +1179,12 @@
      * access key events.
      */
     protected abstract EventTarget getRootEventTarget();
+
+    /**
+     * Returns whether this timed element comes before the given timed element
+     * in document order.
+     */
+    public abstract boolean isBefore(TimedElement other);
 
     /**
      * Returns a string representation of the given time value.

Modified: xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/TimingSpecifier.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/TimingSpecifier.java?rev=420729&r1=420728&r2=420729&view=diff
==============================================================================
--- xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/TimingSpecifier.java (original)
+++ xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/TimingSpecifier.java Mon Jul 10 22:16:05 2006
@@ -66,6 +66,12 @@
     }
 
     /**
+     * Returns whether this timing specifier is event-like (i.e., if it is
+     * an eventbase, accesskey or a repeat timing specifier).
+     */
+    public abstract boolean isEventCondition();
+
+    /**
      * Called by the timebase element when it creates a new Interval.
      * This should be overridden in descendant classes that generate
      * time instances based on the interval of a timebase element.

Modified: xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/WallclockTimingSpecifier.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/WallclockTimingSpecifier.java?rev=420729&r1=420728&r2=420729&view=diff
==============================================================================
--- xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/WallclockTimingSpecifier.java (original)
+++ xmlgraphics/batik/branches/anim/sources/org/apache/batik/anim/timing/WallclockTimingSpecifier.java Mon Jul 10 22:16:05 2006
@@ -62,4 +62,12 @@
         instance = new InstanceTime(this, t, null, false);
         owner.addInstanceTime(instance, isBegin);
     }
+
+    /**
+     * Returns whether this timing specifier is event-like (i.e., if it is
+     * an eventbase, accesskey or a repeat timing specifier).
+     */
+    public boolean isEventCondition() {
+        return false;
+    }
 }

Modified: xmlgraphics/batik/branches/anim/sources/org/apache/batik/bridge/SVGAnimationElementBridge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/anim/sources/org/apache/batik/bridge/SVGAnimationElementBridge.java?rev=420729&r1=420728&r2=420729&view=diff
==============================================================================
--- xmlgraphics/batik/branches/anim/sources/org/apache/batik/bridge/SVGAnimationElementBridge.java (original)
+++ xmlgraphics/batik/branches/anim/sources/org/apache/batik/bridge/SVGAnimationElementBridge.java Mon Jul 10 22:16:05 2006
@@ -28,6 +28,7 @@
 import org.apache.batik.anim.timing.TimedElement;
 import org.apache.batik.anim.values.AnimatableValue;
 import org.apache.batik.css.engine.CSSEngineEvent;
+import org.apache.batik.dom.AbstractNode;
 import org.apache.batik.dom.svg.AnimatedLiveAttributeValue;
 import org.apache.batik.dom.svg.SVGAnimationContext;
 import org.apache.batik.dom.svg.SVGOMElement;
@@ -142,7 +143,12 @@
             b.ctx = ctx;
             b.eng = ctx.getAnimationEngine();
             b.element.setSVGContext(b);
-            b.eng.addInitialBridge(b);
+            if (b.eng.hasStarted()) {
+                b.initializeAnimation();
+                b.initializeTimedElement();
+            } else {
+                b.eng.addInitialBridge(b);
+            }
         }
     }
 
@@ -151,7 +157,7 @@
      * document's AnimationEngine.
      */
     protected void initializeAnimation() {
-        // target element
+        // Determine the target element.
         String uri = XLinkSupport.getXLinkHref(element);
         Node t;
         if (uri.length() == 0) {
@@ -173,7 +179,7 @@
             throw new RuntimeException("Element cannot be the target of an animation");
         }
 
-        // attribute name
+        // Get the attribute/property name.
         String an = element.getAttributeNS(null, SVG_ATTRIBUTE_NAME_ATTRIBUTE);
         int ci = an.indexOf(':');
         if (ci == -1) {
@@ -197,6 +203,7 @@
             throw new RuntimeException("Attribute '" + an + "' cannot be animated");
         }
 
+        // Add the animation.
         timedElement = createTimedElement();
         animation = createAnimation(animationTarget);
         eng.addAnimation(animationTarget, attributeNamespaceURI, attributeLocalName,
@@ -299,8 +306,8 @@
      */
     public void dispose() {
         if (element.getSVGContext() == null) {
-            // Only clear the references if this is not part of a rebuild.
-            // XXX Should also remove this animation.
+            // Only remove the animation if this is not part of a rebuild.
+            eng.removeAnimation(animation);
             element = null;
         }
     }
@@ -518,6 +525,16 @@
          */
         protected EventTarget getParentEventTarget(TimedElement e) {
             return AnimationSupport.getParentEventTarget(e);
+        }
+
+        /**
+         * Returns whether this timed element comes before the given timed
+         * element in document order.
+         */
+        public boolean isBefore(TimedElement other) {
+            Element e = ((SVGTimedElement) other).getElement();
+            int pos = ((AbstractNode) element).compareDocumentPosition(e);
+            return (pos & AbstractNode.DOCUMENT_POSITION_PRECEDING) != 0;
         }
 
         /**

Modified: xmlgraphics/batik/branches/anim/sources/org/apache/batik/bridge/SVGAnimationEngine.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/anim/sources/org/apache/batik/bridge/SVGAnimationEngine.java?rev=420729&r1=420728&r2=420729&view=diff
==============================================================================
--- xmlgraphics/batik/branches/anim/sources/org/apache/batik/bridge/SVGAnimationEngine.java (original)
+++ xmlgraphics/batik/branches/anim/sources/org/apache/batik/bridge/SVGAnimationEngine.java Mon Jul 10 22:16:05 2006
@@ -54,6 +54,7 @@
 import org.apache.batik.css.engine.value.ValueManager;
 import org.apache.batik.dom.svg.SVGOMDocument;
 import org.apache.batik.dom.svg.SVGOMElement;
+import org.apache.batik.dom.svg.SVGStylableElement;
 import org.apache.batik.parser.DefaultPreserveAspectRatioHandler;
 import org.apache.batik.parser.FloatArrayProducer;
 import org.apache.batik.parser.DefaultLengthHandler;
@@ -72,6 +73,7 @@
 
 import org.w3c.dom.Document;
 import org.w3c.dom.css.CSSPrimitiveValue;
+import org.w3c.dom.css.CSSStyleDeclaration;
 import org.w3c.dom.css.CSSValue;
 import org.w3c.dom.events.Event;
 import org.w3c.dom.events.EventListener;
@@ -99,6 +101,13 @@
     protected CSSEngine cssEngine;
 
     /**
+     * Whether animation processing has started.  This affects whether
+     * animation element bridges add their animation on to the initial
+     * bridge list, or process them immediately.
+     */
+    protected boolean started;
+
+    /**
      * The factory for unparsed string values.
      */
     protected UncomputedAnimatableStringValueFactory 
@@ -269,6 +278,13 @@
     }
 
     /**
+     * Returns whether animation processing has begun.
+     */
+    public boolean hasStarted() {
+        return started;
+    }
+
+    /**
      * Parses an AnimatableValue.
      */
     public AnimatableValue parseAnimatableValue(AnimationTarget target,
@@ -304,8 +320,16 @@
                 // XXX Should disable animation instead of throwing.
                 throw new RuntimeException("Attribute type " + type + " is not animatable");
             }
-            Value v = cssEngine.getComputedStyle
-                ((CSSStylableElement) target.getElement(), null, idx);
+            SVGStylableElement e = (SVGStylableElement) target.getElement();
+            CSSStyleDeclaration over = e.getOverrideStyle();
+            String oldValue = over.getPropertyValue(pn);
+            if (oldValue != null) {
+                over.removeProperty(pn);
+            }
+            Value v = cssEngine.getComputedStyle(e, null, idx);
+            if (oldValue != null) {
+                over.setProperty(pn, oldValue, null);
+            }
             return factories[type].createValue(target, pn, v);
         }
         // XXX Doesn't handle shorthands.
@@ -464,6 +488,14 @@
         protected EventTarget getRootEventTarget() {
             return (EventTarget) document;
         }
+
+        /**
+         * Returns whether this timed element comes before the given timed
+         * element in document order.
+         */
+        public boolean isBefore(TimedElement other) {
+            return false;
+        }
     }
 
     /**
@@ -493,6 +525,7 @@
                     (SVGAnimationElementBridge) bridges[i];
                 bridge.initializeTimedElement();
             }
+            started = true;
             tick(0);
             // animationThread = new AnimationThread();
             // animationThread.start();

Added: xmlgraphics/batik/branches/anim/sources/org/apache/batik/dom/svg/SVGAnimationContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/anim/sources/org/apache/batik/dom/svg/SVGAnimationContext.java?rev=420729&view=auto
==============================================================================
--- xmlgraphics/batik/branches/anim/sources/org/apache/batik/dom/svg/SVGAnimationContext.java (added)
+++ xmlgraphics/batik/branches/anim/sources/org/apache/batik/dom/svg/SVGAnimationContext.java Mon Jul 10 22:16:05 2006
@@ -0,0 +1,52 @@
+/*
+
+   Copyright 2006 The Apache Software Foundation 
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+*/
+package org.apache.batik.dom.svg;
+
+import org.w3c.dom.smil.ElementTimeControl;
+import org.w3c.dom.svg.SVGElement;
+
+/**
+ * Context class for SVG animation elements to support extra methods.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id$
+ */
+public interface SVGAnimationContext extends SVGContext, ElementTimeControl {
+
+    /**
+     * <b>DOM</b>: Implements {@link SVGAnimationElement#getTargetElement()}.
+     */
+    SVGElement getTargetElement();
+
+    /**
+     * <b>DOM</b>: Implements {@link SVGAnimationElement#getStartTime()}.
+     */
+    float getStartTime();
+
+    /**
+     * <b>DOM</b>: Implements {@link SVGAnimationElement#getCurrentTime()}.
+     */
+    float getCurrentTime();
+
+    /**
+     * <b>DOM</b>: Implements {@link SVGAnimationElement#getSimpleDuration()}.
+     * With the difference that an indefinite simple duration is returned as
+     * {@link TimedElement.INDEFINITE}, rather than throwing an exception.
+     */
+    float getSimpleDuration();
+}

Propchange: xmlgraphics/batik/branches/anim/sources/org/apache/batik/dom/svg/SVGAnimationContext.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision