You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by jm...@apache.org on 2013/10/08 16:03:30 UTC
[15/62] [abbrv] [partial] Merged Apache Flex 4.9.0 release branch
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/f690ea2f/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGAnimationEngine.java
----------------------------------------------------------------------
diff --git a/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGAnimationEngine.java b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGAnimationEngine.java
new file mode 100644
index 0000000..dd0d3db
--- /dev/null
+++ b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGAnimationEngine.java
@@ -0,0 +1,1888 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.flex.forks.batik.bridge;
+
+import java.awt.Color;
+import java.awt.Paint;
+import java.lang.ref.WeakReference;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Arrays;
+import java.util.Set;
+
+import org.apache.flex.forks.batik.anim.AnimationEngine;
+import org.apache.flex.forks.batik.anim.AnimationException;
+import org.apache.flex.forks.batik.dom.anim.AnimationTarget;
+import org.apache.flex.forks.batik.anim.timing.TimedDocumentRoot;
+import org.apache.flex.forks.batik.anim.timing.TimedElement;
+import org.apache.flex.forks.batik.anim.values.AnimatableAngleValue;
+import org.apache.flex.forks.batik.anim.values.AnimatableAngleOrIdentValue;
+import org.apache.flex.forks.batik.anim.values.AnimatableBooleanValue;
+import org.apache.flex.forks.batik.anim.values.AnimatableIntegerValue;
+import org.apache.flex.forks.batik.anim.values.AnimatableLengthValue;
+import org.apache.flex.forks.batik.anim.values.AnimatableLengthListValue;
+import org.apache.flex.forks.batik.anim.values.AnimatableLengthOrIdentValue;
+import org.apache.flex.forks.batik.anim.values.AnimatableNumberValue;
+import org.apache.flex.forks.batik.anim.values.AnimatableNumberListValue;
+import org.apache.flex.forks.batik.anim.values.AnimatableNumberOrPercentageValue;
+import org.apache.flex.forks.batik.anim.values.AnimatablePathDataValue;
+import org.apache.flex.forks.batik.anim.values.AnimatablePointListValue;
+import org.apache.flex.forks.batik.anim.values.AnimatablePreserveAspectRatioValue;
+import org.apache.flex.forks.batik.anim.values.AnimatableNumberOrIdentValue;
+import org.apache.flex.forks.batik.anim.values.AnimatableRectValue;
+import org.apache.flex.forks.batik.anim.values.AnimatableStringValue;
+import org.apache.flex.forks.batik.anim.values.AnimatableValue;
+import org.apache.flex.forks.batik.anim.values.AnimatableColorValue;
+import org.apache.flex.forks.batik.anim.values.AnimatablePaintValue;
+import org.apache.flex.forks.batik.css.engine.CSSEngine;
+import org.apache.flex.forks.batik.css.engine.CSSStylableElement;
+import org.apache.flex.forks.batik.css.engine.StyleMap;
+import org.apache.flex.forks.batik.css.engine.value.FloatValue;
+import org.apache.flex.forks.batik.css.engine.value.StringValue;
+import org.apache.flex.forks.batik.css.engine.value.Value;
+import org.apache.flex.forks.batik.css.engine.value.ValueManager;
+import org.apache.flex.forks.batik.dom.svg.SVGOMDocument;
+import org.apache.flex.forks.batik.dom.svg.SVGOMElement;
+import org.apache.flex.forks.batik.dom.svg.SVGStylableElement;
+import org.apache.flex.forks.batik.parser.DefaultPreserveAspectRatioHandler;
+import org.apache.flex.forks.batik.parser.FloatArrayProducer;
+import org.apache.flex.forks.batik.parser.DefaultLengthHandler;
+import org.apache.flex.forks.batik.parser.LengthArrayProducer;
+import org.apache.flex.forks.batik.parser.LengthHandler;
+import org.apache.flex.forks.batik.parser.LengthListParser;
+import org.apache.flex.forks.batik.parser.LengthParser;
+import org.apache.flex.forks.batik.parser.NumberListParser;
+import org.apache.flex.forks.batik.parser.PathArrayProducer;
+import org.apache.flex.forks.batik.parser.PathParser;
+import org.apache.flex.forks.batik.parser.PointsParser;
+import org.apache.flex.forks.batik.parser.ParseException;
+import org.apache.flex.forks.batik.parser.PreserveAspectRatioHandler;
+import org.apache.flex.forks.batik.parser.PreserveAspectRatioParser;
+import org.apache.flex.forks.batik.util.RunnableQueue;
+import org.apache.flex.forks.batik.util.SMILConstants;
+import org.apache.flex.forks.batik.util.XMLConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.css.CSSPrimitiveValue;
+import org.w3c.dom.css.CSSStyleDeclaration;
+import org.w3c.dom.css.CSSValue;
+import org.w3c.dom.events.EventTarget;
+import org.w3c.dom.svg.SVGAngle;
+import org.w3c.dom.svg.SVGLength;
+import org.w3c.dom.svg.SVGPreserveAspectRatio;
+
+/**
+ * An AnimationEngine for SVG documents.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id: SVGAnimationEngine.java 579854 2007-09-27 00:07:53Z cam $
+ */
+public class SVGAnimationEngine extends AnimationEngine {
+
+ /**
+ * The BridgeContext to use for value parsing.
+ */
+ protected BridgeContext ctx;
+
+ /**
+ * The CSSEngine used for CSS value parsing.
+ */
+ 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 Runnable that ticks the document.
+ */
+ protected AnimationTickRunnable animationTickRunnable;
+
+ /**
+ * The factory for unparsed string values.
+ */
+ protected UncomputedAnimatableStringValueFactory
+ uncomputedAnimatableStringValueFactory =
+ new UncomputedAnimatableStringValueFactory();
+
+ /**
+ * The factory for length-or-ident values.
+ */
+ protected AnimatableLengthOrIdentFactory
+ animatableLengthOrIdentFactory = new AnimatableLengthOrIdentFactory();
+
+ /**
+ * The factory for number-or-ident values.
+ */
+ protected AnimatableNumberOrIdentFactory
+ animatableNumberOrIdentFactory =
+ new AnimatableNumberOrIdentFactory(false);
+
+ /**
+ * Factories for {@link AnimatableValue} parsing.
+ */
+ protected Factory[] factories = {
+ null, // TYPE_UNKNOWN
+ new AnimatableIntegerValueFactory(), // TYPE_INTEGER
+ new AnimatableNumberValueFactory(), // TYPE_NUMBER
+ new AnimatableLengthValueFactory(), // TYPE_LENGTH
+ null, // TYPE_NUMBER_OPTIONAL_NUMBER
+ new AnimatableAngleValueFactory(), // TYPE_ANGLE
+ new AnimatableColorValueFactory(), // TYPE_COLOR
+ new AnimatablePaintValueFactory(), // TYPE_PAINT
+ null, // TYPE_PERCENTAGE
+ null, // TYPE_TRANSFORM_LIST
+ uncomputedAnimatableStringValueFactory, // TYPE_URI
+ null, // TYPE_FREQUENCY
+ null, // TYPE_TIME
+ new AnimatableNumberListValueFactory(), // TYPE_NUMBER_LIST
+ new AnimatableLengthListValueFactory(), // TYPE_LENGTH_LIST
+ uncomputedAnimatableStringValueFactory, // TYPE_IDENT
+ uncomputedAnimatableStringValueFactory, // TYPE_CDATA
+ animatableLengthOrIdentFactory, // TYPE_LENGTH_OR_INHERIT
+ uncomputedAnimatableStringValueFactory, // TYPE_IDENT_LIST
+ uncomputedAnimatableStringValueFactory, // TYPE_CLIP_VALUE
+ uncomputedAnimatableStringValueFactory, // TYPE_URI_OR_IDENT
+ uncomputedAnimatableStringValueFactory, // TYPE_CURSOR_VALUE
+ new AnimatablePathDataFactory(), // TYPE_PATH_DATA
+ uncomputedAnimatableStringValueFactory, // TYPE_ENABLE_BACKGROUND_VALUE
+ null, // TYPE_TIME_VALUE_LIST
+ animatableNumberOrIdentFactory, // TYPE_NUMBER_OR_INHERIT
+ uncomputedAnimatableStringValueFactory, // TYPE_FONT_FAMILY_VALUE
+ null, // TYPE_FONT_FACE_FONT_SIZE_VALUE
+ new AnimatableNumberOrIdentFactory(true), // TYPE_FONT_WEIGHT_VALUE
+ new AnimatableAngleOrIdentFactory(), // TYPE_ANGLE_OR_IDENT
+ null, // TYPE_KEY_SPLINES_VALUE
+ new AnimatablePointListValueFactory(), // TYPE_POINTS_VALUE
+ new AnimatablePreserveAspectRatioValueFactory(), // TYPE_PRESERVE_ASPECT_RATIO_VALUE
+ null, // TYPE_URI_LIST
+ uncomputedAnimatableStringValueFactory, // TYPE_LENGTH_LIST_OR_IDENT
+ null, // TYPE_CHARACTER_OR_UNICODE_RANGE_LIST
+ null, // TYPE_UNICODE_RANGE_LIST
+ null, // TYPE_FONT_VALUE
+ null, // TYPE_FONT_DECSRIPTOR_SRC_VALUE
+ animatableLengthOrIdentFactory, // TYPE_FONT_SIZE_VALUE
+ animatableLengthOrIdentFactory, // TYPE_BASELINE_SHIFT_VALUE
+ animatableLengthOrIdentFactory, // TYPE_KERNING_VALUE
+ animatableLengthOrIdentFactory, // TYPE_SPACING_VALUE
+ animatableLengthOrIdentFactory, // TYPE_LINE_HEIGHT_VALUE
+ animatableNumberOrIdentFactory, // TYPE_FONT_SIZE_ADJUST_VALUE
+ null, // TYPE_LANG_VALUE
+ null, // TYPE_LANG_LIST_VALUE
+ new AnimatableNumberOrPercentageValueFactory(), // TYPE_NUMBER_OR_PERCENTAGE
+ null, // TYPE_TIMING_SPECIFIER_LIST
+ new AnimatableBooleanValueFactory(), // TYPE_BOOLEAN
+ new AnimatableRectValueFactory() // TYPE_RECT
+ };
+
+ /**
+ * Whether the document is an SVG 1.2 document.
+ */
+ protected boolean isSVG12;
+
+ /**
+ * List of bridges that will be initialized when the document is started.
+ */
+ protected LinkedList initialBridges = new LinkedList();
+
+ /**
+ * A StyleMap used by the {@link Factory}s when computing CSS values.
+ */
+ protected StyleMap dummyStyleMap;
+
+ /**
+ * The thread that ticks the animation engine.
+ */
+ protected AnimationThread animationThread;
+
+ /**
+ * The animation limiting mode.
+ */
+ protected int animationLimitingMode;
+
+ /**
+ * The amount of animation limiting.
+ */
+ protected float animationLimitingAmount;
+
+ /**
+ * Set of SMIL animation event names for SVG 1.1.
+ */
+ protected static final Set animationEventNames11 = new HashSet();
+
+ /**
+ * Set of SMIL animation event names for SVG 1.2.
+ */
+ protected static final Set animationEventNames12 = new HashSet();
+
+ static {
+ String[] eventNamesCommon = {
+ "click", "mousedown", "mouseup", "mouseover", "mousemove",
+ "mouseout", "beginEvent", "endEvent"
+ };
+ String[] eventNamesSVG11 = {
+ "DOMSubtreeModified", "DOMNodeInserted", "DOMNodeRemoved",
+ "DOMNodeRemovedFromDocument", "DOMNodeInsertedIntoDocument",
+ "DOMAttrModified", "DOMCharacterDataModified", "SVGLoad",
+ "SVGUnload", "SVGAbort", "SVGError", "SVGResize", "SVGScroll",
+ "repeatEvent"
+ };
+ String[] eventNamesSVG12 = {
+ "load", "resize", "scroll", "zoom"
+ };
+ for (int i = 0; i < eventNamesCommon.length; i++) {
+ animationEventNames11.add(eventNamesCommon[i]);
+ animationEventNames12.add(eventNamesCommon[i]);
+ }
+ for (int i = 0; i < eventNamesSVG11.length; i++) {
+ animationEventNames11.add(eventNamesSVG11[i]);
+ }
+ for (int i = 0; i < eventNamesSVG12.length; i++) {
+ animationEventNames12.add(eventNamesSVG12[i]);
+ }
+ }
+
+ /**
+ * Creates a new SVGAnimationEngine.
+ */
+ public SVGAnimationEngine(Document doc, BridgeContext ctx) {
+ super(doc);
+ this.ctx = ctx;
+ SVGOMDocument d = (SVGOMDocument) doc;
+ cssEngine = d.getCSSEngine();
+ dummyStyleMap = new StyleMap(cssEngine.getNumberOfProperties());
+ isSVG12 = d.isSVG12();
+ }
+
+ /**
+ * Disposes this animation engine.
+ */
+ public void dispose() {
+ synchronized (this) {
+ pause();
+ super.dispose();
+ }
+ }
+
+ /**
+ * Adds an animation element bridge to the list of bridges that
+ * require initializing when the document is started.
+ */
+ public void addInitialBridge(SVGAnimationElementBridge b) {
+ if (initialBridges != null) {
+ initialBridges.add(b);
+ }
+ }
+
+ /**
+ * Returns whether animation processing has begun.
+ */
+ public boolean hasStarted() {
+ return started;
+ }
+
+ /**
+ * Parses an AnimatableValue.
+ */
+ public AnimatableValue parseAnimatableValue(Element animElt,
+ AnimationTarget target,
+ String ns, String ln,
+ boolean isCSS,
+ String s) {
+ SVGOMElement elt = (SVGOMElement) target.getElement();
+ int type;
+ if (isCSS) {
+ type = elt.getPropertyType(ln);
+ } else {
+ type = elt.getAttributeType(ns, ln);
+ }
+ Factory factory = factories[type];
+ if (factory == null) {
+ String an = ns == null ? ln : '{' + ns + '}' + ln;
+ throw new BridgeException
+ (ctx, animElt, "attribute.not.animatable",
+ new Object[] { target.getElement().getNodeName(), an });
+ }
+ return factories[type].createValue(target, ns, ln, isCSS, s);
+ }
+
+ /**
+ * Returns an AnimatableValue for the underlying value of a CSS property.
+ */
+ public AnimatableValue getUnderlyingCSSValue(Element animElt,
+ AnimationTarget target,
+ String pn) {
+ ValueManager[] vms = cssEngine.getValueManagers();
+ int idx = cssEngine.getPropertyIndex(pn);
+ if (idx != -1) {
+ int type = vms[idx].getPropertyType();
+ Factory factory = factories[type];
+ if (factory == null) {
+ throw new BridgeException
+ (ctx, animElt, "attribute.not.animatable",
+ new Object[] { target.getElement().getNodeName(), pn });
+ }
+ 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 && !oldValue.equals("")) {
+ over.setProperty(pn, oldValue, null);
+ }
+ return factories[type].createValue(target, pn, v);
+ }
+ // XXX Doesn't handle shorthands.
+ return null;
+ }
+
+ /**
+ * Pauses the animations.
+ */
+ public void pause() {
+ super.pause();
+ UpdateManager um = ctx.getUpdateManager();
+ if (um != null) {
+ um.getUpdateRunnableQueue().setIdleRunnable(null);
+ }
+ }
+
+ /**
+ * Pauses the animations.
+ */
+ public void unpause() {
+ super.unpause();
+ UpdateManager um = ctx.getUpdateManager();
+ if (um != null) {
+ um.getUpdateRunnableQueue().setIdleRunnable(animationTickRunnable);
+ }
+ }
+
+ /**
+ * Returns the current document time.
+ */
+ public float getCurrentTime() {
+ boolean p = pauseTime != 0;
+ unpause();
+ float t = timedDocumentRoot.getCurrentTime();
+ if (p) {
+ pause();
+ }
+ return t;
+ }
+
+ /**
+ * Sets the current document time.
+ */
+ public float setCurrentTime(float t) {
+ float ret = super.setCurrentTime(t);
+ if (animationTickRunnable != null) {
+ animationTickRunnable.resume();
+ }
+ return ret;
+ }
+
+ /**
+ * Creates a new returns a new TimedDocumentRoot object for the document.
+ */
+ protected TimedDocumentRoot createDocumentRoot() {
+ return new AnimationRoot();
+ }
+
+ /**
+ * Starts the animation engine.
+ */
+ public void start(long documentStartTime) {
+ if (started) {
+ return;
+ }
+ started = true;
+ try {
+ try {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(new Date(documentStartTime));
+ timedDocumentRoot.resetDocument(cal);
+ Object[] bridges = initialBridges.toArray();
+ initialBridges = null;
+ for (int i = 0; i < bridges.length; i++) {
+ SVGAnimationElementBridge bridge =
+ (SVGAnimationElementBridge) bridges[i];
+ bridge.initializeAnimation();
+ }
+ for (int i = 0; i < bridges.length; i++) {
+ SVGAnimationElementBridge bridge =
+ (SVGAnimationElementBridge) bridges[i];
+ bridge.initializeTimedElement();
+ }
+ // tick(0, false);
+ // animationThread = new AnimationThread();
+ // animationThread.start();
+ UpdateManager um = ctx.getUpdateManager();
+ if (um != null) {
+ RunnableQueue q = um.getUpdateRunnableQueue();
+ animationTickRunnable = new AnimationTickRunnable(q, this);
+ q.setIdleRunnable(animationTickRunnable);
+ }
+ } catch (AnimationException ex) {
+ throw new BridgeException(ctx, ex.getElement().getElement(),
+ ex.getMessage());
+ }
+ } catch (Exception ex) {
+ if (ctx.getUserAgent() == null) {
+ ex.printStackTrace();
+ } else {
+ ctx.getUserAgent().displayError(ex);
+ }
+ }
+ }
+
+ /**
+ * Sets the animation limiting mode to "none".
+ */
+ public void setAnimationLimitingNone() {
+ animationLimitingMode = 0;
+ }
+
+ /**
+ * Sets the animation limiting mode to a percentage of CPU.
+ * @param pc the maximum percentage of CPU to use (0 < pc ≤ 1)
+ */
+ public void setAnimationLimitingCPU(float pc) {
+ animationLimitingMode = 1;
+ animationLimitingAmount = pc;
+ }
+
+ /**
+ * Sets the animation limiting mode to a number of frames per second.
+ * @param fps the maximum number of frames per second (fps > 0)
+ */
+ public void setAnimationLimitingFPS(float fps) {
+ animationLimitingMode = 2;
+ animationLimitingAmount = fps;
+ }
+
+ /**
+ * A class for the root time container.
+ */
+ protected class AnimationRoot extends TimedDocumentRoot {
+
+ /**
+ * Creates a new AnimationRoot object.
+ */
+ public AnimationRoot() {
+ super(!isSVG12, isSVG12);
+ }
+
+ /**
+ * Returns the namespace URI of the event that corresponds to the given
+ * animation event name.
+ */
+ protected String getEventNamespaceURI(String eventName) {
+ if (!isSVG12) {
+ return null;
+ }
+ if (eventName.equals("focusin")
+ || eventName.equals("focusout")
+ || eventName.equals("activate")
+ || animationEventNames12.contains(eventName)) {
+ return XMLConstants.XML_EVENTS_NAMESPACE_URI;
+ }
+ return null;
+ }
+
+ /**
+ * Returns the type of the event that corresponds to the given
+ * animation event name.
+ */
+ protected String getEventType(String eventName) {
+ if (eventName.equals("focusin")) {
+ return "DOMFocusIn";
+ } else if (eventName.equals("focusout")) {
+ return "DOMFocusOut";
+ } else if (eventName.equals("activate")) {
+ return "DOMActivate";
+ }
+ if (isSVG12) {
+ if (animationEventNames12.contains(eventName)) {
+ return eventName;
+ }
+ } else {
+ if (animationEventNames11.contains(eventName)) {
+ return eventName;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the name of the repeat event.
+ * @return "repeatEvent" for SVG
+ */
+ protected String getRepeatEventName() {
+ return SMILConstants.SMIL_REPEAT_EVENT_NAME;
+ }
+
+ /**
+ * Fires a TimeEvent of the given type on this element.
+ * @param eventType the type of TimeEvent ("beginEvent", "endEvent"
+ * or "repeatEvent"/"repeat").
+ * @param time the timestamp of the event object
+ */
+ protected void fireTimeEvent(String eventType, Calendar time,
+ int detail) {
+ AnimationSupport.fireTimeEvent
+ ((EventTarget) document, eventType, time, detail);
+ }
+
+ /**
+ * Invoked to indicate this timed element became active at the
+ * specified time.
+ * @param begin the time the element became active, in document simple time
+ */
+ protected void toActive(float begin) {
+ }
+
+ /**
+ * Invoked to indicate that this timed element became inactive.
+ * @param stillActive if true, indicates that the element is still
+ * actually active, but between the end of the
+ * computed repeat duration and the end of the
+ * interval
+ * @param isFrozen whether the element is frozen or not
+ */
+ protected void toInactive(boolean stillActive, boolean isFrozen) {
+ }
+
+ /**
+ * Invoked to indicate that this timed element has had its fill removed.
+ */
+ protected void removeFill() {
+ }
+
+ /**
+ * Invoked to indicate that this timed element has been sampled at the
+ * given time.
+ * @param simpleTime the sample time in local simple time
+ * @param simpleDur the simple duration of the element
+ * @param repeatIteration the repeat iteration during which the element
+ * was sampled
+ */
+ protected void sampledAt(float simpleTime, float simpleDur,
+ int repeatIteration) {
+ }
+
+ /**
+ * Invoked to indicate that this timed element has been sampled
+ * at the end of its active time, at an integer multiple of the
+ * simple duration. This is the "last" value that will be used
+ * for filling, which cannot be sampled normally.
+ */
+ protected void sampledLastValue(int repeatIteration) {
+ }
+
+ /**
+ * Returns the timed element with the given ID.
+ */
+ protected TimedElement getTimedElementById(String id) {
+ return AnimationSupport.getTimedElementById(id, document);
+ }
+
+ /**
+ * Returns the event target with the given ID.
+ */
+ protected EventTarget getEventTargetById(String id) {
+ return AnimationSupport.getEventTargetById(id, document);
+ }
+
+ /**
+ * Returns the target of this animation as an {@link EventTarget}. Used
+ * for eventbase timing specifiers where the element ID is omitted.
+ */
+ protected EventTarget getAnimationEventTarget() {
+ return null;
+ }
+
+ /**
+ * Returns the event target that should be listened to for
+ * access key events.
+ */
+ protected EventTarget getRootEventTarget() {
+ return (EventTarget) document;
+ }
+
+ /**
+ * Returns the DOM element that corresponds to this timed element, if
+ * such a DOM element exists.
+ */
+ public Element getElement() {
+ return null;
+ }
+
+ /**
+ * Returns whether this timed element comes before the given timed
+ * element in document order.
+ */
+ public boolean isBefore(TimedElement other) {
+ return false;
+ }
+
+ /**
+ * Invoked by timed elements in this document to indicate that the
+ * current interval will be re-evaluated at the next sample.
+ */
+ protected void currentIntervalWillUpdate() {
+ if (animationTickRunnable != null) {
+ animationTickRunnable.resume();
+ }
+ }
+ }
+
+ /**
+ * Idle runnable to tick the animation, that reads times from System.in.
+ */
+ protected static class DebugAnimationTickRunnable extends AnimationTickRunnable {
+
+ float t = 0f;
+
+ public DebugAnimationTickRunnable(RunnableQueue q, SVGAnimationEngine eng) {
+ super(q, eng);
+ waitTime = Long.MAX_VALUE;
+ new Thread() {
+ public void run() {
+ java.io.BufferedReader r = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
+ System.out.println("Enter times.");
+ for (;;) {
+ String s;
+ try {
+ s = r.readLine();
+ } catch (java.io.IOException e) {
+ s = null;
+ }
+ if (s == null) {
+ System.exit(0);
+ }
+ t = Float.parseFloat(s);
+ DebugAnimationTickRunnable.this.resume();
+ }
+ }
+ }.start();
+ }
+
+ public void resume() {
+ waitTime = 0;
+ Object lock = q.getIteratorLock();
+ synchronized (lock) {
+ lock.notify();
+ }
+ }
+
+ public long getWaitTime() {
+ long wt = waitTime;
+ waitTime = Long.MAX_VALUE;
+ return wt;
+ }
+
+ public void run() {
+ SVGAnimationEngine eng = getAnimationEngine();
+ synchronized (eng) {
+ try {
+ try {
+ eng.tick(t, false);
+ } catch (AnimationException ex) {
+ throw new BridgeException
+ (eng.ctx, ex.getElement().getElement(),
+ ex.getMessage());
+ }
+ } catch (Exception ex) {
+ if (eng.ctx.getUserAgent() == null) {
+ ex.printStackTrace();
+ } else {
+ eng.ctx.getUserAgent().displayError(ex);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Idle runnable to tick the animation.
+ */
+ protected static class AnimationTickRunnable
+ implements RunnableQueue.IdleRunnable {
+
+ /**
+ * Calendar instance used for passing current time values to the
+ * animation timing system.
+ */
+ protected Calendar time = Calendar.getInstance();
+
+// /**
+// * The current document time in seconds, truncated.
+// */
+// protected double second = -1.;
+
+// /**
+// * The number of frames that have been ticked so far this second.
+// */
+// protected int frames;
+
+ /**
+ * The number of milliseconds to wait until the next animation tick.
+ * This is returned by {@link #getWaitTime()}.
+ */
+ protected long waitTime;
+
+ /**
+ * The RunnableQueue in which this is the
+ * {@link RunnableQueue.IdleRunnable}.
+ */
+ protected RunnableQueue q;
+
+ /**
+ * The number of past tick times to keep, for computing the average
+ * time per tick.
+ */
+ private static final int NUM_TIMES = 8;
+
+ /**
+ * The past tick times.
+ */
+ protected long[] times = new long[NUM_TIMES];
+
+ /**
+ * The sum of the times in {@link #times}.
+ */
+ protected long sumTime;
+
+ /**
+ * The current index into {@link #times}.
+ */
+ protected int timeIndex;
+
+ /**
+ * A weak reference to the SVGAnimationEngine this AnimationTickRunnable
+ * is for. We make this a WeakReference so that a ticking animation
+ * engine does not prevent from being GCed.
+ */
+ protected WeakReference engRef;
+
+ /**
+ * The maximum number of consecutive exceptions to allow before
+ * stopping the report of them.
+ */
+ protected static final int MAX_EXCEPTION_COUNT = 10;
+
+ /**
+ * The number of consecutive exceptions that have been thrown. This is
+ * used to detect when exceptions are occurring every tick, and to stop
+ * reporting them when this happens.
+ */
+ protected int exceptionCount;
+
+ /**
+ * Creates a new AnimationTickRunnable.
+ */
+ public AnimationTickRunnable(RunnableQueue q, SVGAnimationEngine eng) {
+ this.q = q;
+ this.engRef = new WeakReference(eng);
+ // Initialize the past times to 100ms.
+ Arrays.fill(times, 100);
+ sumTime = 100 * NUM_TIMES;
+ }
+
+ /**
+ * Forces an animation update, if the {@link RunnableQueue} is
+ * currently waiting.
+ */
+ public void resume() {
+ waitTime = 0;
+ Object lock = q.getIteratorLock();
+ synchronized (lock) {
+ lock.notify();
+ }
+ }
+
+ /**
+ * Returns the system time that can be safely waited until before this
+ * {@link Runnable} is run again.
+ *
+ * @return time to wait until, <code>0</code> if no waiting can
+ * be done, or {@link Long#MAX_VALUE} if the {@link Runnable}
+ * should not be run again at this time
+ */
+ public long getWaitTime() {
+ return waitTime;
+ }
+
+ /**
+ * Performs one tick of the animation.
+ */
+ public void run() {
+ SVGAnimationEngine eng = getAnimationEngine();
+ synchronized (eng) {
+ int animationLimitingMode = eng.animationLimitingMode;
+ float animationLimitingAmount = eng.animationLimitingAmount;
+ try {
+ try {
+ long before = System.currentTimeMillis();
+ time.setTime(new Date(before));
+ float t = eng.timedDocumentRoot.convertWallclockTime(time);
+// if (Math.floor(t) > second) {
+// second = Math.floor(t);
+// System.err.println("fps: " + frames);
+// frames = 0;
+// }
+ float t2 = eng.tick(t, false);
+ long after = System.currentTimeMillis();
+ long dur = after - before;
+ if (dur == 0) {
+ dur = 1;
+ }
+ sumTime -= times[timeIndex];
+ sumTime += dur;
+ times[timeIndex] = dur;
+ timeIndex = (timeIndex + 1) % NUM_TIMES;
+
+ if (t2 == Float.POSITIVE_INFINITY) {
+ waitTime = Long.MAX_VALUE;
+ } else {
+ waitTime = before + (long) (t2 * 1000) - 1000;
+ if (waitTime < after) {
+ waitTime = after;
+ }
+ if (animationLimitingMode != 0) {
+ float ave = (float) sumTime / NUM_TIMES;
+ float delay;
+ if (animationLimitingMode == 1) {
+ // %cpu
+ delay = ave / animationLimitingAmount - ave;
+ } else {
+ // fps
+ delay = 1000f / animationLimitingAmount - ave;
+ }
+ long newWaitTime = after + (long) delay;
+ if (newWaitTime > waitTime) {
+ waitTime = newWaitTime;
+ }
+ }
+ }
+// frames++;
+ } catch (AnimationException ex) {
+ throw new BridgeException
+ (eng.ctx, ex.getElement().getElement(),
+ ex.getMessage());
+ }
+ exceptionCount = 0;
+ } catch (Exception ex) {
+ if (++exceptionCount < MAX_EXCEPTION_COUNT) {
+ if (eng.ctx.getUserAgent() == null) {
+ ex.printStackTrace();
+ } else {
+ eng.ctx.getUserAgent().displayError(ex);
+ }
+ }
+ }
+
+ if (animationLimitingMode == 0) {
+ // so we don't steal too much time from the Swing thread
+ try {
+ Thread.sleep(1);
+ } catch (InterruptedException ie) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the SVGAnimationEngine this AnimationTickRunnable is for.
+ */
+ protected SVGAnimationEngine getAnimationEngine() {
+ return (SVGAnimationEngine) engRef.get();
+ }
+ }
+
+ /**
+ * The thread that ticks the animation.
+ */
+ protected class AnimationThread extends Thread {
+
+ /**
+ * The current time.
+ */
+ protected Calendar time = Calendar.getInstance();
+
+ /**
+ * The RunnableQueue to perform the animation in.
+ */
+ protected RunnableQueue runnableQueue =
+ ctx.getUpdateManager().getUpdateRunnableQueue();
+
+ /**
+ * The animation ticker Runnable.
+ */
+ protected Ticker ticker = new Ticker();
+
+ /**
+ * Ticks the animation over as fast as possible.
+ */
+ public void run() {
+ if (true) {
+ for (;;) {
+ time.setTime(new Date());
+ ticker.t = timedDocumentRoot.convertWallclockTime(time);
+ try {
+ runnableQueue.invokeAndWait(ticker);
+ } catch (InterruptedException e) {
+ return;
+ }
+ }
+ } else {
+ ticker.t = 1;
+ while (ticker.t < 10) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ie) {
+ }
+ try {
+ runnableQueue.invokeAndWait(ticker);
+ } catch (InterruptedException e) {
+ return;
+ }
+ ticker.t++;
+ }
+ }
+ }
+
+ /**
+ * A runnable that ticks the animation engine.
+ */
+ protected class Ticker implements Runnable {
+
+ /**
+ * The document time to tick at next.
+ */
+ protected float t;
+
+ /**
+ * Ticks the animation over.
+ */
+ public void run() {
+ tick(t, false);
+ }
+ }
+ }
+
+ // AnimatableValue factories
+
+ /**
+ * Interface for AnimatableValue factories.
+ */
+ protected interface Factory {
+
+ /**
+ * Creates a new AnimatableValue from a string.
+ */
+ AnimatableValue createValue(AnimationTarget target, String ns,
+ String ln, boolean isCSS, String s);
+
+ /**
+ * Creates a new AnimatableValue from a CSS {@link Value}.
+ */
+ AnimatableValue createValue(AnimationTarget target, String pn, Value v);
+ }
+
+ /**
+ * Factory class for AnimatableValues for CSS properties.
+ * XXX Shorthand properties are not supported.
+ */
+ protected abstract class CSSValueFactory implements Factory {
+
+ public AnimatableValue createValue(AnimationTarget target, String ns,
+ String ln, boolean isCSS, String s) {
+ // XXX Always parsing as a CSS value.
+ return createValue(target, ln, createCSSValue(target, ln, s));
+ }
+
+ public AnimatableValue createValue(AnimationTarget target, String pn,
+ Value v) {
+ CSSStylableElement elt = (CSSStylableElement) target.getElement();
+ v = computeValue(elt, pn, v);
+ return createAnimatableValue(target, pn, v);
+ }
+
+ /**
+ * Creates a new AnimatableValue from a CSS {@link Value}, after
+ * computation and inheritance.
+ */
+ protected abstract AnimatableValue createAnimatableValue
+ (AnimationTarget target, String pn, Value v);
+
+ /**
+ * Creates a new CSS {@link Value} from a string.
+ */
+ protected Value createCSSValue(AnimationTarget t, String pn, String s) {
+ CSSStylableElement elt = (CSSStylableElement) t.getElement();
+ Value v = cssEngine.parsePropertyValue(elt, pn, s);
+ return computeValue(elt, pn, v);
+ }
+
+ /**
+ * Computes a CSS {@link Value} and performance inheritance if the
+ * specified value is 'inherit'.
+ */
+ protected Value computeValue(CSSStylableElement elt, String pn,
+ Value v) {
+ ValueManager[] vms = cssEngine.getValueManagers();
+ int idx = cssEngine.getPropertyIndex(pn);
+ if (idx != -1) {
+ if (v.getCssValueType() == CSSValue.CSS_INHERIT) {
+ elt = CSSEngine.getParentCSSStylableElement(elt);
+ if (elt != null) {
+ return cssEngine.getComputedStyle(elt, null, idx);
+ }
+ return vms[idx].getDefaultValue();
+ }
+ v = vms[idx].computeValue(elt, null, cssEngine, idx,
+ dummyStyleMap, v);
+ }
+ return v;
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatableBooleanValue}s.
+ */
+ protected class AnimatableBooleanValueFactory implements Factory {
+
+ /**
+ * Creates a new AnimatableValue from a string.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String ns,
+ String ln, boolean isCSS, String s) {
+ return new AnimatableBooleanValue(target, "true".equals(s));
+ }
+
+ /**
+ * Creates a new AnimatableValue from a CSS {@link Value}.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String pn,
+ Value v) {
+ return new AnimatableBooleanValue(target,
+ "true".equals(v.getCssText()));
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatableIntegerValue}s.
+ */
+ protected class AnimatableIntegerValueFactory implements Factory {
+
+ /**
+ * Creates a new AnimatableValue from a string.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String ns,
+ String ln, boolean isCSS, String s) {
+ return new AnimatableIntegerValue(target, Integer.parseInt(s));
+ }
+
+ /**
+ * Creates a new AnimatableValue from a CSS {@link Value}.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String pn,
+ Value v) {
+ return new AnimatableIntegerValue(target,
+ Math.round(v.getFloatValue()));
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatableNumberValue}s.
+ */
+ protected class AnimatableNumberValueFactory implements Factory {
+
+ /**
+ * Creates a new AnimatableValue from a string.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String ns,
+ String ln, boolean isCSS, String s) {
+ return new AnimatableNumberValue(target, Float.parseFloat(s));
+ }
+
+ /**
+ * Creates a new AnimatableValue from a CSS {@link Value}.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String pn,
+ Value v) {
+ return new AnimatableNumberValue(target, v.getFloatValue());
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatableNumberOrPercentageValue}s.
+ */
+ protected class AnimatableNumberOrPercentageValueFactory
+ implements Factory {
+
+ /**
+ * Creates a new AnimatableValue from a string.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String ns,
+ String ln, boolean isCSS, String s) {
+ float v;
+ boolean pc;
+ if (s.charAt(s.length() - 1) == '%') {
+ v = Float.parseFloat(s.substring(0, s.length() - 1));
+ pc = true;
+ } else {
+ v = Float.parseFloat(s);
+ pc = false;
+ }
+ return new AnimatableNumberOrPercentageValue(target, v, pc);
+ }
+
+ /**
+ * Creates a new AnimatableValue from a CSS {@link Value}.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String pn,
+ Value v) {
+ switch (v.getPrimitiveType()) {
+ case CSSPrimitiveValue.CSS_PERCENTAGE:
+ return new AnimatableNumberOrPercentageValue
+ (target, v.getFloatValue(), true);
+ case CSSPrimitiveValue.CSS_NUMBER:
+ return new AnimatableNumberOrPercentageValue
+ (target, v.getFloatValue());
+ }
+ // XXX Do something better than returning null.
+ return null;
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatablePreserveAspectRatioValue}s.
+ */
+ protected class AnimatablePreserveAspectRatioValueFactory implements Factory {
+
+ /**
+ * The parsed 'align' value.
+ */
+ protected short align;
+
+ /**
+ * The parsed 'meetOrSlice' value.
+ */
+ protected short meetOrSlice;
+
+ /**
+ * Parser for preserveAspectRatio values.
+ */
+ protected PreserveAspectRatioParser parser =
+ new PreserveAspectRatioParser();
+
+ /**
+ * Handler for the preserveAspectRatio parser.
+ */
+ protected DefaultPreserveAspectRatioHandler handler =
+ new DefaultPreserveAspectRatioHandler() {
+
+ /**
+ * Implements {@link
+ * PreserveAspectRatioHandler#startPreserveAspectRatio()}.
+ */
+ public void startPreserveAspectRatio() throws ParseException {
+ align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_UNKNOWN;
+ meetOrSlice = SVGPreserveAspectRatio.SVG_MEETORSLICE_UNKNOWN;
+ }
+
+ /**
+ * Implements {@link PreserveAspectRatioHandler#none()}.
+ */
+ public void none() throws ParseException {
+ align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE;
+ }
+
+ /**
+ * Implements {@link PreserveAspectRatioHandler#xMaxYMax()}.
+ */
+ public void xMaxYMax() throws ParseException {
+ align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMAX;
+ }
+
+ /**
+ * Implements {@link PreserveAspectRatioHandler#xMaxYMid()}.
+ */
+ public void xMaxYMid() throws ParseException {
+ align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMID;
+ }
+
+ /**
+ * Implements {@link PreserveAspectRatioHandler#xMaxYMin()}.
+ */
+ public void xMaxYMin() throws ParseException {
+ align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMIN;
+ }
+
+ /**
+ * Implements {@link PreserveAspectRatioHandler#xMidYMax()}.
+ */
+ public void xMidYMax() throws ParseException {
+ align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMAX;
+ }
+
+ /**
+ * Implements {@link PreserveAspectRatioHandler#xMidYMid()}.
+ */
+ public void xMidYMid() throws ParseException {
+ align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMID;
+ }
+
+ /**
+ * Implements {@link PreserveAspectRatioHandler#xMidYMin()}.
+ */
+ public void xMidYMin() throws ParseException {
+ align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMIN;
+ }
+
+ /**
+ * Implements {@link PreserveAspectRatioHandler#xMinYMax()}.
+ */
+ public void xMinYMax() throws ParseException {
+ align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMAX;
+ }
+
+ /**
+ * Implements {@link PreserveAspectRatioHandler#xMinYMid()}.
+ */
+ public void xMinYMid() throws ParseException {
+ align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMID;
+ }
+
+ /**
+ * Implements {@link PreserveAspectRatioHandler#xMinYMin()}.
+ */
+ public void xMinYMin() throws ParseException {
+ align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMIN;
+ }
+
+ /**
+ * Implements {@link PreserveAspectRatioHandler#meet()}.
+ */
+ public void meet() throws ParseException {
+ meetOrSlice = SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET;
+ }
+
+ /**
+ * Implements {@link PreserveAspectRatioHandler#slice()}.
+ */
+ public void slice() throws ParseException {
+ meetOrSlice = SVGPreserveAspectRatio.SVG_MEETORSLICE_SLICE;
+ }
+ };
+
+ /**
+ * Creates a new AnimatablePreserveAspectRatioValueFactory.
+ */
+ public AnimatablePreserveAspectRatioValueFactory() {
+ parser.setPreserveAspectRatioHandler(handler);
+ }
+
+ /**
+ * Creates a new AnimatableValue from a string.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String ns,
+ String ln, boolean isCSS, String s) {
+ try {
+ parser.parse(s);
+ return new AnimatablePreserveAspectRatioValue(target, align,
+ meetOrSlice);
+ } catch (ParseException e) {
+ // XXX Do something better than returning null.
+ return null;
+ }
+ }
+
+ /**
+ * Creates a new AnimatableValue from a CSS {@link Value}. Returns null
+ * since preserveAspectRatio values aren't used in CSS values.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String pn,
+ Value v) {
+ return null;
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatableLengthValue}s.
+ */
+ protected class AnimatableLengthValueFactory implements Factory {
+
+ /**
+ * The parsed length unit type.
+ */
+ protected short type;
+
+ /**
+ * The parsed length value.
+ */
+ protected float value;
+
+ /**
+ * Parser for lengths.
+ */
+ protected LengthParser parser = new LengthParser();
+
+ /**
+ * Handler for the length parser.
+ */
+ protected LengthHandler handler = new DefaultLengthHandler() {
+ public void startLength() throws ParseException {
+ type = SVGLength.SVG_LENGTHTYPE_NUMBER;
+ }
+ public void lengthValue(float v) throws ParseException {
+ value = v;
+ }
+ public void em() throws ParseException {
+ type = SVGLength.SVG_LENGTHTYPE_EMS;
+ }
+ public void ex() throws ParseException {
+ type = SVGLength.SVG_LENGTHTYPE_EXS;
+ }
+ public void in() throws ParseException {
+ type = SVGLength.SVG_LENGTHTYPE_IN;
+ }
+ public void cm() throws ParseException {
+ type = SVGLength.SVG_LENGTHTYPE_CM;
+ }
+ public void mm() throws ParseException {
+ type = SVGLength.SVG_LENGTHTYPE_MM;
+ }
+ public void pc() throws ParseException {
+ type = SVGLength.SVG_LENGTHTYPE_PC;
+ }
+ public void pt() throws ParseException {
+ type = SVGLength.SVG_LENGTHTYPE_PT;
+ }
+ public void px() throws ParseException {
+ type = SVGLength.SVG_LENGTHTYPE_PX;
+ }
+ public void percentage() throws ParseException {
+ type = SVGLength.SVG_LENGTHTYPE_PERCENTAGE;
+ }
+ public void endLength() throws ParseException {
+ }
+ };
+
+ /**
+ * Creates a new AnimatableLengthValueFactory.
+ */
+ public AnimatableLengthValueFactory() {
+ parser.setLengthHandler(handler);
+ }
+
+ /**
+ * Creates a new AnimatableValue from a string.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String ns,
+ String ln, boolean isCSS, String s) {
+ short pcInterp = target.getPercentageInterpretation(ns, ln, isCSS);
+ try {
+ parser.parse(s);
+ return new AnimatableLengthValue
+ (target, type, value, pcInterp);
+ } catch (ParseException e) {
+ // XXX Do something better than returning null.
+ return null;
+ }
+ }
+
+ /**
+ * Creates a new AnimatableValue from a CSS {@link Value}.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String pn,
+ Value v) {
+ return new AnimatableIntegerValue(target,
+ Math.round(v.getFloatValue()));
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatableLengthListValue}s.
+ */
+ protected class AnimatableLengthListValueFactory implements Factory {
+
+ /**
+ * Parser for length lists.
+ */
+ protected LengthListParser parser = new LengthListParser();
+
+ /**
+ * The producer class that accumulates the lengths.
+ */
+ protected LengthArrayProducer producer = new LengthArrayProducer();
+
+ /**
+ * Creates a new AnimatableLengthListValueFactory.
+ */
+ public AnimatableLengthListValueFactory() {
+ parser.setLengthListHandler(producer);
+ }
+
+ /**
+ * Creates a new AnimatableValue from a string.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String ns,
+ String ln, boolean isCSS, String s) {
+ try {
+ short pcInterp = target.getPercentageInterpretation
+ (ns, ln, isCSS);
+ parser.parse(s);
+ return new AnimatableLengthListValue
+ (target, producer.getLengthTypeArray(),
+ producer.getLengthValueArray(),
+ pcInterp);
+ } catch (ParseException e) {
+ // XXX Do something better than returning null.
+ return null;
+ }
+ }
+
+ /**
+ * Creates a new AnimatableValue from a CSS {@link Value}. Returns null
+ * since point lists aren't used in CSS values.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String pn,
+ Value v) {
+ return null;
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatableNumberListValue}s.
+ */
+ protected class AnimatableNumberListValueFactory implements Factory {
+
+ /**
+ * Parser for number lists.
+ */
+ protected NumberListParser parser = new NumberListParser();
+
+ /**
+ * The producer class that accumulates the numbers.
+ */
+ protected FloatArrayProducer producer = new FloatArrayProducer();
+
+ /**
+ * Creates a new AnimatableNumberListValueFactory.
+ */
+ public AnimatableNumberListValueFactory() {
+ parser.setNumberListHandler(producer);
+ }
+
+ /**
+ * Creates a new AnimatableValue from a string.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String ns,
+ String ln, boolean isCSS, String s) {
+ try {
+ parser.parse(s);
+ return new AnimatableNumberListValue(target,
+ producer.getFloatArray());
+ } catch (ParseException e) {
+ // XXX Do something better than returning null.
+ return null;
+ }
+ }
+
+ /**
+ * Creates a new AnimatableValue from a CSS {@link Value}. Returns null
+ * since number lists aren't used in CSS values.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String pn,
+ Value v) {
+ return null;
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatableNumberListValue}s.
+ */
+ protected class AnimatableRectValueFactory implements Factory {
+
+ /**
+ * Parser for number lists.
+ */
+ protected NumberListParser parser = new NumberListParser();
+
+ /**
+ * The producer class that accumulates the numbers.
+ */
+ protected FloatArrayProducer producer = new FloatArrayProducer();
+
+ /**
+ * Creates a new AnimatableNumberListValueFactory.
+ */
+ public AnimatableRectValueFactory() {
+ parser.setNumberListHandler(producer);
+ }
+
+ /**
+ * Creates a new AnimatableValue from a string.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String ns,
+ String ln, boolean isCSS, String s) {
+ try {
+ parser.parse(s);
+ float[] r = producer.getFloatArray();
+ if (r.length != 4) {
+ // XXX Do something better than returning null.
+ return null;
+ }
+ return new AnimatableRectValue(target, r[0], r[1], r[2], r[3]);
+ } catch (ParseException e) {
+ // XXX Do something better than returning null.
+ return null;
+ }
+ }
+
+ /**
+ * Creates a new AnimatableValue from a CSS {@link Value}. Returns null
+ * since rects aren't used in CSS values.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String pn,
+ Value v) {
+ return null;
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatablePointListValue}s.
+ */
+ protected class AnimatablePointListValueFactory implements Factory {
+
+ /**
+ * Parser for point lists.
+ */
+ protected PointsParser parser = new PointsParser();
+
+ /**
+ * The producer class that accumulates the points.
+ */
+ protected FloatArrayProducer producer = new FloatArrayProducer();
+
+ /**
+ * Creates a new AnimatablePointListValueFactory.
+ */
+ public AnimatablePointListValueFactory() {
+ parser.setPointsHandler(producer);
+ }
+
+ /**
+ * Creates a new AnimatableValue from a string.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String ns,
+ String ln, boolean isCSS, String s) {
+ try {
+ parser.parse(s);
+ return new AnimatablePointListValue(target,
+ producer.getFloatArray());
+ } catch (ParseException e) {
+ // XXX Do something better than returning null.
+ return null;
+ }
+ }
+
+ /**
+ * Creates a new AnimatableValue from a CSS {@link Value}. Returns null
+ * since point lists aren't used in CSS values.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String pn,
+ Value v) {
+ return null;
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatablePathDataValue}s.
+ */
+ protected class AnimatablePathDataFactory implements Factory {
+
+ /**
+ * Parser for path data.
+ */
+ protected PathParser parser = new PathParser();
+
+ /**
+ * The producer class that accumulates the path segments.
+ */
+ protected PathArrayProducer producer = new PathArrayProducer();
+
+ /**
+ * Creates a new AnimatablePathDataFactory.
+ */
+ public AnimatablePathDataFactory() {
+ parser.setPathHandler(producer);
+ }
+
+ /**
+ * Creates a new AnimatableValue from a string.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String ns,
+ String ln, boolean isCSS, String s) {
+ try {
+ parser.parse(s);
+ return new AnimatablePathDataValue
+ (target, producer.getPathCommands(),
+ producer.getPathParameters());
+ } catch (ParseException e) {
+ // XXX Do something better than returning null.
+ return null;
+ }
+ }
+
+ /**
+ * Creates a new AnimatableValue from a CSS {@link Value}. Returns null
+ * since point lists aren't used in CSS values.
+ */
+ public AnimatableValue createValue(AnimationTarget target, String pn,
+ Value v) {
+ return null;
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatableStringValue}s.
+ */
+ protected class UncomputedAnimatableStringValueFactory implements Factory {
+
+ public AnimatableValue createValue(AnimationTarget target, String ns,
+ String ln, boolean isCSS, String s) {
+ return new AnimatableStringValue(target, s);
+ }
+
+ public AnimatableValue createValue(AnimationTarget target, String pn,
+ Value v) {
+ return new AnimatableStringValue(target, v.getCssText());
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatableLengthOrIdentValue}s.
+ */
+ protected class AnimatableLengthOrIdentFactory extends CSSValueFactory {
+
+ protected AnimatableValue createAnimatableValue(AnimationTarget target,
+ String pn, Value v) {
+ if (v instanceof StringValue) {
+ return new AnimatableLengthOrIdentValue(target,
+ v.getStringValue());
+ }
+ short pcInterp = target.getPercentageInterpretation(null, pn, true);
+ FloatValue fv = (FloatValue) v;
+ return new AnimatableLengthOrIdentValue
+ (target, fv.getPrimitiveType(), fv.getFloatValue(), pcInterp);
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatableNumberOrIdentValue}s.
+ */
+ protected class AnimatableNumberOrIdentFactory extends CSSValueFactory {
+
+ /**
+ * Whether numbers are actually numeric keywords, as with the
+ * font-weight property.
+ */
+ protected boolean numericIdents;
+
+ public AnimatableNumberOrIdentFactory(boolean numericIdents) {
+ this.numericIdents = numericIdents;
+ }
+
+ protected AnimatableValue createAnimatableValue(AnimationTarget target,
+ String pn, Value v) {
+ if (v instanceof StringValue) {
+ return new AnimatableNumberOrIdentValue(target,
+ v.getStringValue());
+ }
+ FloatValue fv = (FloatValue) v;
+ return new AnimatableNumberOrIdentValue(target, fv.getFloatValue(),
+ numericIdents);
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatableAngleValue}s.
+ */
+ protected class AnimatableAngleValueFactory extends CSSValueFactory {
+
+ protected AnimatableValue createAnimatableValue(AnimationTarget target,
+ String pn, Value v) {
+ FloatValue fv = (FloatValue) v;
+ short unit;
+ switch (fv.getPrimitiveType()) {
+ case CSSPrimitiveValue.CSS_NUMBER:
+ case CSSPrimitiveValue.CSS_DEG:
+ unit = SVGAngle.SVG_ANGLETYPE_DEG;
+ break;
+ case CSSPrimitiveValue.CSS_RAD:
+ unit = SVGAngle.SVG_ANGLETYPE_RAD;
+ break;
+ case CSSPrimitiveValue.CSS_GRAD:
+ unit = SVGAngle.SVG_ANGLETYPE_GRAD;
+ break;
+ default:
+ // XXX Do something better than returning null.
+ return null;
+ }
+ return new AnimatableAngleValue(target, fv.getFloatValue(), unit);
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatableAngleOrIdentValue}s.
+ */
+ protected class AnimatableAngleOrIdentFactory extends CSSValueFactory {
+
+ protected AnimatableValue createAnimatableValue(AnimationTarget target,
+ String pn, Value v) {
+ if (v instanceof StringValue) {
+ return new AnimatableAngleOrIdentValue(target,
+ v.getStringValue());
+ }
+ FloatValue fv = (FloatValue) v;
+ short unit;
+ switch (fv.getPrimitiveType()) {
+ case CSSPrimitiveValue.CSS_NUMBER:
+ case CSSPrimitiveValue.CSS_DEG:
+ unit = SVGAngle.SVG_ANGLETYPE_DEG;
+ break;
+ case CSSPrimitiveValue.CSS_RAD:
+ unit = SVGAngle.SVG_ANGLETYPE_RAD;
+ break;
+ case CSSPrimitiveValue.CSS_GRAD:
+ unit = SVGAngle.SVG_ANGLETYPE_GRAD;
+ break;
+ default:
+ // XXX Do something better than returning null.
+ return null;
+ }
+ return new AnimatableAngleOrIdentValue(target, fv.getFloatValue(),
+ unit);
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatableColorValue}s.
+ */
+ protected class AnimatableColorValueFactory extends CSSValueFactory {
+
+ protected AnimatableValue createAnimatableValue(AnimationTarget target,
+ String pn, Value v) {
+ Paint p = PaintServer.convertPaint
+ (target.getElement(), null, v, 1.0f, ctx);
+ if (p instanceof Color) {
+ Color c = (Color) p;
+ return new AnimatableColorValue(target,
+ c.getRed() / 255f,
+ c.getGreen() / 255f,
+ c.getBlue() / 255f);
+ }
+ // XXX Indicate that the parsed value wasn't a Color?
+ return null;
+ }
+ }
+
+ /**
+ * Factory class for {@link AnimatablePaintValue}s.
+ */
+ protected class AnimatablePaintValueFactory extends CSSValueFactory {
+
+ /**
+ * Creates a new {@link AnimatablePaintValue} from a {@link Color}
+ * object.
+ */
+ protected AnimatablePaintValue createColorPaintValue(AnimationTarget t,
+ Color c) {
+ return AnimatablePaintValue.createColorPaintValue
+ (t, c.getRed() / 255f, c.getGreen() / 255f, c.getBlue() / 255f);
+
+ }
+
+ protected AnimatableValue createAnimatableValue(AnimationTarget target,
+ String pn, Value v) {
+ if (v.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ switch (v.getPrimitiveType()) {
+ case CSSPrimitiveValue.CSS_IDENT:
+ return AnimatablePaintValue.createNonePaintValue(target);
+ case CSSPrimitiveValue.CSS_RGBCOLOR: {
+ Paint p = PaintServer.convertPaint
+ (target.getElement(), null, v, 1.0f, ctx);
+ return createColorPaintValue(target, (Color) p);
+ }
+ case CSSPrimitiveValue.CSS_URI:
+ return AnimatablePaintValue.createURIPaintValue
+ (target, v.getStringValue());
+ }
+ } else {
+ Value v1 = v.item(0);
+ switch (v1.getPrimitiveType()) {
+ case CSSPrimitiveValue.CSS_RGBCOLOR: {
+ Paint p = PaintServer.convertPaint
+ (target.getElement(), null, v, 1.0f, ctx);
+ return createColorPaintValue(target, (Color) p);
+ }
+ case CSSPrimitiveValue.CSS_URI: {
+ Value v2 = v.item(1);
+ switch (v2.getPrimitiveType()) {
+ case CSSPrimitiveValue.CSS_IDENT:
+ return AnimatablePaintValue.createURINonePaintValue
+ (target, v1.getStringValue());
+ case CSSPrimitiveValue.CSS_RGBCOLOR: {
+ Paint p = PaintServer.convertPaint
+ (target.getElement(), null, v.item(1), 1.0f, ctx);
+ return createColorPaintValue(target, (Color) p);
+ }
+ }
+ }
+ }
+ }
+ // XXX Indicate that the specified Value wasn't a Color?
+ return null;
+ }
+ }
+
+ /**
+ * Factory class for computed CSS {@link AnimatableStringValue}s.
+ */
+ protected class AnimatableStringValueFactory extends CSSValueFactory {
+
+ protected AnimatableValue createAnimatableValue(AnimationTarget target,
+ String pn, Value v) {
+ return new AnimatableStringValue(target, v.getCssText());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/f690ea2f/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGBridgeExtension.java
----------------------------------------------------------------------
diff --git a/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGBridgeExtension.java b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGBridgeExtension.java
index 3d00998..b1683e3 100644
--- a/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGBridgeExtension.java
+++ b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGBridgeExtension.java
@@ -1,10 +1,11 @@
/*
- Copyright 2001-2002,2004-2005 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
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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
@@ -26,6 +27,9 @@ import org.w3c.dom.Element;
/**
* This is a Service interface for classes that want to extend the
* functionality of the Bridge, to support new tags in the rendering tree.
+ *
+ * @author <a href="mailto:thomas.deweese@kodak.com">Thomas DeWeese</a>
+ * @version $Id: SVGBridgeExtension.java 475477 2006-11-15 22:44:28Z cam $
*/
public class SVGBridgeExtension implements BridgeExtension {
@@ -147,7 +151,11 @@ public class SVGBridgeExtension implements BridgeExtension {
ctx.putBridge(new SVGTitleElementBridge());
ctx.putBridge(new SVGUseElementBridge());
ctx.putBridge(new SVGVKernElementBridge());
-
+ ctx.putBridge(new SVGSetElementBridge());
+ ctx.putBridge(new SVGAnimateElementBridge());
+ ctx.putBridge(new SVGAnimateColorElementBridge());
+ ctx.putBridge(new SVGAnimateTransformElementBridge());
+ ctx.putBridge(new SVGAnimateMotionElementBridge());
}
/**
@@ -165,7 +173,7 @@ public class SVGBridgeExtension implements BridgeExtension {
String ln = e.getLocalName();
if (ln.equals(SVGConstants.SVG_SCRIPT_TAG)
|| ln.startsWith("animate")
- || ln.equals("set")) {
+ || ln.equals(SVGConstants.SVG_SET_TAG)) {
return true;
}
return false;
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/f690ea2f/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGBrokenLinkProvider.java
----------------------------------------------------------------------
diff --git a/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGBrokenLinkProvider.java b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGBrokenLinkProvider.java
index 27e1f94..1a1f318 100644
--- a/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGBrokenLinkProvider.java
+++ b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGBrokenLinkProvider.java
@@ -1,10 +1,11 @@
/*
- Copyright 2001-2003 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
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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
@@ -17,53 +18,27 @@
*/
package org.apache.flex.forks.batik.bridge;
-import java.net.URL;
import java.util.HashMap;
import java.util.Map;
-import org.apache.flex.forks.batik.dom.util.DOMUtilities;
import org.apache.flex.forks.batik.ext.awt.image.renderable.Filter;
import org.apache.flex.forks.batik.ext.awt.image.spi.DefaultBrokenLinkProvider;
-import org.apache.flex.forks.batik.gvt.GraphicsNode;
+import org.apache.flex.forks.batik.gvt.CompositeGraphicsNode;
import org.apache.flex.forks.batik.gvt.filter.GraphicsNodeRable8Bit;
-import org.apache.flex.forks.batik.util.SVGConstants;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.flex.forks.dom.svg.SVGDocument;
+
/**
* This interface is to be used to provide alternate ways of
* generating a placeholder image when the ImageTagRegistry
* fails to handle a given reference.
+ *
+ * @author <a href="mailto:thomas.deweese@kodak.com">Thomas DeWeese</a>
+ * @version $Id: SVGBrokenLinkProvider.java 475477 2006-11-15 22:44:28Z cam $
*/
public class SVGBrokenLinkProvider
extends DefaultBrokenLinkProvider
implements ErrorConstants {
- public final static String SVG_BROKEN_LINK_DOCUMENT_PROPERTY =
- "org.apache.flex.forks.batik.bridge.BrokenLinkDocument";
-
- UserAgent userAgent;
- DocumentLoader loader;
- BridgeContext ctx;
- GraphicsNode gvtRoot = null;
- SVGDocument svgDoc;
-
public SVGBrokenLinkProvider() {
- userAgent = new UserAgentAdapter();
- loader = new DocumentLoader(userAgent);
- ctx = new BridgeContext(userAgent, loader);
-
- Class cls = SVGBrokenLinkProvider.class;
- URL blURL = cls.getResource("BrokenLink.svg");
- if (blURL == null) return;
-
- GVTBuilder builder = new GVTBuilder();
- try {
- svgDoc = (SVGDocument)loader.loadDocument(blURL.toString());
- gvtRoot = builder.build(ctx, svgDoc);
- } catch (Exception ex) {
- // t.printStackTrace();
- }
}
/**
@@ -81,38 +56,11 @@ public class SVGBrokenLinkProvider
* the circumstances of the failure. */
public Filter getBrokenLinkImage(Object base, String code,
Object[] params) {
- if (gvtRoot == null)
- return null;
-
String message = formatMessage(base, code, params);
- Document doc = getBrokenLinkDocument(message);
Map props = new HashMap();
props.put(BROKEN_LINK_PROPERTY, message);
- props.put(SVG_BROKEN_LINK_DOCUMENT_PROPERTY, doc);
-
- return new GraphicsNodeRable8Bit(gvtRoot, props);
- }
-
- public SVGDocument getBrokenLinkDocument(Object base,
- String code, Object [] params) {
- String message = formatMessage(base, code, params);
- return getBrokenLinkDocument(message);
- }
- public SVGDocument getBrokenLinkDocument(String message) {
- SVGDocument doc = (SVGDocument)DOMUtilities.deepCloneDocument
- (svgDoc, svgDoc.getImplementation());
- Element infoE = doc.getElementById("__More_About");
- Element title = doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI,
- SVGConstants.SVG_TITLE_TAG);
- title.appendChild(doc.createTextNode
- (Messages.formatMessage
- (MSG_BROKEN_LINK_TITLE, null)));
- Element desc = doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI,
- SVGConstants.SVG_DESC_TAG);
- desc.appendChild(doc.createTextNode(message));
- infoE.insertBefore(desc, infoE.getFirstChild());
- infoE.insertBefore(title, desc);
- return doc;
+ CompositeGraphicsNode cgn = new CompositeGraphicsNode();
+ return new GraphicsNodeRable8Bit(cgn, props);
}
}
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/f690ea2f/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGCircleElementBridge.java
----------------------------------------------------------------------
diff --git a/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGCircleElementBridge.java b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGCircleElementBridge.java
index e620f1c..0193610 100644
--- a/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGCircleElementBridge.java
+++ b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGCircleElementBridge.java
@@ -1,10 +1,11 @@
/*
- Copyright 2001-2003 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
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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
@@ -20,16 +21,20 @@ package org.apache.flex.forks.batik.bridge;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
+import org.apache.flex.forks.batik.dom.svg.AbstractSVGAnimatedLength;
+import org.apache.flex.forks.batik.dom.svg.AnimatedLiveAttributeValue;
+import org.apache.flex.forks.batik.dom.svg.LiveAttributeException;
+import org.apache.flex.forks.batik.dom.svg.SVGOMCircleElement;
import org.apache.flex.forks.batik.gvt.ShapeNode;
import org.apache.flex.forks.batik.gvt.ShapePainter;
+
import org.w3c.dom.Element;
-import org.w3c.dom.events.MutationEvent;
/**
* Bridge class for the <circle> element.
*
* @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a>
- * @version $Id: SVGCircleElementBridge.java,v 1.15 2004/08/18 07:12:33 vhardy Exp $
+ * @version $Id: SVGCircleElementBridge.java 527382 2007-04-11 04:31:58Z cam $
*/
public class SVGCircleElementBridge extends SVGShapeElementBridge {
@@ -62,57 +67,51 @@ public class SVGCircleElementBridge extends SVGShapeElementBridge {
protected void buildShape(BridgeContext ctx,
Element e,
ShapeNode shapeNode) {
- UnitProcessor.Context uctx = UnitProcessor.createContext(ctx, e);
- String s;
-
- // 'cx' attribute - default is 0
- s = e.getAttributeNS(null, SVG_CX_ATTRIBUTE);
- float cx = 0;
- if (s.length() != 0) {
- cx = UnitProcessor.svgHorizontalCoordinateToUserSpace
- (s, SVG_CX_ATTRIBUTE, uctx);
- }
-
- // 'cy' attribute - default is 0
- s = e.getAttributeNS(null, SVG_CY_ATTRIBUTE);
- float cy = 0;
- if (s.length() != 0) {
- cy = UnitProcessor.svgVerticalCoordinateToUserSpace
- (s, SVG_CY_ATTRIBUTE, uctx);
- }
-
- // 'r' attribute - required
- s = e.getAttributeNS(null, SVG_R_ATTRIBUTE);
- float r;
- if (s.length() != 0) {
- r = UnitProcessor.svgOtherLengthToUserSpace
- (s, SVG_R_ATTRIBUTE, uctx);
- } else {
- throw new BridgeException(e, ERR_ATTRIBUTE_MISSING,
- new Object[] {SVG_R_ATTRIBUTE, s});
+ try {
+ SVGOMCircleElement ce = (SVGOMCircleElement) e;
+
+ // 'cx' attribute - default is 0
+ AbstractSVGAnimatedLength _cx =
+ (AbstractSVGAnimatedLength) ce.getCx();
+ float cx = _cx.getCheckedValue();
+
+ // 'cy' attribute - default is 0
+ AbstractSVGAnimatedLength _cy =
+ (AbstractSVGAnimatedLength) ce.getCy();
+ float cy = _cy.getCheckedValue();
+
+ // 'r' attribute - required
+ AbstractSVGAnimatedLength _r =
+ (AbstractSVGAnimatedLength) ce.getR();
+ float r = _r.getCheckedValue();
+
+ float x = cx - r;
+ float y = cy - r;
+ float w = r * 2;
+ shapeNode.setShape(new Ellipse2D.Float(x, y, w, w));
+ } catch (LiveAttributeException ex) {
+ throw new BridgeException(ctx, ex);
}
- float x = cx - r;
- float y = cy - r;
- float w = r * 2;
- shapeNode.setShape(new Ellipse2D.Float(x, y, w, w));
}
// BridgeUpdateHandler implementation //////////////////////////////////
/**
- * Invoked when an MutationEvent of type 'DOMAttrModified' is fired.
+ * Invoked when the animated value of an animatable attribute has changed.
*/
- public void handleDOMAttrModifiedEvent(MutationEvent evt) {
- String attrName = evt.getAttrName();
- if (attrName.equals(SVG_CX_ATTRIBUTE) ||
- attrName.equals(SVG_CY_ATTRIBUTE) ||
- attrName.equals(SVG_R_ATTRIBUTE)) {
-
- buildShape(ctx, e, (ShapeNode)node);
- handleGeometryChanged();
- } else {
- super.handleDOMAttrModifiedEvent(evt);
+ public void handleAnimatedAttributeChanged
+ (AnimatedLiveAttributeValue alav) {
+ if (alav.getNamespaceURI() == null) {
+ String ln = alav.getLocalName();
+ if (ln.equals(SVG_CX_ATTRIBUTE)
+ || ln.equals(SVG_CY_ATTRIBUTE)
+ || ln.equals(SVG_R_ATTRIBUTE)) {
+ buildShape(ctx, e, (ShapeNode)node);
+ handleGeometryChanged();
+ return;
+ }
}
+ super.handleAnimatedAttributeChanged(alav);
}
protected ShapePainter createShapePainter(BridgeContext ctx,
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/f690ea2f/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGClipPathElementBridge.java
----------------------------------------------------------------------
diff --git a/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGClipPathElementBridge.java b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGClipPathElementBridge.java
index 06bc58f..4d77761 100644
--- a/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGClipPathElementBridge.java
+++ b/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/bridge/SVGClipPathElementBridge.java
@@ -1,10 +1,11 @@
/*
- Copyright 2001-2004 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
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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
@@ -23,8 +24,7 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
-import org.apache.flex.forks.batik.css.engine.CSSImportNode;
-import org.apache.flex.forks.batik.dom.svg.SVGOMCSSImportedElementRoot;
+import org.apache.flex.forks.batik.dom.svg.SVGOMUseElement;
import org.apache.flex.forks.batik.ext.awt.image.renderable.ClipRable;
import org.apache.flex.forks.batik.ext.awt.image.renderable.ClipRable8Bit;
import org.apache.flex.forks.batik.ext.awt.image.renderable.Filter;
@@ -37,10 +37,10 @@ import org.w3c.dom.Node;
* Bridge class for the <clipPath> element.
*
* @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a>
- * @version $Id: SVGClipPathElementBridge.java,v 1.23 2004/11/18 01:46:53 deweese Exp $
+ * @version $Id: SVGClipPathElementBridge.java 475477 2006-11-15 22:44:28Z cam $
*/
-public class SVGClipPathElementBridge extends AbstractSVGBridge
- implements ClipBridge {
+public class SVGClipPathElementBridge extends AnimatableGenericSVGBridge
+ implements ClipBridge {
/**
* Constructs a new bridge for the <clipPath> element.
@@ -74,7 +74,7 @@ public class SVGClipPathElementBridge extends AbstractSVGBridge
s = clipElement.getAttributeNS(null, SVG_TRANSFORM_ATTRIBUTE);
if (s.length() != 0) {
Tx = SVGUtilities.convertTransform
- (clipElement, SVG_TRANSFORM_ATTRIBUTE, s);
+ (clipElement, SVG_TRANSFORM_ATTRIBUTE, s, ctx);
} else {
Tx = new AffineTransform();
}
@@ -86,7 +86,7 @@ public class SVGClipPathElementBridge extends AbstractSVGBridge
coordSystemType = SVGUtilities.USER_SPACE_ON_USE;
} else {
coordSystemType = SVGUtilities.parseCoordinateSystem
- (clipElement, SVG_CLIP_PATH_UNITS_ATTRIBUTE, s);
+ (clipElement, SVG_CLIP_PATH_UNITS_ATTRIBUTE, s, ctx);
}
// additional transform to move to objectBoundingBox coordinate system
if (coordSystemType == SVGUtilities.OBJECT_BOUNDING_BOX) {
@@ -123,17 +123,13 @@ public class SVGClipPathElementBridge extends AbstractSVGBridge
hasChildren = true;
// if this is a 'use' element, get the actual shape used
- if (child instanceof CSSImportNode) {
- SVGOMCSSImportedElementRoot shadow =
- (SVGOMCSSImportedElementRoot)
- ((CSSImportNode) child).getCSSImportedElementRoot();
-
- if (shadow != null) {
- Node shadowChild = shadow.getFirstChild();
- if (shadowChild != null
- && shadowChild.getNodeType() == Node.ELEMENT_NODE) {
- child = (Element) shadowChild;
- }
+ if (child instanceof SVGOMUseElement) {
+ Node shadowChild
+ = ((SVGOMUseElement) child).getCSSFirstChild();
+
+ if (shadowChild != null
+ && shadowChild.getNodeType() == Node.ELEMENT_NODE) {
+ child = (Element) shadowChild;
}
}