Index: 3rdParty_sources/versions.txt =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/versions.txt,v diff -u -r1.8 -r1.9 --- 3rdParty_sources/versions.txt 15 Mar 2013 09:55:56 -0000 1.8 +++ 3rdParty_sources/versions.txt 8 Apr 2013 10:55:58 -0000 1.9 @@ -7,6 +7,8 @@ aspirin 0.8.03.201003071132 +batik 1.7.0 + CKEditor 3.6.2 Commons HttpClient 3.0 Index: 3rdParty_sources/batik/org/apache/batik/Version.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/Version.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/batik/org/apache/batik/Version.java 8 Apr 2013 10:55:58 -0000 1.1 @@ -0,0 +1,103 @@ +/* + + 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.batik; + +/** + * This class defines the Batik version number. + * + * @author Vincent Hardy + * @version $Id: Version.java,v 1.1 2013/04/08 10:55:58 marcin Exp $ + */ +public final class Version { + + /** + * Returns the Batik version. + *
+ * This is based on the Implementation-Version attribute in the + * batik-util.jar (which is where this Version class lives) and + * the 'HeadURL' SVN keyword. The keyword be substituted with + * the URL of this file, which is then inspected to determine if this + * file was compiled from the trunk, a tag (a release version), or a + * branch. The format of the returned string will be one of the + * following: + *
+ *Source | + *Version string | + *
---|---|
Release version | + *version | + *
Trunk | + *version+rrevision | + *
Branch | + *version+rrevision; branch-name | + *
Unknown | + *development version | + *
+ * Prior to release 1.7, the version string would
+ * be the straight tag (e.g. "batik-1_6"
) or the
+ * string "development.version"
. revision is the
+ * Subversion working copy's revision number.
+ *
ANIM_TYPE_*
constants defined in this class
+ * @param ns the namespace URI of the attribute being animated, if
+ * type ==
{@link #ANIM_TYPE_XML}
+ * @param an the attribute name if type ==
{@link
+ * #ANIM_TYPE_XML}, the property name if type ==
+ * {@link #ANIM_TYPE_CSS}, and the animation type otherwise
+ * @param anim the animation
+ */
+ public void addAnimation(AnimationTarget target, short type, String ns,
+ String an, AbstractAnimation anim) {
+ // org.apache.batik.anim.timing.Trace.enter(this, "addAnimation", new Object[] { target, new Short[type], ns, an, anim } ); try {
+ timedDocumentRoot.addChild(anim.getTimedElement());
+
+ AnimationInfo animInfo = getAnimationInfo(anim);
+ animInfo.type = type;
+ animInfo.attributeNamespaceURI = ns;
+ animInfo.attributeLocalName = an;
+ animInfo.target = target;
+ animations.put(anim, animInfo);
+
+ Sandwich sandwich = getSandwich(target, type, ns, an);
+ if (sandwich.animation == null) {
+ anim.lowerAnimation = null;
+ anim.higherAnimation = null;
+ } else {
+ sandwich.animation.higherAnimation = anim;
+ anim.lowerAnimation = sandwich.animation;
+ anim.higherAnimation = null;
+ }
+ sandwich.animation = anim;
+ if (anim.lowerAnimation == null) {
+ sandwich.lowestAnimation = anim;
+ }
+ // } finally { org.apache.batik.anim.timing.Trace.exit(); }
+ }
+
+ /**
+ * 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());
+ AbstractAnimation nextHigher = anim.higherAnimation;
+ if (nextHigher != null) {
+ nextHigher.markDirty();
+ }
+ moveToBottom(anim);
+ if (anim.higherAnimation != null) {
+ anim.higherAnimation.lowerAnimation = null;
+ }
+ AnimationInfo animInfo = getAnimationInfo(anim);
+ Sandwich sandwich = getSandwich(animInfo.target, animInfo.type,
+ animInfo.attributeNamespaceURI,
+ animInfo.attributeLocalName);
+ if (sandwich.animation == anim) {
+ sandwich.animation = null;
+ sandwich.lowestAnimation = null;
+ sandwich.shouldUpdate = true;
+ }
+ // } finally { org.apache.batik.anim.timing.Trace.exit(); }
+ }
+
+ /**
+ * Returns the Sandwich for the given animation type/attribute.
+ */
+ protected Sandwich getSandwich(AnimationTarget target, short type,
+ String ns, String an) {
+ TargetInfo info = getTargetInfo(target);
+ Sandwich sandwich;
+ if (type == ANIM_TYPE_XML) {
+ sandwich = (Sandwich) info.xmlAnimations.get(ns, an);
+ if (sandwich == null) {
+ sandwich = new Sandwich();
+ info.xmlAnimations.put(ns, an, sandwich);
+ }
+ } else if (type == ANIM_TYPE_CSS) {
+ sandwich = (Sandwich) info.cssAnimations.get(an);
+ if (sandwich == null) {
+ sandwich = new Sandwich();
+ info.cssAnimations.put(an, sandwich);
+ }
+ } else {
+ sandwich = (Sandwich) info.otherAnimations.get(an);
+ if (sandwich == null) {
+ sandwich = new Sandwich();
+ info.otherAnimations.put(an, sandwich);
+ }
+ }
+ return sandwich;
+ }
+
+ /**
+ * Returns the TargetInfo for the given AnimationTarget.
+ */
+ protected TargetInfo getTargetInfo(AnimationTarget target) {
+ TargetInfo info = (TargetInfo) targets.get(target);
+ if (info == null) {
+ info = new TargetInfo();
+ targets.put(target, info);
+ }
+ return info;
+ }
+
+ /**
+ * Returns the AnimationInfo for the given AbstractAnimation.
+ */
+ protected AnimationInfo getAnimationInfo(AbstractAnimation anim) {
+ AnimationInfo info = (AnimationInfo) animations.get(anim);
+ if (info == null) {
+ info = new AnimationInfo();
+ animations.put(anim, info);
+ }
+ return info;
+ }
+
+ protected static final Map.Entry[] MAP_ENTRY_ARRAY = new Map.Entry[0];
+
+ /**
+ * Updates the animations in the document to the given document time.
+ * @param time the document time to sample at
+ * @param hyperlinking whether the document should be seeked to the given
+ * time, as with hyperlinking
+ */
+ protected float tick(float time, boolean hyperlinking) {
+ float waitTime = timedDocumentRoot.seekTo(time, hyperlinking);
+ Map.Entry[] targetEntries =
+ (Map.Entry[]) targets.entrySet().toArray(MAP_ENTRY_ARRAY);
+ for (int i = 0; i < targetEntries.length; i++) {
+ Map.Entry e = targetEntries[i];
+ AnimationTarget target = (AnimationTarget) e.getKey();
+ TargetInfo info = (TargetInfo) e.getValue();
+
+ // Update the XML animations.
+ Iterator j = info.xmlAnimations.iterator();
+ while (j.hasNext()) {
+ DoublyIndexedTable.Entry e2 =
+ (DoublyIndexedTable.Entry) j.next();
+ String namespaceURI = (String) e2.getKey1();
+ String localName = (String) e2.getKey2();
+ Sandwich sandwich = (Sandwich) e2.getValue();
+ if (sandwich.shouldUpdate ||
+ sandwich.animation != null
+ && sandwich.animation.isDirty) {
+ AnimatableValue av = null;
+ boolean usesUnderlying = false;
+ AbstractAnimation anim = sandwich.animation;
+ if (anim != null) {
+ av = anim.getComposedValue();
+ usesUnderlying =
+ sandwich.lowestAnimation.usesUnderlyingValue();
+ anim.isDirty = false;
+ }
+ if (usesUnderlying && !sandwich.listenerRegistered) {
+ target.addTargetListener(namespaceURI, localName, false,
+ targetListener);
+ sandwich.listenerRegistered = true;
+ } else if (!usesUnderlying && sandwich.listenerRegistered) {
+ target.removeTargetListener(namespaceURI, localName,
+ false, targetListener);
+ sandwich.listenerRegistered = false;
+ }
+ target.updateAttributeValue(namespaceURI, localName, av);
+ sandwich.shouldUpdate = false;
+ }
+ }
+
+ // Update the CSS animations.
+ j = info.cssAnimations.entrySet().iterator();
+ while (j.hasNext()) {
+ Map.Entry e2 = (Map.Entry) j.next();
+ String propertyName = (String) e2.getKey();
+ Sandwich sandwich = (Sandwich) e2.getValue();
+ if (sandwich.shouldUpdate ||
+ sandwich.animation != null
+ && sandwich.animation.isDirty) {
+ AnimatableValue av = null;
+ boolean usesUnderlying = false;
+ AbstractAnimation anim = sandwich.animation;
+ if (anim != null) {
+ av = anim.getComposedValue();
+ usesUnderlying =
+ sandwich.lowestAnimation.usesUnderlyingValue();
+ anim.isDirty = false;
+ }
+ if (usesUnderlying && !sandwich.listenerRegistered) {
+ target.addTargetListener(null, propertyName, true,
+ targetListener);
+ sandwich.listenerRegistered = true;
+ } else if (!usesUnderlying && sandwich.listenerRegistered) {
+ target.removeTargetListener(null, propertyName, true,
+ targetListener);
+ sandwich.listenerRegistered = false;
+ }
+ if (usesUnderlying) {
+ target.updatePropertyValue(propertyName, null);
+ }
+ if (!(usesUnderlying && av == null)) {
+ target.updatePropertyValue(propertyName, av);
+ }
+ sandwich.shouldUpdate = false;
+ }
+ }
+
+ // Update the other animations.
+ j = info.otherAnimations.entrySet().iterator();
+ while (j.hasNext()) {
+ Map.Entry e2 = (Map.Entry) j.next();
+ String type = (String) e2.getKey();
+ Sandwich sandwich = (Sandwich) e2.getValue();
+ if (sandwich.shouldUpdate || sandwich.animation.isDirty) {
+ AnimatableValue av = null;
+ AbstractAnimation anim = sandwich.animation;
+ if (anim != null) {
+ av = sandwich.animation.getComposedValue();
+ anim.isDirty = false;
+ }
+ target.updateOtherValue(type, av);
+ sandwich.shouldUpdate = false;
+ }
+ }
+ }
+ return waitTime;
+ }
+
+ /**
+ * Invoked to indicate an animation became active at the specified time.
+ *
+ * @param anim the animation
+ * @param begin the time the element became active, in document simple time
+ */
+ public void toActive(AbstractAnimation anim, float begin) {
+ 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 = getSandwich(animInfo.target, animInfo.type,
+ animInfo.attributeNamespaceURI,
+ animInfo.attributeLocalName);
+ if (sandwich.animation == anim) {
+ sandwich.animation = top;
+ }
+ if (anim.lowerAnimation == null) {
+ sandwich.lowestAnimation = anim;
+ }
+ }
+ }
+
+ /**
+ * Invoked to indicate that this timed element became inactive.
+ *
+ * @param anim the animation
+ * @param isFrozen whether the element is frozen or not
+ */
+ public void toInactive(AbstractAnimation anim, boolean isFrozen) {
+ anim.isActive = false;
+ anim.isFrozen = isFrozen;
+ anim.beginTime = Float.NEGATIVE_INFINITY;
+ anim.markDirty();
+ if (!isFrozen) {
+ anim.value = null;
+ moveToBottom(anim);
+ } else {
+ pushDown(anim);
+ }
+ }
+
+ /**
+ * Invoked to indicate that this timed element has had its fill removed.
+ */
+ public void removeFill(AbstractAnimation anim) {
+ anim.isActive = false;
+ anim.isFrozen = false;
+ anim.value = null;
+ anim.markDirty();
+ moveToBottom(anim);
+ }
+
+ /**
+ * Moves the given animation to the top of the sandwich.
+ */
+ protected void moveToTop(AbstractAnimation anim) {
+ AnimationInfo animInfo = getAnimationInfo(anim);
+ Sandwich sandwich = getSandwich(animInfo.target, animInfo.type,
+ animInfo.attributeNamespaceURI,
+ animInfo.attributeLocalName);
+ sandwich.shouldUpdate = true;
+ if (anim.higherAnimation == null) {
+ return;
+ }
+ if (anim.lowerAnimation == null) {
+ sandwich.lowestAnimation = anim.higherAnimation;
+ } else {
+ anim.lowerAnimation.higherAnimation = anim.higherAnimation;
+ }
+ anim.higherAnimation.lowerAnimation = anim.lowerAnimation;
+ if (sandwich.animation != null) {
+ sandwich.animation.higherAnimation = anim;
+ }
+ anim.lowerAnimation = sandwich.animation;
+ anim.higherAnimation = null;
+ sandwich.animation = anim;
+ }
+
+ /**
+ * Moves the given animation to the bottom of the sandwich.
+ */
+ protected void moveToBottom(AbstractAnimation anim) {
+ if (anim.lowerAnimation == null) {
+ return;
+ }
+ AnimationInfo animInfo = getAnimationInfo(anim);
+ Sandwich sandwich = getSandwich(animInfo.target, animInfo.type,
+ animInfo.attributeNamespaceURI,
+ animInfo.attributeLocalName);
+ AbstractAnimation nextLower = anim.lowerAnimation;
+ nextLower.markDirty();
+ anim.lowerAnimation.higherAnimation = anim.higherAnimation;
+ if (anim.higherAnimation != null) {
+ anim.higherAnimation.lowerAnimation = anim.lowerAnimation;
+ } else {
+ sandwich.animation = nextLower;
+ sandwich.shouldUpdate = true;
+ }
+ sandwich.lowestAnimation.lowerAnimation = anim;
+ anim.higherAnimation = sandwich.lowestAnimation;
+ anim.lowerAnimation = null;
+ sandwich.lowestAnimation = anim;
+ if (sandwich.animation.isDirty) {
+ sandwich.shouldUpdate = true;
+ }
+ }
+
+ /**
+ * Adds a {@link TimegraphListener} to the document.
+ */
+ public void addTimegraphListener(TimegraphListener l) {
+ timedDocumentRoot.addTimegraphListener(l);
+ }
+
+ /**
+ * Removes a {@link TimegraphListener} from the document.
+ */
+ public void removeTimegraphListener(TimegraphListener l) {
+ timedDocumentRoot.removeTimegraphListener(l);
+ }
+
+ /**
+ * Invoked to indicate that this timed element has been sampled at the given
+ * time.
+ *
+ * @param anim the animation
+ * @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
+ */
+ public void sampledAt(AbstractAnimation anim, float simpleTime,
+ float simpleDur, int repeatIteration) {
+ anim.sampledAt(simpleTime, simpleDur, 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.
+ */
+ public void sampledLastValue(AbstractAnimation anim, int repeatIteration) {
+ anim.sampledLastValue(repeatIteration);
+ }
+
+ /**
+ * Creates a new returns a new TimedDocumentRoot object for the document.
+ */
+ protected abstract TimedDocumentRoot createDocumentRoot();
+
+ /**
+ * Listener class for changes to base values on a target element.
+ */
+ protected class Listener implements AnimationTargetListener {
+
+ /**
+ * Invoked to indicate that base value of the specified attribute
+ * or property has changed.
+ */
+ public void baseValueChanged(AnimationTarget t, String ns, String ln,
+ boolean isCSS) {
+ short type = isCSS ? ANIM_TYPE_CSS : ANIM_TYPE_XML;
+ Sandwich sandwich = getSandwich(t, type, ns, ln);
+ sandwich.shouldUpdate = true;
+ AbstractAnimation anim = sandwich.animation;
+ while (anim.lowerAnimation != null) {
+ anim = anim.lowerAnimation;
+ }
+ anim.markDirty();
+ }
+ }
+
+ /**
+ * Class to hold XML and CSS animations for a target element.
+ */
+ protected static class TargetInfo {
+
+ /**
+ * Map of XML attribute names to the corresponding {@link Sandwich}
+ * objects.
+ */
+ public DoublyIndexedTable xmlAnimations = new DoublyIndexedTable();
+
+ /**
+ * Map of CSS attribute names to the corresponding {@link Sandwich}
+ * objects.
+ */
+ public HashMap cssAnimations = new HashMap();
+
+ /**
+ * Map of other animation types to the corresponding {@link Sandwich}
+ * objects.
+ */
+ public HashMap otherAnimations = new HashMap();
+ }
+
+ /**
+ * Class to hold an animation sandwich for a particular attribute.
+ */
+ protected static class Sandwich {
+
+ /**
+ * The top-most animation in the sandwich.
+ */
+ public AbstractAnimation animation;
+
+ /**
+ * The bottom-most animation in the sandwich.
+ */
+ public AbstractAnimation lowestAnimation;
+
+ /**
+ * Whether the animation needs to have its value copied into the
+ * document.
+ */
+ public boolean shouldUpdate;
+
+ /**
+ * Whether an {@link AnimationTargetListener} has been registered to
+ * listen for changes to the base value.
+ */
+ public boolean listenerRegistered;
+ }
+
+ /**
+ * Class to hold target information of an animation.
+ */
+ protected static class AnimationInfo {
+
+ /**
+ * The target of the animation.
+ */
+ public AnimationTarget target;
+
+ /**
+ * The type of animation. Must be one of the ANIM_TYPE_*
+ * constants defined in {@link AnimationEngine}.
+ */
+ public short type;
+
+ /**
+ * The namespace URI of the attribute to animate, if this is an XML
+ * attribute animation.
+ */
+ public String attributeNamespaceURI;
+
+ /**
+ * The local name of the attribute or the name of the CSS property to
+ * animate.
+ */
+ public String attributeLocalName;
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/AnimationException.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/AnimationException.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/AnimationException.java 8 Apr 2013 10:55:58 -0000 1.1
@@ -0,0 +1,90 @@
+/*
+
+ 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.batik.anim;
+
+import org.apache.batik.anim.timing.TimedElement;
+
+/**
+ * An exception class for SMIL animation exceptions.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimationException.java,v 1.1 2013/04/08 10:55:58 marcin Exp $
+ */
+public class AnimationException extends RuntimeException {
+
+ /**
+ * The timed element on which the error occurred.
+ */
+ protected TimedElement e;
+
+ /**
+ * The error code.
+ */
+ protected String code;
+
+ /**
+ * The parameters to use for the error message.
+ */
+ protected Object[] params;
+
+ /**
+ * The message.
+ */
+ protected String message;
+
+ /**
+ * Creates a new AnimationException.
+ * @param e the animation element on which the error occurred
+ * @param code the error code
+ * @param params the parameters to use for the error message
+ */
+ public AnimationException(TimedElement e, String code, Object[] params) {
+ this.e = e;
+ this.code = code;
+ this.params = params;
+ }
+
+ /**
+ * Returns the timed element that caused this animation exception.
+ */
+ public TimedElement getElement() {
+ return e;
+ }
+
+ /**
+ * Returns the error code.
+ */
+ public String getCode() {
+ return code;
+ }
+
+ /**
+ * Returns the error message parameters.
+ */
+ public Object[] getParams() {
+ return params;
+ }
+
+ /**
+ * Returns the error message according to the error code and parameters.
+ */
+ public String getMessage() {
+ return TimedElement.formatMessage(code, params);
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/ColorAnimation.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/ColorAnimation.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/ColorAnimation.java 8 Apr 2013 10:55:58 -0000 1.1
@@ -0,0 +1,50 @@
+/*
+
+ 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.batik.anim;
+
+import org.apache.batik.anim.timing.TimedElement;
+import org.apache.batik.anim.values.AnimatableValue;
+import org.apache.batik.dom.anim.AnimatableElement;
+
+/**
+ * An animation class for 'animateColor' animations.
+ *
+ * @author Cameron McCormack
+ * @version $Id: ColorAnimation.java,v 1.1 2013/04/08 10:55:58 marcin Exp $
+ */
+public class ColorAnimation extends SimpleAnimation {
+
+ /**
+ * Creates a new ColorAnimation.
+ */
+ public ColorAnimation(TimedElement timedElement,
+ AnimatableElement animatableElement,
+ int calcMode,
+ float[] keyTimes,
+ float[] keySplines,
+ boolean additive,
+ boolean cumulative,
+ AnimatableValue[] values,
+ AnimatableValue from,
+ AnimatableValue to,
+ AnimatableValue by) {
+ super(timedElement, animatableElement, calcMode, keyTimes, keySplines,
+ additive, cumulative, values, from, to, by);
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/InterpolatingAnimation.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/InterpolatingAnimation.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/InterpolatingAnimation.java 8 Apr 2013 10:55:58 -0000 1.1
@@ -0,0 +1,167 @@
+/*
+
+ 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.batik.anim;
+
+import org.apache.batik.anim.timing.TimedElement;
+import org.apache.batik.dom.anim.AnimatableElement;
+import org.apache.batik.ext.awt.geom.Cubic;
+import org.apache.batik.util.SMILConstants;
+
+/**
+ * An abstract animation class for those animations that interpolate
+ * values. Specifically, this is for animations that have the 'calcMode',
+ * 'keyTimes', 'keySplines', 'additive' and 'cumulative' attributes.
+ *
+ * @author Cameron McCormack
+ * @version $Id: InterpolatingAnimation.java,v 1.1 2013/04/08 10:55:58 marcin Exp $
+ */
+public abstract class InterpolatingAnimation extends AbstractAnimation {
+
+ /**
+ * The interpolation mode of this animator. This should take one
+ * of the CALC_MODE_* constants defined in {@link AbstractAnimation}.
+ */
+ protected int calcMode;
+
+ /**
+ * Time values to control the pacing of the animation.
+ */
+ protected float[] keyTimes;
+
+ /**
+ * Bezier control points that control the pacing of the animation.
+ */
+ protected float[] keySplines;
+
+ /**
+ * Cubics built from the bezier control points in {@link #keySplines}.
+ */
+ protected Cubic[] keySplineCubics;
+
+ /**
+ * Whether this animation adds to ones below it in the animation sandwich
+ * or replaces them.
+ */
+ protected boolean additive;
+
+ /**
+ * Whether this animation accumulates from previous iterations.
+ */
+ protected boolean cumulative;
+
+ /**
+ * Creates a new InterpolatingAnimation.
+ */
+ public InterpolatingAnimation(TimedElement timedElement,
+ AnimatableElement animatableElement,
+ int calcMode,
+ float[] keyTimes,
+ float[] keySplines,
+ boolean additive,
+ boolean cumulative) {
+ super(timedElement, animatableElement);
+ this.calcMode = calcMode;
+ this.keyTimes = keyTimes;
+ this.keySplines = keySplines;
+ this.additive = additive;
+ this.cumulative = cumulative;
+
+ if (calcMode == CALC_MODE_SPLINE) {
+ if (keySplines == null || keySplines.length % 4 != 0) {
+ throw timedElement.createException
+ ("attribute.malformed",
+ new Object[] { null,
+ SMILConstants.SMIL_KEY_SPLINES_ATTRIBUTE });
+ }
+ keySplineCubics = new Cubic[keySplines.length / 4];
+ for (int i = 0; i < keySplines.length / 4; i++) {
+ keySplineCubics[i] = new Cubic(0, 0,
+ keySplines[i * 4],
+ keySplines[i * 4 + 1],
+ keySplines[i * 4 + 2],
+ keySplines[i * 4 + 3],
+ 1, 1);
+ }
+ }
+
+ if (keyTimes != null) {
+ boolean invalidKeyTimes = false;
+ if ((calcMode == CALC_MODE_LINEAR || calcMode == CALC_MODE_SPLINE
+ || calcMode == CALC_MODE_PACED)
+ && (keyTimes.length < 2
+ || keyTimes[0] != 0
+ || keyTimes[keyTimes.length - 1] != 1)
+ || calcMode == CALC_MODE_DISCRETE
+ && (keyTimes.length == 0 || keyTimes[0] != 0)) {
+ invalidKeyTimes = true;
+ }
+ if (!invalidKeyTimes) {
+ for (int i = 1; i < keyTimes.length; i++) {
+ if (keyTimes[i] < 0 || keyTimes[1] > 1
+ || keyTimes[i] < keyTimes[i - 1]) {
+ invalidKeyTimes = true;
+ break;
+ }
+ }
+ }
+ if (invalidKeyTimes) {
+ throw timedElement.createException
+ ("attribute.malformed",
+ new Object[] { null,
+ SMILConstants.SMIL_KEY_TIMES_ATTRIBUTE });
+ }
+ }
+ }
+
+ /**
+ * Returns whether this animation will replace values on animations
+ * lower in the sandwich.
+ */
+ protected boolean willReplace() {
+ return !additive;
+ }
+
+ /**
+ * Called when the element is sampled for its "last" value.
+ */
+ protected void sampledLastValue(int repeatIteration) {
+ sampledAtUnitTime(1f, repeatIteration);
+ }
+
+ /**
+ * Called when the element is sampled at the given time.
+ */
+ protected void sampledAt(float simpleTime, float simpleDur,
+ int repeatIteration) {
+ float unitTime;
+ if (simpleDur == TimedElement.INDEFINITE) {
+ unitTime = 0;
+ } else {
+ unitTime = simpleTime / simpleDur;
+ }
+ sampledAtUnitTime(unitTime, repeatIteration);
+ }
+
+ /**
+ * Called when the element is sampled at the given unit time. This updates
+ * the {@link #value} of the animation if active.
+ */
+ protected abstract void sampledAtUnitTime(float unitTime,
+ int repeatIteration);
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/MotionAnimation.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/MotionAnimation.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/MotionAnimation.java 8 Apr 2013 10:55:58 -0000 1.1
@@ -0,0 +1,331 @@
+/*
+
+ 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.batik.anim;
+
+import java.awt.geom.Point2D;
+
+import org.apache.batik.anim.timing.TimedElement;
+import org.apache.batik.anim.values.AnimatableAngleValue;
+import org.apache.batik.anim.values.AnimatableMotionPointValue;
+import org.apache.batik.anim.values.AnimatableValue;
+import org.apache.batik.dom.anim.AnimatableElement;
+import org.apache.batik.ext.awt.geom.Cubic;
+import org.apache.batik.ext.awt.geom.ExtendedGeneralPath;
+import org.apache.batik.ext.awt.geom.ExtendedPathIterator;
+import org.apache.batik.ext.awt.geom.PathLength;
+import org.apache.batik.util.SMILConstants;
+
+/**
+ * An animation class for 'animateMotion' animations.
+ *
+ * @author Cameron McCormack
+ * @version $Id: MotionAnimation.java,v 1.1 2013/04/08 10:55:58 marcin Exp $
+ */
+public class MotionAnimation extends InterpolatingAnimation {
+
+ /**
+ * The path that describes the motion.
+ */
+ protected ExtendedGeneralPath path;
+
+ /**
+ * The path length calculation object.
+ */
+ protected PathLength pathLength;
+
+ /**
+ * The points defining the distance along the path that the
+ * keyTimes apply.
+ */
+ protected float[] keyPoints;
+
+ /**
+ * Whether automatic rotation should be performed.
+ */
+ protected boolean rotateAuto;
+
+ /**
+ * Whether the automatic rotation should be reversed.
+ */
+ protected boolean rotateAutoReverse;
+
+ /**
+ * The angle of rotation (in radians) to use when automatic rotation is
+ * not being used.
+ */
+ protected float rotateAngle;
+
+ /**
+ * Creates a new MotionAnimation.
+ */
+ public MotionAnimation(TimedElement timedElement,
+ AnimatableElement animatableElement,
+ int calcMode,
+ float[] keyTimes,
+ float[] keySplines,
+ boolean additive,
+ boolean cumulative,
+ AnimatableValue[] values,
+ AnimatableValue from,
+ AnimatableValue to,
+ AnimatableValue by,
+ ExtendedGeneralPath path,
+ float[] keyPoints,
+ boolean rotateAuto,
+ boolean rotateAutoReverse,
+ float rotateAngle,
+ short rotateAngleUnit) {
+ super(timedElement, animatableElement, calcMode, keyTimes, keySplines,
+ additive, cumulative);
+ this.rotateAuto = rotateAuto;
+ this.rotateAutoReverse = rotateAutoReverse;
+ this.rotateAngle = AnimatableAngleValue.rad(rotateAngle, rotateAngleUnit);
+
+ if (path == null) {
+ path = new ExtendedGeneralPath();
+ if (values == null || values.length == 0) {
+ if (from != null) {
+ AnimatableMotionPointValue fromPt = (AnimatableMotionPointValue) from;
+ float x = fromPt.getX();
+ float y = fromPt.getY();
+ path.moveTo(x, y);
+ if (to != null) {
+ AnimatableMotionPointValue toPt = (AnimatableMotionPointValue) to;
+ path.lineTo(toPt.getX(), toPt.getY());
+ } else if (by != null) {
+ AnimatableMotionPointValue byPt = (AnimatableMotionPointValue) by;
+ path.lineTo(x + byPt.getX(), y + byPt.getY());
+ } else {
+ throw timedElement.createException
+ ("values.to.by.path.missing",
+ new Object[] { null });
+ }
+ } else {
+ if (to != null) {
+ AnimatableMotionPointValue unPt = (AnimatableMotionPointValue)
+ animatableElement.getUnderlyingValue();
+ AnimatableMotionPointValue toPt = (AnimatableMotionPointValue) to;
+ path.moveTo(unPt.getX(), unPt.getY());
+ path.lineTo(toPt.getX(), toPt.getY());
+ this.cumulative = false;
+ } else if (by != null) {
+ AnimatableMotionPointValue byPt = (AnimatableMotionPointValue) by;
+ path.moveTo(0, 0);
+ path.lineTo(byPt.getX(), byPt.getY());
+ this.additive = true;
+ } else {
+ throw timedElement.createException
+ ("values.to.by.path.missing",
+ new Object[] { null });
+ }
+ }
+ } else {
+ AnimatableMotionPointValue pt = (AnimatableMotionPointValue) values[0];
+ path.moveTo(pt.getX(), pt.getY());
+ for (int i = 1; i < values.length; i++) {
+ pt = (AnimatableMotionPointValue) values[i];
+ path.lineTo(pt.getX(), pt.getY());
+ }
+ }
+ }
+ this.path = path;
+ pathLength = new PathLength(path);
+ int segments = 0;
+ ExtendedPathIterator epi = path.getExtendedPathIterator();
+ while (!epi.isDone()) {
+ int type = epi.currentSegment();
+ if (type != ExtendedPathIterator.SEG_MOVETO) {
+ segments++;
+ }
+ epi.next();
+ }
+
+ int count = keyPoints == null ? segments + 1 : keyPoints.length;
+ float totalLength = pathLength.lengthOfPath();
+ if (this.keyTimes != null && calcMode != CALC_MODE_PACED) {
+ if (this.keyTimes.length != count) {
+ throw timedElement.createException
+ ("attribute.malformed",
+ new Object[] { null,
+ SMILConstants.SMIL_KEY_TIMES_ATTRIBUTE });
+ }
+ } else {
+ if (calcMode == CALC_MODE_LINEAR || calcMode == CALC_MODE_SPLINE) {
+ this.keyTimes = new float[count];
+ for (int i = 0; i < count; i++) {
+ this.keyTimes[i] = (float) i / (count - 1);
+ }
+ } else if (calcMode == CALC_MODE_DISCRETE) {
+ this.keyTimes = new float[count];
+ for (int i = 0; i < count; i++) {
+ this.keyTimes[i] = (float) i / count;
+ }
+ } else { // CALC_MODE_PACED
+ // This corrects the keyTimes to be paced, so from now on
+ // it can be considered the same as CALC_MODE_LINEAR.
+ epi = path.getExtendedPathIterator();
+ this.keyTimes = new float[count];
+ int j = 0;
+ for (int i = 0; i < count - 1; i++) {
+ while (epi.currentSegment() ==
+ ExtendedPathIterator.SEG_MOVETO) {
+ j++;
+ epi.next();
+ }
+ this.keyTimes[i] =
+ pathLength.getLengthAtSegment(j) / totalLength;
+ j++;
+ epi.next();
+ }
+ this.keyTimes[count - 1] = 1f;
+ }
+ }
+
+ if (keyPoints != null) {
+ if (keyPoints.length != this.keyTimes.length) {
+ throw timedElement.createException
+ ("attribute.malformed",
+ new Object[] { null,
+ SMILConstants.SMIL_KEY_POINTS_ATTRIBUTE });
+ }
+ } else {
+ epi = path.getExtendedPathIterator();
+ keyPoints = new float[count];
+ int j = 0;
+ for (int i = 0; i < count - 1; i++) {
+ while (epi.currentSegment() ==
+ ExtendedPathIterator.SEG_MOVETO) {
+ j++;
+ epi.next();
+ }
+ keyPoints[i] = pathLength.getLengthAtSegment(j) / totalLength;
+ j++;
+ epi.next();
+ }
+ keyPoints[count - 1] = 1f;
+ }
+ this.keyPoints = keyPoints;
+ }
+
+ /**
+ * Called when the element is sampled at the given unit time. This updates
+ * the {@link #value} of the animation if active.
+ */
+ protected void sampledAtUnitTime(float unitTime, int repeatIteration) {
+ AnimatableValue value, accumulation;
+ float interpolation = 0;
+ if (unitTime != 1) {
+ int keyTimeIndex = 0;
+ while (keyTimeIndex < keyTimes.length - 1
+ && unitTime >= keyTimes[keyTimeIndex + 1]) {
+ keyTimeIndex++;
+ }
+ if (keyTimeIndex == keyTimes.length - 1 && calcMode == CALC_MODE_DISCRETE) {
+ keyTimeIndex = keyTimes.length - 2;
+ interpolation = 1;
+ } else {
+ if (calcMode == CALC_MODE_LINEAR || calcMode == CALC_MODE_PACED
+ || calcMode == CALC_MODE_SPLINE) {
+ if (unitTime == 0) {
+ interpolation = 0;
+ } else {
+ interpolation = (unitTime - keyTimes[keyTimeIndex])
+ / (keyTimes[keyTimeIndex + 1] - keyTimes[keyTimeIndex]);
+ }
+ if (calcMode == CALC_MODE_SPLINE && unitTime != 0) {
+ // XXX This could be done better, e.g. with
+ // Newton-Raphson.
+ Cubic c = keySplineCubics[keyTimeIndex];
+ float tolerance = 0.001f;
+ float min = 0;
+ float max = 1;
+ Point2D.Double p;
+ for (;;) {
+ float t = (min + max) / 2;
+ p = c.eval(t);
+ double x = p.getX();
+ if (Math.abs(x - interpolation) < tolerance) {
+ break;
+ }
+ if (x < interpolation) {
+ min = t;
+ } else {
+ max = t;
+ }
+ }
+ interpolation = (float) p.getY();
+ }
+ }
+ }
+ float point = keyPoints[keyTimeIndex];
+ if (interpolation != 0) {
+ point += interpolation *
+ (keyPoints[keyTimeIndex + 1] - keyPoints[keyTimeIndex]);
+ }
+ point *= pathLength.lengthOfPath();
+ Point2D p = pathLength.pointAtLength(point);
+ float ang;
+ if (rotateAuto) {
+ ang = pathLength.angleAtLength(point);
+ if (rotateAutoReverse) {
+ ang += Math.PI;
+ }
+ } else {
+ ang = rotateAngle;
+ }
+ value = new AnimatableMotionPointValue(null, (float) p.getX(),
+ (float) p.getY(), ang);
+ } else {
+ Point2D p = pathLength.pointAtLength(pathLength.lengthOfPath());
+ float ang;
+ if (rotateAuto) {
+ ang = pathLength.angleAtLength(pathLength.lengthOfPath());
+ if (rotateAutoReverse) {
+ ang += Math.PI;
+ }
+ } else {
+ ang = rotateAngle;
+ }
+ value = new AnimatableMotionPointValue(null, (float) p.getX(),
+ (float) p.getY(), ang);
+ }
+ if (cumulative) {
+ Point2D p = pathLength.pointAtLength(pathLength.lengthOfPath());
+ float ang;
+ if (rotateAuto) {
+ ang = pathLength.angleAtLength(pathLength.lengthOfPath());
+ if (rotateAutoReverse) {
+ ang += Math.PI;
+ }
+ } else {
+ ang = rotateAngle;
+ }
+ accumulation = new AnimatableMotionPointValue(null, (float) p.getX(),
+ (float) p.getY(), ang);
+ } else {
+ accumulation = null;
+ }
+
+ this.value = value.interpolate(this.value, null, interpolation,
+ accumulation, repeatIteration);
+ if (this.value.hasChanged()) {
+ markDirty();
+ }
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/SetAnimation.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/SetAnimation.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/SetAnimation.java 8 Apr 2013 10:55:58 -0000 1.1
@@ -0,0 +1,68 @@
+/*
+
+ 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.batik.anim;
+
+import org.apache.batik.anim.values.AnimatableValue;
+import org.apache.batik.anim.timing.TimedElement;
+import org.apache.batik.dom.anim.AnimatableElement;
+
+/**
+ * An animation class for 'set' animations.
+ *
+ * @author Cameron McCormack
+ * @version $Id: SetAnimation.java,v 1.1 2013/04/08 10:55:58 marcin Exp $
+ */
+public class SetAnimation extends AbstractAnimation {
+
+ /**
+ * The set animation value.
+ */
+ protected AnimatableValue to;
+
+ /**
+ * Creates a new SetAnimation.
+ */
+ public SetAnimation(TimedElement timedElement,
+ AnimatableElement animatableElement,
+ AnimatableValue to) {
+ super(timedElement, animatableElement);
+ this.to = to;
+ }
+
+ /**
+ * Called when the element is sampled at the given time.
+ */
+ protected void sampledAt(float simpleTime, float simpleDur,
+ int repeatIteration) {
+ if (value == null) {
+ value = to;
+ markDirty();
+ }
+ }
+
+ /**
+ * Called when the element is sampled for its "last" value.
+ */
+ protected void sampledLastValue(int repeatIteration) {
+ if (value == null) {
+ value = to;
+ markDirty();
+ }
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/SimpleAnimation.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/SimpleAnimation.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/SimpleAnimation.java 8 Apr 2013 10:55:58 -0000 1.1
@@ -0,0 +1,221 @@
+/*
+
+ 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.batik.anim;
+
+import java.awt.geom.Point2D;
+
+import org.apache.batik.anim.timing.TimedElement;
+import org.apache.batik.anim.values.AnimatableValue;
+import org.apache.batik.dom.anim.AnimatableElement;
+import org.apache.batik.ext.awt.geom.Cubic;
+import org.apache.batik.util.SMILConstants;
+
+/**
+ * An animation class for 'animate' animations.
+ *
+ * @author Cameron McCormack
+ * @version $Id: SimpleAnimation.java,v 1.1 2013/04/08 10:55:58 marcin Exp $
+ */
+public class SimpleAnimation extends InterpolatingAnimation {
+
+ /**
+ * Values between which to interpolate.
+ */
+ protected AnimatableValue[] values;
+
+ /**
+ * Starting value of the animation.
+ */
+ protected AnimatableValue from;
+
+ /**
+ * Ending value of the animation.
+ */
+ protected AnimatableValue to;
+
+ /**
+ * Relative offset value for the animation.
+ */
+ protected AnimatableValue by;
+
+ /**
+ * Creates a new SimpleAnimation.
+ */
+ public SimpleAnimation(TimedElement timedElement,
+ AnimatableElement animatableElement,
+ int calcMode,
+ float[] keyTimes,
+ float[] keySplines,
+ boolean additive,
+ boolean cumulative,
+ AnimatableValue[] values,
+ AnimatableValue from,
+ AnimatableValue to,
+ AnimatableValue by) {
+ super(timedElement, animatableElement, calcMode, keyTimes, keySplines,
+ additive, cumulative);
+ this.from = from;
+ this.to = to;
+ this.by = by;
+
+ if (values == null) {
+ if (from != null) {
+ values = new AnimatableValue[2];
+ values[0] = from;
+ if (to != null) {
+ values[1] = to;
+ } else if (by != null) {
+ values[1] = from.interpolate(null, null, 0f, by, 1);
+ } else {
+ throw timedElement.createException
+ ("values.to.by.missing", new Object[] { null });
+ }
+ } else {
+ if (to != null) {
+ values = new AnimatableValue[2];
+ values[0] = animatableElement.getUnderlyingValue();
+ values[1] = to;
+ this.cumulative = false;
+ toAnimation = true;
+ } else if (by != null) {
+ this.additive = true;
+ values = new AnimatableValue[2];
+ values[0] = by.getZeroValue();
+ values[1] = by;
+ } else {
+ throw timedElement.createException
+ ("values.to.by.missing", new Object[] { null });
+ }
+ }
+ }
+ this.values = values;
+
+ if (this.keyTimes != null && calcMode != CALC_MODE_PACED) {
+ if (this.keyTimes.length != values.length) {
+ throw timedElement.createException
+ ("attribute.malformed",
+ new Object[] { null,
+ SMILConstants.SMIL_KEY_TIMES_ATTRIBUTE });
+ }
+ } else {
+ if (calcMode == CALC_MODE_LINEAR || calcMode == CALC_MODE_SPLINE
+ || calcMode == CALC_MODE_PACED && !values[0].canPace()) {
+ int count = values.length == 1 ? 2 : values.length;
+ this.keyTimes = new float[count];
+ for (int i = 0; i < count; i++) {
+ this.keyTimes[i] = (float) i / (count - 1);
+ }
+ } else if (calcMode == CALC_MODE_DISCRETE) {
+ int count = values.length;
+ this.keyTimes = new float[count];
+ for (int i = 0; i < count; i++) {
+ this.keyTimes[i] = (float) i / count;
+ }
+ } else { // CALC_MODE_PACED
+ // This corrects the keyTimes to be paced, so from now on
+ // it can be considered the same as CALC_MODE_LINEAR.
+ int count = values.length;
+ float[] cumulativeDistances = new float[count];
+ cumulativeDistances[0] = 0;
+ for (int i = 1; i < count; i++) {
+ cumulativeDistances[i] = cumulativeDistances[i - 1]
+ + values[i - 1].distanceTo(values[i]);
+ }
+ float totalLength = cumulativeDistances[count - 1];
+ this.keyTimes = new float[count];
+ this.keyTimes[0] = 0;
+ for (int i = 1; i < count - 1; i++) {
+ this.keyTimes[i] = cumulativeDistances[i] / totalLength;
+ }
+ this.keyTimes[count - 1] = 1;
+ }
+ }
+
+ if (calcMode == CALC_MODE_SPLINE
+ && keySplines.length != (this.keyTimes.length - 1) * 4) {
+ throw timedElement.createException
+ ("attribute.malformed",
+ new Object[] { null,
+ SMILConstants.SMIL_KEY_SPLINES_ATTRIBUTE });
+ }
+ }
+
+ /**
+ * Called when the element is sampled at the given unit time. This updates
+ * the {@link #value} of the animation if active.
+ */
+ protected void sampledAtUnitTime(float unitTime, int repeatIteration) {
+ AnimatableValue value, accumulation, nextValue;
+ float interpolation = 0;
+ if (unitTime != 1) {
+ int keyTimeIndex = 0;
+ while (keyTimeIndex < keyTimes.length - 1
+ && unitTime >= keyTimes[keyTimeIndex + 1]) {
+ keyTimeIndex++;
+ }
+ value = values[keyTimeIndex];
+ if (calcMode == CALC_MODE_LINEAR
+ || calcMode == CALC_MODE_PACED
+ || calcMode == CALC_MODE_SPLINE) {
+ nextValue = values[keyTimeIndex + 1];
+ interpolation = (unitTime - keyTimes[keyTimeIndex])
+ / (keyTimes[keyTimeIndex + 1] - keyTimes[keyTimeIndex]);
+ if (calcMode == CALC_MODE_SPLINE && unitTime != 0) {
+ // XXX This could be done better, e.g. with
+ // Newton-Raphson.
+ Cubic c = keySplineCubics[keyTimeIndex];
+ float tolerance = 0.001f;
+ float min = 0;
+ float max = 1;
+ Point2D.Double p;
+ for (;;) {
+ float t = (min + max) / 2;
+ p = c.eval(t);
+ double x = p.getX();
+ if (Math.abs(x - interpolation) < tolerance) {
+ break;
+ }
+ if (x < interpolation) {
+ min = t;
+ } else {
+ max = t;
+ }
+ }
+ interpolation = (float) p.getY();
+ }
+ } else {
+ nextValue = null;
+ }
+ } else {
+ value = values[values.length - 1];
+ nextValue = null;
+ }
+ if (cumulative) {
+ accumulation = values[values.length - 1];
+ } else {
+ accumulation = null;
+ }
+
+ this.value = value.interpolate(this.value, nextValue, interpolation,
+ accumulation, repeatIteration);
+ if (this.value.hasChanged()) {
+ markDirty();
+ }
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/TransformAnimation.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/TransformAnimation.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/TransformAnimation.java 8 Apr 2013 10:55:58 -0000 1.1
@@ -0,0 +1,251 @@
+/*
+
+ 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.batik.anim;
+
+import org.apache.batik.anim.timing.TimedElement;
+import org.apache.batik.anim.values.AnimatableValue;
+import org.apache.batik.anim.values.AnimatableTransformListValue;
+import org.apache.batik.dom.anim.AnimatableElement;
+
+import org.w3c.dom.svg.SVGTransform;
+
+/**
+ * An animation class for 'animateTransform' animations.
+ *
+ * @author Cameron McCormack
+ * @version $Id: TransformAnimation.java,v 1.1 2013/04/08 10:55:58 marcin Exp $
+ */
+public class TransformAnimation extends SimpleAnimation {
+
+ /**
+ * The transform type. This should take one of the constants defined
+ * in {@link org.w3c.dom.svg.SVGTransform}.
+ */
+ protected short type;
+
+ /**
+ * Time values to control the pacing of the second component of the
+ * animation.
+ */
+ protected float[] keyTimes2;
+
+ /**
+ * Time values to control the pacing of the third component of the
+ * animation.
+ */
+ protected float[] keyTimes3;
+
+ /**
+ * Creates a new TransformAnimation.
+ */
+ public TransformAnimation(TimedElement timedElement,
+ AnimatableElement animatableElement,
+ int calcMode,
+ float[] keyTimes,
+ float[] keySplines,
+ boolean additive,
+ boolean cumulative,
+ AnimatableValue[] values,
+ AnimatableValue from,
+ AnimatableValue to,
+ AnimatableValue by,
+ short type) {
+ // pretend we didn't get a calcMode="paced", since we need specialised
+ // behaviour in sampledAtUnitTime.
+ super(timedElement, animatableElement,
+ calcMode == CALC_MODE_PACED ? CALC_MODE_LINEAR : calcMode,
+ calcMode == CALC_MODE_PACED ? null : keyTimes,
+ keySplines, additive, cumulative, values, from, to, by);
+ this.calcMode = calcMode;
+ this.type = type;
+
+ if (calcMode != CALC_MODE_PACED) {
+ return;
+ }
+
+ // Determine the equivalent keyTimes for the individual components
+ // of the transforms for CALC_MODE_PACED.
+ int count = this.values.length;
+ float[] cumulativeDistances1;
+ float[] cumulativeDistances2 = null;
+ float[] cumulativeDistances3 = null;
+ switch (type) {
+ case SVGTransform.SVG_TRANSFORM_ROTATE:
+ cumulativeDistances3 = new float[count];
+ cumulativeDistances3[0] = 0f;
+ // fall through
+ case SVGTransform.SVG_TRANSFORM_SCALE:
+ case SVGTransform.SVG_TRANSFORM_TRANSLATE:
+ cumulativeDistances2 = new float[count];
+ cumulativeDistances2[0] = 0f;
+ // fall through
+ default:
+ cumulativeDistances1 = new float[count];
+ cumulativeDistances1[0] = 0f;
+ }
+
+ for (int i = 1; i < this.values.length; i++) {
+ switch (type) {
+ case SVGTransform.SVG_TRANSFORM_ROTATE:
+ cumulativeDistances3[i] =
+ cumulativeDistances3[i - 1]
+ + ((AnimatableTransformListValue)
+ this.values[i - 1]).distanceTo3(this.values[i]);
+ // fall through
+ case SVGTransform.SVG_TRANSFORM_SCALE:
+ case SVGTransform.SVG_TRANSFORM_TRANSLATE:
+ cumulativeDistances2[i] =
+ cumulativeDistances2[i - 1]
+ + ((AnimatableTransformListValue)
+ this.values[i - 1]).distanceTo2(this.values[i]);
+ // fall through
+ default:
+ cumulativeDistances1[i] =
+ cumulativeDistances1[i - 1]
+ + ((AnimatableTransformListValue)
+ this.values[i - 1]).distanceTo1(this.values[i]);
+ }
+ }
+
+ switch (type) {
+ case SVGTransform.SVG_TRANSFORM_ROTATE:
+ float totalLength = cumulativeDistances3[count - 1];
+ keyTimes3 = new float[count];
+ keyTimes3[0] = 0f;
+ for (int i = 1; i < count - 1; i++) {
+ keyTimes3[i] = cumulativeDistances3[i] / totalLength;
+ }
+ keyTimes3[count - 1] = 1f;
+ // fall through
+ case SVGTransform.SVG_TRANSFORM_SCALE:
+ case SVGTransform.SVG_TRANSFORM_TRANSLATE:
+ totalLength = cumulativeDistances2[count - 1];
+ keyTimes2 = new float[count];
+ keyTimes2[0] = 0f;
+ for (int i = 1; i < count - 1; i++) {
+ keyTimes2[i] = cumulativeDistances2[i] / totalLength;
+ }
+ keyTimes2[count - 1] = 1f;
+ // fall through
+ default:
+ totalLength = cumulativeDistances1[count - 1];
+ this.keyTimes = new float[count];
+ this.keyTimes[0] = 0f;
+ for (int i = 1; i < count - 1; i++) {
+ this.keyTimes[i] = cumulativeDistances1[i] / totalLength;
+ }
+ this.keyTimes[count - 1] = 1f;
+ }
+ }
+
+ /**
+ * Called when the element is sampled at the given unit time. This updates
+ * the {@link #value} of the animation if active.
+ */
+ protected void sampledAtUnitTime(float unitTime, int repeatIteration) {
+ // Note that skews are handled by SimpleAnimation and not here, since
+ // they need just the one component of interpolation.
+ if (calcMode != CALC_MODE_PACED
+ || type == SVGTransform.SVG_TRANSFORM_SKEWX
+ || type == SVGTransform.SVG_TRANSFORM_SKEWY) {
+ super.sampledAtUnitTime(unitTime, repeatIteration);
+ return;
+ }
+
+ AnimatableTransformListValue
+ value1, value2, value3 = null, nextValue1, nextValue2,
+ nextValue3 = null, accumulation;
+ float interpolation1 = 0f, interpolation2 = 0f, interpolation3 = 0f;
+ if (unitTime != 1) {
+ switch (type) {
+ case SVGTransform.SVG_TRANSFORM_ROTATE:
+ int keyTimeIndex = 0;
+ while (keyTimeIndex < keyTimes3.length - 1
+ && unitTime >= keyTimes3[keyTimeIndex + 1]) {
+ keyTimeIndex++;
+ }
+ value3 = (AnimatableTransformListValue)
+ this.values[keyTimeIndex];
+ nextValue3 = (AnimatableTransformListValue)
+ this.values[keyTimeIndex + 1];
+ interpolation3 = (unitTime - keyTimes3[keyTimeIndex])
+ / (keyTimes3[keyTimeIndex + 1] -
+ keyTimes3[keyTimeIndex]);
+ // fall through
+ default:
+ keyTimeIndex = 0;
+ while (keyTimeIndex < keyTimes2.length - 1
+ && unitTime >= keyTimes2[keyTimeIndex + 1]) {
+ keyTimeIndex++;
+ }
+ value2 = (AnimatableTransformListValue)
+ this.values[keyTimeIndex];
+ nextValue2 = (AnimatableTransformListValue)
+ this.values[keyTimeIndex + 1];
+ interpolation2 = (unitTime - keyTimes2[keyTimeIndex])
+ / (keyTimes2[keyTimeIndex + 1] -
+ keyTimes2[keyTimeIndex]);
+
+ keyTimeIndex = 0;
+ while (keyTimeIndex < keyTimes.length - 1
+ && unitTime >= keyTimes[keyTimeIndex + 1]) {
+ keyTimeIndex++;
+ }
+ value1 = (AnimatableTransformListValue)
+ this.values[keyTimeIndex];
+ nextValue1 = (AnimatableTransformListValue)
+ this.values[keyTimeIndex + 1];
+ interpolation1 = (unitTime - keyTimes[keyTimeIndex])
+ / (keyTimes[keyTimeIndex + 1] -
+ keyTimes[keyTimeIndex]);
+ }
+ } else {
+ value1 = value2 = value3 = (AnimatableTransformListValue)
+ this.values[this.values.length - 1];
+ nextValue1 = nextValue2 = nextValue3 = null;
+ interpolation1 = interpolation2 = interpolation3 = 1f;
+ }
+ if (cumulative) {
+ accumulation = (AnimatableTransformListValue)
+ this.values[this.values.length - 1];
+ } else {
+ accumulation = null;
+ }
+
+ switch (type) {
+ case SVGTransform.SVG_TRANSFORM_ROTATE:
+ this.value = AnimatableTransformListValue.interpolate
+ ((AnimatableTransformListValue) this.value, value1, value2,
+ value3, nextValue1, nextValue2, nextValue3, interpolation1,
+ interpolation2, interpolation3, accumulation,
+ repeatIteration);
+ break;
+ default:
+ this.value = AnimatableTransformListValue.interpolate
+ ((AnimatableTransformListValue) this.value, value1, value2,
+ nextValue1, nextValue2, interpolation1, interpolation2,
+ accumulation, repeatIteration);
+ break;
+ }
+
+ if (this.value.hasChanged()) {
+ markDirty();
+ }
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/AccesskeyTimingSpecifier.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/AccesskeyTimingSpecifier.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/AccesskeyTimingSpecifier.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,149 @@
+/*
+
+ 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.batik.anim.timing;
+
+import org.apache.batik.dom.events.DOMKeyEvent;
+import org.apache.batik.dom.events.NodeEventTarget;
+import org.apache.batik.util.XMLConstants;
+
+import org.w3c.dom.events.Event;
+import org.w3c.dom.events.EventListener;
+import org.w3c.dom.events.EventTarget;
+import org.w3c.dom.events.KeyboardEvent;
+
+/**
+ * A class to handle SMIL access key timing specifiers.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AccesskeyTimingSpecifier.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public class AccesskeyTimingSpecifier
+ extends EventLikeTimingSpecifier
+ implements EventListener {
+
+ /**
+ * The accesskey.
+ */
+ protected char accesskey;
+
+ /**
+ * Whether this access key specifier uses SVG 1.2 syntax.
+ */
+ protected boolean isSVG12AccessKey;
+
+ /**
+ * The DOM 3 key name for SVG 1.2 access key specifiers.
+ */
+ protected String keyName;
+
+ /**
+ * Creates a new AccesskeyTimingSpecifier object using SVG 1.1
+ * or SMIL syntax.
+ */
+ public AccesskeyTimingSpecifier(TimedElement owner, boolean isBegin,
+ float offset, char accesskey) {
+ super(owner, isBegin, offset);
+ this.accesskey = accesskey;
+ }
+
+ /**
+ * Creates a new AccesskeyTimingSpecifier object using SVG 1.2 syntax.
+ */
+ public AccesskeyTimingSpecifier(TimedElement owner, boolean isBegin,
+ float offset, String keyName) {
+ super(owner, isBegin, offset);
+ this.isSVG12AccessKey = true;
+ this.keyName = keyName;
+ }
+
+ /**
+ * Returns a string representation of this timing specifier.
+ */
+ public String toString() {
+ if (isSVG12AccessKey) {
+ return "accessKey(" + keyName + ")"
+ + (offset != 0 ? super.toString() : "");
+ }
+ return "accesskey(" + accesskey + ")"
+ + (offset != 0 ? super.toString() : "");
+ }
+
+ /**
+ * Initializes this timing specifier by adding the initial instance time
+ * to the owner's instance time list or setting up any event listeners.
+ */
+ public void initialize() {
+ if (isSVG12AccessKey) {
+ NodeEventTarget eventTarget =
+ (NodeEventTarget) owner.getRootEventTarget();
+ eventTarget.addEventListenerNS
+ (XMLConstants.XML_EVENTS_NAMESPACE_URI, "keydown",
+ this, false, null);
+ } else {
+ EventTarget eventTarget = owner.getRootEventTarget();
+ eventTarget.addEventListener("keypress", this, false);
+ }
+ }
+
+ /**
+ * Deinitializes this timing specifier by removing any event listeners.
+ */
+ public void deinitialize() {
+ if (isSVG12AccessKey) {
+ NodeEventTarget eventTarget =
+ (NodeEventTarget) owner.getRootEventTarget();
+ eventTarget.removeEventListenerNS
+ (XMLConstants.XML_EVENTS_NAMESPACE_URI, "keydown",
+ this, false);
+ } else {
+ EventTarget eventTarget = owner.getRootEventTarget();
+ eventTarget.removeEventListener("keypress", this, false);
+ }
+ }
+
+ // EventListener /////////////////////////////////////////////////////////
+
+ /**
+ * Handles key events fired by the eventbase element.
+ */
+ public void handleEvent(Event e) {
+ boolean matched;
+ if (e.getType().charAt(3) == 'p') {
+ // DOM 2 key draft keypress
+ DOMKeyEvent evt = (DOMKeyEvent) e;
+ matched = evt.getCharCode() == accesskey;
+ } else {
+ // DOM 3 keydown
+ KeyboardEvent evt = (KeyboardEvent) e;
+ matched = evt.getKeyIdentifier().equals(keyName);
+ }
+ if (matched) {
+ owner.eventOccurred(this, e);
+ }
+ }
+
+ /**
+ * Invoked to resolve an event-like timing specifier into an instance time.
+ */
+ public void resolve(Event e) {
+ float time = owner.getRoot().convertEpochTime(e.getTimeStamp());
+ InstanceTime instance = new InstanceTime(this, time + offset, true);
+ owner.addInstanceTime(instance, isBegin);
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/EventLikeTimingSpecifier.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/EventLikeTimingSpecifier.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/EventLikeTimingSpecifier.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,51 @@
+/*
+
+ 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.batik.anim.timing;
+
+import org.w3c.dom.events.Event;
+
+/**
+ * Abstract class from which all event-like timing specifier classes derive.
+ *
+ * @author Cameron McCormack
+ * @version $Id: EventLikeTimingSpecifier.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public abstract class EventLikeTimingSpecifier extends OffsetTimingSpecifier {
+
+ /**
+ * Creates a new EventLikeTimingSpecifier object.
+ */
+ public EventLikeTimingSpecifier(TimedElement owner, boolean isBegin,
+ float offset) {
+ super(owner, isBegin, offset);
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Invoked to resolve an event-like timing specifier into an instance time.
+ */
+ public abstract void resolve(Event e);
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/EventbaseTimingSpecifier.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/EventbaseTimingSpecifier.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/EventbaseTimingSpecifier.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,128 @@
+/*
+
+ 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.batik.anim.timing;
+
+import org.apache.batik.dom.events.NodeEventTarget;
+
+import org.w3c.dom.events.Event;
+import org.w3c.dom.events.EventListener;
+import org.w3c.dom.events.EventTarget;
+
+/**
+ * A class to handle eventbase SMIL timing specifiers.
+ *
+ * @author Cameron McCormack
+ * @version $Id: EventbaseTimingSpecifier.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public class EventbaseTimingSpecifier
+ extends EventLikeTimingSpecifier
+ implements EventListener {
+
+ /**
+ * The ID of the eventbase element.
+ */
+ protected String eventbaseID;
+
+ /**
+ * The eventbase element.
+ */
+ protected TimedElement eventbase;
+
+ /**
+ * The eventbase element as an {@link EventTarget}.
+ */
+ protected EventTarget eventTarget;
+
+ /**
+ * The namespace URI of the event to sync to.
+ */
+ protected String eventNamespaceURI;
+
+ /**
+ * The type of the event to sync to.
+ */
+ protected String eventType;
+
+ /**
+ * The animation name of the event to sync to.
+ */
+ protected String eventName;
+
+ /**
+ * Creates a new EventbaseTimingSpecifier object.
+ */
+ public EventbaseTimingSpecifier(TimedElement owner, boolean isBegin,
+ float offset, String eventbaseID,
+ String eventName) {
+ super(owner, isBegin, offset);
+ this.eventbaseID = eventbaseID;
+ this.eventName = eventName;
+ TimedDocumentRoot root = owner.getRoot();
+ this.eventNamespaceURI = root.getEventNamespaceURI(eventName);
+ this.eventType = root.getEventType(eventName);
+ if (eventbaseID == null) {
+ this.eventTarget = owner.getAnimationEventTarget();
+ } else {
+ this.eventTarget = owner.getEventTargetById(eventbaseID);
+ }
+ }
+
+ /**
+ * Returns a string representation of this timing specifier.
+ */
+ public String toString() {
+ return (eventbaseID == null ? "" : eventbaseID + ".") + eventName
+ + (offset != 0 ? super.toString() : "");
+ }
+
+ /**
+ * Initializes this timing specifier by adding the initial instance time
+ * to the owner's instance time list or setting up any event listeners.
+ */
+ public void initialize() {
+ ((NodeEventTarget) eventTarget).addEventListenerNS
+ (eventNamespaceURI, eventType, this, false, null);
+ }
+
+ /**
+ * Deinitializes this timing specifier by removing any event listeners.
+ */
+ public void deinitialize() {
+ ((NodeEventTarget) eventTarget).removeEventListenerNS
+ (eventNamespaceURI, eventType, this, false);
+ }
+
+ // EventListener /////////////////////////////////////////////////////////
+
+ /**
+ * Handles an event fired on the eventbase element.
+ */
+ public void handleEvent(Event e) {
+ owner.eventOccurred(this, e);
+ }
+
+ /**
+ * Invoked to resolve an event-like timing specifier into an instance time.
+ */
+ public void resolve(Event e) {
+ float time = owner.getRoot().convertEpochTime(e.getTimeStamp());
+ InstanceTime instance = new InstanceTime(this, time + offset, true);
+ owner.addInstanceTime(instance, isBegin);
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/IndefiniteTimingSpecifier.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/IndefiniteTimingSpecifier.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/IndefiniteTimingSpecifier.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,64 @@
+/*
+
+ 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.batik.anim.timing;
+
+/**
+ * A class to handle the 'indefinite' SMIL timing specifier.
+ *
+ * @author Cameron McCormack
+ * @version $Id: IndefiniteTimingSpecifier.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public class IndefiniteTimingSpecifier extends TimingSpecifier {
+
+ /**
+ * Creates a new IndefiniteTimingSpecifier object.
+ */
+ public IndefiniteTimingSpecifier(TimedElement owner, boolean isBegin) {
+ super(owner, isBegin);
+ }
+
+ /**
+ * Returns a string representation of this timing specifier.
+ */
+ public String toString() {
+ return "indefinite";
+ }
+
+ /**
+ * Initializes this timing specifier by adding the initial instance time
+ * to the owner's instance time list or setting up any event listeners.
+ */
+ public void initialize() {
+ if (!isBegin) {
+ // Only end instance lists get an 'indefinite' instance time from
+ // an indefinite timing specifier.
+ InstanceTime instance =
+ new InstanceTime(this, TimedElement.INDEFINITE, 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;
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/InstanceTime.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/InstanceTime.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/InstanceTime.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,117 @@
+/*
+
+ 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.batik.anim.timing;
+
+/**
+ * A class that represents an instance time created from a timing
+ * specification.
+ *
+ * @author Cameron McCormack
+ * @version $Id: InstanceTime.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public class InstanceTime implements Comparable {
+
+ /**
+ * The time.
+ */
+ protected float time;
+
+ /**
+ * The {@link TimingSpecifier} that created this InstanceTime.
+ */
+ protected TimingSpecifier creator;
+
+ /**
+ * Whether this InstanceTime should be removed from an element's
+ * begin or end instance time lists upon reset.
+ */
+ protected boolean clearOnReset;
+
+ /**
+ * Creates a new InstanceTime.
+ * @param creator the TimingSpecifier that created this InstanceTime
+ * @param time the new time, in parent simple time
+ * @param clearOnReset whether this InstanceTime should be removed from
+ * an instance time list upon element reset
+ */
+ public InstanceTime(TimingSpecifier creator,
+ float time,
+ boolean clearOnReset) {
+ // Trace.enter(this, null, new Object[] { creator, new Float(time), timebase, new Boolean(clearOnReset) } ); try {
+ this.creator = creator;
+ // XXX Convert time from the creator's syncbase's
+ // time system into this time system. Not
+ // strictly necessary in SVG.
+ this.time = time;
+ this.clearOnReset = clearOnReset;
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Returns whether the InstanceTime should be removed from the
+ * element's begin or end instance time list when it is reset.
+ */
+ public boolean getClearOnReset() {
+ return clearOnReset;
+ }
+
+ /**
+ * Returns the time of this instance time.
+ */
+ public float getTime() {
+ return time;
+ }
+
+ /**
+ * Called by the dependent Interval to indicate that its time
+ * has changed.
+ * @param newTime the new time, in parent simple time
+ */
+ float dependentUpdate(float newTime) {
+ // Trace.enter(this, "dependentUpdate", new Object[] { new Float(newTime) } ); try {
+ // XXX Convert time from the creator's syncbase's
+ // time system into this time system. Not
+ // strictly necessary in SVG.
+ time = newTime;
+ if (creator != null) {
+ return creator.handleTimebaseUpdate(this, time);
+ }
+ return Float.POSITIVE_INFINITY;
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Returns a string representation of this InstanceTime.
+ */
+ public String toString() {
+ return Float.toString(time);
+ }
+
+ // Comparable ////////////////////////////////////////////////////////////
+
+ /**
+ * Compares this InstanceTime with another.
+ */
+ public int compareTo(Object o) {
+ InstanceTime it = (InstanceTime)o;
+ if (time == it.time) return 0;
+ if (time > it.time) return 1;
+ return -1;
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/Interval.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/Interval.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/Interval.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,184 @@
+/*
+
+ 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.batik.anim.timing;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+/**
+ * A class that represents an interval for a timed element.
+ *
+ * @author Cameron McCormack
+ * @version $Id: Interval.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public class Interval {
+
+ /**
+ * The begin time for the interval.
+ */
+ protected float begin;
+
+ /**
+ * The end time for the interval.
+ */
+ protected float end;
+
+ /**
+ * The InstanceTime that defined the begin time of the current interval.
+ */
+ protected InstanceTime beginInstanceTime;
+
+ /**
+ * The InstanceTime that defined the end time of the current interval.
+ */
+ protected InstanceTime endInstanceTime;
+
+ /**
+ * The list of {@link InstanceTime} objects that are dependent
+ * on the begin time of this Interval.
+ */
+ protected LinkedList beginDependents = new LinkedList();
+
+ /**
+ * The list of {@link InstanceTime} objects that are dependent
+ * on the end time of this Interval.
+ */
+ protected LinkedList endDependents = new LinkedList();
+
+ /**
+ * Creates a new Interval.
+ * @param begin the begin time of the Interval
+ * @param end the end time of the Interval
+ * @param beginInstanceTime the {@link InstanceTime} object that defined
+ * the begin time of the Interval
+ * @param endInstanceTime the {@link InstanceTime} object that defined
+ * the end time of the Interval
+ */
+ public Interval(float begin, float end, InstanceTime beginInstanceTime,
+ InstanceTime endInstanceTime) {
+ // Trace.enter(this, null, new Object[] { new Float(begin), new Float(end), beginInstanceTime, endInstanceTime } ); try {
+ this.begin = begin;
+ this.end = end;
+ this.beginInstanceTime = beginInstanceTime;
+ this.endInstanceTime = endInstanceTime;
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Returns a string representation of this Interval.
+ */
+ public String toString() {
+ return TimedElement.toString(begin) + ".." + TimedElement.toString(end);
+ }
+
+ /**
+ * Returns the begin time of this interval.
+ */
+ public float getBegin() {
+ return begin;
+ }
+
+ /**
+ * Returns the end time of this interval.
+ */
+ public float getEnd() {
+ return end;
+ }
+
+ /**
+ * Returns the {@link InstanceTime} that defined the begin time of this
+ * interval.
+ */
+ public InstanceTime getBeginInstanceTime() {
+ return beginInstanceTime;
+ }
+
+ /**
+ * Returns the {@link InstanceTime} that defined the end time of this
+ * interval.
+ */
+ public InstanceTime getEndInstanceTime() {
+ return endInstanceTime;
+ }
+
+ /**
+ * Adds a dependent InstanceTime for this Interval.
+ */
+ void addDependent(InstanceTime dependent, boolean forBegin) {
+ // Trace.enter(this, "addDependent", new Object[] { dependent, new Boolean(forBegin) } ); try {
+ if (forBegin) {
+ beginDependents.add(dependent);
+ } else {
+ endDependents.add(dependent);
+ }
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Removes a dependent InstanceTime for this Interval.
+ */
+ void removeDependent(InstanceTime dependent, boolean forBegin) {
+ // Trace.enter(this, "removeDependent", new Object[] { dependent, new Boolean(forBegin) } ); try {
+ if (forBegin) {
+ beginDependents.remove(dependent);
+ } else {
+ endDependents.remove(dependent);
+ }
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Updates the begin time for this interval.
+ */
+ float setBegin(float begin) {
+ // Trace.enter(this, "setBegin", new Object[] { new Float(begin) } ); try {
+ float minTime = Float.POSITIVE_INFINITY;
+ this.begin = begin;
+ Iterator i = beginDependents.iterator();
+ while (i.hasNext()) {
+ InstanceTime it = (InstanceTime) i.next();
+ float t = it.dependentUpdate(begin);
+ if (t < minTime) {
+ minTime = t;
+ }
+ }
+ return minTime;
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Updates the end time for this interval.
+ */
+ float setEnd(float end, InstanceTime endInstanceTime) {
+ // Trace.enter(this, "setEnd", new Object[] { new Float(end) } ); try {
+ float minTime = Float.POSITIVE_INFINITY;
+ this.end = end;
+ this.endInstanceTime = endInstanceTime;
+ Iterator i = endDependents.iterator();
+ while (i.hasNext()) {
+ InstanceTime it = (InstanceTime) i.next();
+ float t = it.dependentUpdate(end);
+ if (t < minTime) {
+ minTime = t;
+ }
+ }
+ return minTime;
+ // } finally { Trace.exit(); }
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/MediaMarkerTimingSpecifier.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/MediaMarkerTimingSpecifier.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/MediaMarkerTimingSpecifier.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,75 @@
+/*
+
+ 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.batik.anim.timing;
+
+/**
+ * A class to handle media marker SMIL timing specifiers. This class
+ * of timing specifier is currently unused.
+ *
+ * @author Cameron McCormack
+ * @version $Id: MediaMarkerTimingSpecifier.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public class MediaMarkerTimingSpecifier extends TimingSpecifier {
+
+ /**
+ * The ID of the media element.
+ */
+ protected String syncbaseID;
+
+ /**
+ * The media element.
+ */
+ protected TimedElement mediaElement;
+
+ /**
+ * The media marker name.
+ */
+ protected String markerName;
+
+ /**
+ * The instance time.
+ */
+ protected InstanceTime instance;
+
+ /**
+ * Creates a new MediaMarkerTimingSpecifier object.
+ */
+ public MediaMarkerTimingSpecifier(TimedElement owner, boolean isBegin,
+ String syncbaseID, String markerName) {
+ super(owner, isBegin);
+ this.syncbaseID = syncbaseID;
+ this.markerName = markerName;
+ this.mediaElement = owner.getTimedElementById(syncbaseID);
+ }
+
+ /**
+ * Returns a string representation of this timing specifier.
+ */
+ 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;
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/OffsetTimingSpecifier.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/OffsetTimingSpecifier.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/OffsetTimingSpecifier.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,66 @@
+/*
+
+ 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.batik.anim.timing;
+
+/**
+ * A class to handle offset SMIL timing specifiers.
+ *
+ * @author Cameron McCormack
+ * @version $Id: OffsetTimingSpecifier.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public class OffsetTimingSpecifier extends TimingSpecifier {
+
+ /**
+ * The offset value.
+ */
+ protected float offset;
+
+ /**
+ * Creates a new OffsetTimingSpecifier object.
+ */
+ public OffsetTimingSpecifier(TimedElement owner, boolean isBegin,
+ float offset) {
+ super(owner, isBegin);
+ this.offset = offset;
+ }
+
+ /**
+ * Returns a string representation of this timing specifier.
+ */
+ public String toString() {
+ return (offset >= 0 ? "+" : "") + offset;
+ }
+
+ /**
+ * Initializes this timing specifier by adding the initial instance time
+ * to the owner's instance time list or setting up any event listeners.
+ */
+ public void initialize() {
+ InstanceTime instance = new InstanceTime(this, offset, 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;
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/RepeatTimingSpecifier.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/RepeatTimingSpecifier.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/RepeatTimingSpecifier.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,83 @@
+/*
+
+ 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.batik.anim.timing;
+
+import org.w3c.dom.events.Event;
+import org.w3c.dom.smil.TimeEvent;
+
+/**
+ * A class to handle repeat event SMIL timing specifiers.
+ *
+ * @author Cameron McCormack
+ * @version $Id: RepeatTimingSpecifier.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public class RepeatTimingSpecifier extends EventbaseTimingSpecifier {
+
+ /**
+ * The repeat iteration.
+ */
+ protected int repeatIteration;
+
+ /**
+ * Whether a repeat iteration was specified.
+ */
+ protected boolean repeatIterationSpecified;
+
+ /**
+ * Creates a new RepeatTimingSpecifier object without a repeat iteration.
+ */
+ public RepeatTimingSpecifier(TimedElement owner, boolean isBegin,
+ float offset, String syncbaseID) {
+ super(owner, isBegin, offset, syncbaseID,
+ owner.getRoot().getRepeatEventName());
+ }
+
+ /**
+ * Creates a new RepeatTimingSpecifier object with a repeat iteration.
+ */
+ public RepeatTimingSpecifier(TimedElement owner, boolean isBegin,
+ float offset, String syncbaseID,
+ int repeatIteration) {
+ super(owner, isBegin, offset, syncbaseID,
+ owner.getRoot().getRepeatEventName());
+ this.repeatIteration = repeatIteration;
+ this.repeatIterationSpecified = true;
+ }
+
+ /**
+ * Returns a string representation of this timing specifier.
+ */
+ public String toString() {
+ return (eventbaseID == null ? "" : eventbaseID + ".") + "repeat"
+ + (repeatIterationSpecified ? "(" + repeatIteration + ")" : "")
+ + (offset != 0 ? super.toString() : "");
+ }
+
+ // EventListener /////////////////////////////////////////////////////////
+
+ /**
+ * Handles an event fired on the eventbase element.
+ */
+ public void handleEvent(Event e) {
+ TimeEvent evt = (TimeEvent) e;
+ if (!repeatIterationSpecified || evt.getDetail() == repeatIteration) {
+ super.handleEvent(e);
+ }
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/SyncbaseTimingSpecifier.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/SyncbaseTimingSpecifier.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/SyncbaseTimingSpecifier.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,136 @@
+/*
+
+ 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.batik.anim.timing;
+
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+
+/**
+ * A class to handle syncbase SMIL timing specifiers.
+ *
+ * @author Cameron McCormack
+ * @version $Id: SyncbaseTimingSpecifier.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public class SyncbaseTimingSpecifier extends OffsetTimingSpecifier {
+
+ /**
+ * The ID of the syncbase element.
+ */
+ protected String syncbaseID;
+
+ /**
+ * The syncbase element.
+ */
+ protected TimedElement syncbaseElement;
+
+ /**
+ * Whether this specifier specifies a sync to the begin or the end
+ * of the syncbase element.
+ */
+ protected boolean syncBegin;
+
+ /**
+ * Map of {@link Interval}s to an
+ * {@link InstanceTime}.
+ */
+ protected HashMap instances = new HashMap();
+
+ /**
+ * Creates a new SyncbaseTimingSpecifier object.
+ */
+ public SyncbaseTimingSpecifier(TimedElement owner, boolean isBegin,
+ float offset, String syncbaseID,
+ boolean syncBegin) {
+ super(owner, isBegin, offset);
+ // Trace.enter(this, null, new Object[] { owner, new Boolean(isBegin), new Float(offset), syncbaseID, new Boolean(syncBegin) } ); try {
+ this.syncbaseID = syncbaseID;
+ this.syncBegin = syncBegin;
+ this.syncbaseElement = owner.getTimedElementById(syncbaseID);
+ syncbaseElement.addDependent(this, syncBegin);
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Returns a string representation of this timing specifier.
+ */
+ public String toString() {
+ return syncbaseID + "." + (syncBegin ? "begin" : "end")
+ + (offset != 0 ? super.toString() : "");
+ }
+
+ /**
+ * Initializes this timing specifier by adding the initial instance time
+ * to the owner's instance time list or setting up any event listeners.
+ */
+ public void initialize() {
+ }
+
+ /**
+ * 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.
+ */
+ float newInterval(Interval interval) {
+ // Trace.enter(this, "newInterval", new Object[] { interval } ); try {
+ if (owner.hasPropagated) {
+ return Float.POSITIVE_INFINITY;
+ }
+ InstanceTime instance =
+ new InstanceTime(this, (syncBegin ? interval.getBegin()
+ : interval.getEnd()) + offset,
+ true);
+ instances.put(interval, instance);
+ interval.addDependent(instance, syncBegin);
+ return owner.addInstanceTime(instance, isBegin);
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Called by the timebase element when it deletes an Interval.
+ */
+ float removeInterval(Interval interval) {
+ // Trace.enter(this, "removeInterval", new Object[] { interval } ); try {
+ if (owner.hasPropagated) {
+ return Float.POSITIVE_INFINITY;
+ }
+ InstanceTime instance = (InstanceTime) instances.get(interval);
+ interval.removeDependent(instance, syncBegin);
+ return owner.removeInstanceTime(instance, isBegin);
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Called by an {@link InstanceTime} created by this TimingSpecifier
+ * to indicate that its value has changed.
+ */
+ float handleTimebaseUpdate(InstanceTime instanceTime, float newTime) {
+ // Trace.enter(this, "handleTimebaseUpdate", new Object[] { instanceTime, new Float(newTime) } ); try {
+ if (owner.hasPropagated) {
+ return Float.POSITIVE_INFINITY;
+ }
+ return owner.instanceTimeChanged(instanceTime, isBegin);
+ // } finally { Trace.exit(); }
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/TimeContainer.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/TimeContainer.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/TimeContainer.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,147 @@
+/*
+
+ 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.batik.anim.timing;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * An abstract base class for time container elements.
+ *
+ * @author Cameron McCormack
+ * @version $Id: TimeContainer.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public abstract class TimeContainer extends TimedElement {
+
+ /**
+ * The child {@link TimedElement}s of this time container.
+ */
+ protected List children = new LinkedList();
+
+ /**
+ * Adds a {@link TimedElement} to this container.
+ */
+ public void addChild(TimedElement e) {
+ if (e == this) {
+ throw new IllegalArgumentException("recursive datastructure not allowed here!");
+ }
+ children.add(e);
+ e.parent = this;
+ setRoot(e, root);
+ root.fireElementAdded(e);
+ root.currentIntervalWillUpdate();
+ }
+
+ /**
+ * Recursively sets the {@link TimedDocumentRoot} of the given
+ * {@link TimedElement} and any of its descendants.
+ */
+ protected void setRoot(TimedElement e, TimedDocumentRoot root) {
+ e.root = root;
+ if (e instanceof TimeContainer) {
+ TimeContainer c = (TimeContainer) e;
+ Iterator it = c.children.iterator();
+ while (it.hasNext()) {
+ TimedElement te = (TimedElement)it.next();
+ setRoot(te, root);
+ }
+ }
+ }
+
+ /**
+ * Removes a {@link TimedElement} from this container.
+ */
+ public void removeChild(TimedElement e) {
+ children.remove(e);
+ e.parent = null;
+ setRoot(e, null);
+ root.fireElementRemoved(e);
+ root.currentIntervalWillUpdate();
+ }
+
+ /**
+ * Returns an array of the children of this container.
+ */
+ public TimedElement[] getChildren() {
+ return (TimedElement[]) children.toArray(new TimedElement[0]);
+ }
+
+ /**
+ * Calculates the local simple time. Currently the hyperlinking parameter
+ * is ignored, so DOM timing events are fired during hyperlinking seeks.
+ * If we were following SMIL 2.1 rather than SMIL Animation, then these
+ * events would have to be surpressed.
+ *
+ * @return the number of seconds until this element becomes active again
+ * if it currently is not, {@link Float#POSITIVE_INFINITY} if this
+ * element will become active at some undetermined point in the
+ * future (because of unresolved begin times, for example) or
+ * will never become active again, or 0f
if the
+ * element is currently active.
+ */
+ protected float sampleAt(float parentSimpleTime, boolean hyperlinking) {
+ super.sampleAt(parentSimpleTime, hyperlinking);
+ // Maybe check the return value of the previous statement.
+ return sampleChildren(parentSimpleTime, hyperlinking);
+ }
+
+ /**
+ * Samples all the child timed elements.
+ */
+ protected float sampleChildren(float parentSimpleTime,
+ boolean hyperlinking) {
+ float mint = Float.POSITIVE_INFINITY;
+ Iterator i = children.iterator();
+ while (i.hasNext()) {
+ TimedElement e = (TimedElement) i.next();
+ float t = e.sampleAt(parentSimpleTime, hyperlinking);
+ if (t < mint) {
+ mint = t;
+ }
+ }
+ return mint;
+ }
+
+ /**
+ * Resets this element.
+ */
+ protected void reset(boolean clearCurrentBegin) {
+ super.reset(clearCurrentBegin);
+ Iterator i = children.iterator();
+ while (i.hasNext()) {
+ TimedElement e = (TimedElement) i.next();
+ e.reset(clearCurrentBegin);
+ }
+ }
+
+ /**
+ * Returns whether this timed element is for a constant animation (i.e., a
+ * 'set' animation.
+ */
+ protected boolean isConstantAnimation() {
+ return false;
+ }
+
+ /**
+ * Returns the default begin time for the given child
+ * timed element.
+ */
+ public abstract float getDefaultBegin(TimedElement child);
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/TimedDocumentRoot.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/TimedDocumentRoot.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/TimedDocumentRoot.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,288 @@
+/*
+
+ 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.batik.anim.timing;
+
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.apache.batik.util.DoublyIndexedSet;
+
+/**
+ * An abstract base class for the root time container element
+ * for a document.
+ *
+ * @author Cameron McCormack
+ * @version $Id: TimedDocumentRoot.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public abstract class TimedDocumentRoot extends TimeContainer {
+
+ /**
+ * The wallclock time that the document began.
+ */
+ protected Calendar documentBeginTime;
+
+ /**
+ * Allows the use of accessKey() timing specifiers with a single
+ * character, as specified in SVG 1.1.
+ */
+ protected boolean useSVG11AccessKeys;
+
+ /**
+ * Allows the use of accessKey() timing specifiers with a DOM 3
+ * key name, as specified in SVG 1.2.
+ */
+ protected boolean useSVG12AccessKeys;
+
+ /**
+ * A set to determine when propagation of new Instance times should
+ * be stopped.
+ */
+ protected DoublyIndexedSet propagationFlags = new DoublyIndexedSet();
+
+ /**
+ * List of {link TimegraphListener}s to be notified of changes to the
+ * timed elements in this document.
+ */
+ protected LinkedList listeners = new LinkedList();
+
+ /**
+ * Whether the document is currently being sampled.
+ */
+ protected boolean isSampling;
+
+ /**
+ * Whether the document is currently being sampled for a hyperlink.
+ */
+ protected boolean isHyperlinking;
+
+ /**
+ * Creates a new TimedDocumentRoot.
+ * @param useSVG11AccessKeys allows the use of accessKey() timing
+ * specifiers with a single character
+ * @param useSVG12AccessKeys allows the use of accessKey() with a
+ * DOM 3 key name
+ */
+ public TimedDocumentRoot(boolean useSVG11AccessKeys,
+ boolean useSVG12AccessKeys) {
+ root = this;
+ this.useSVG11AccessKeys = useSVG11AccessKeys;
+ this.useSVG12AccessKeys = useSVG12AccessKeys;
+ }
+
+ /**
+ * Returns the implicit duration of the element. The document root
+ * has an {@link #INDEFINITE} implicit duration.
+ */
+ protected float getImplicitDur() {
+ return INDEFINITE;
+ }
+
+ /**
+ * Returns the default begin time for the given child
+ * timed element. In SVG, this is always 0, since the
+ * only time container is the root SVG element, which acts
+ * like a 'par'.
+ */
+ public float getDefaultBegin(TimedElement child) {
+ return 0.0f;
+ }
+
+ /**
+ * Returns the last sampled document time.
+ */
+ public float getCurrentTime() {
+ return lastSampleTime;
+ }
+
+ /**
+ * Returns whether the document is currently being sampled.
+ */
+ public boolean isSampling() {
+ return isSampling;
+ }
+
+ /**
+ * Returns whether the document is currently being sampled for a hyperlink.
+ */
+ public boolean isHyperlinking() {
+ return isHyperlinking;
+ }
+
+ /**
+ * Samples the entire timegraph at the given time.
+ */
+ public float seekTo(float time, boolean hyperlinking) {
+ // Trace.enter(this, "seekTo", new Object[] { new Float(time) } ); try {
+ isSampling = true;
+ lastSampleTime = time;
+ isHyperlinking = hyperlinking;
+ propagationFlags.clear();
+ // No time containers in SVG, so we don't have to worry
+ // about a partial ordering of timed elements to sample.
+ float mint = Float.POSITIVE_INFINITY;
+ TimedElement[] es = getChildren();
+ for (int i = 0; i < es.length; i++) {
+ float t = es[i].sampleAt(time, hyperlinking);
+ if (t < mint) {
+ mint = t;
+ }
+ }
+ boolean needsUpdates;
+ do {
+ needsUpdates = false;
+ for (int i = 0; i < es.length; i++) {
+ if (es[i].shouldUpdateCurrentInterval) {
+ needsUpdates = true;
+ // System.err.print("{" + ((Test.AnimateElement) es[i]).id + "} ");
+ float t = es[i].sampleAt(time, hyperlinking);
+ if (t < mint) {
+ mint = t;
+ }
+ }
+ }
+ } while (needsUpdates);
+ isSampling = false;
+ if (hyperlinking) {
+ root.currentIntervalWillUpdate();
+ }
+ return mint;
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Resets the entire timegraph.
+ */
+ public void resetDocument(Calendar documentBeginTime) {
+ if (documentBeginTime == null) {
+ this.documentBeginTime = Calendar.getInstance();
+ } else {
+ this.documentBeginTime = documentBeginTime;
+ }
+ reset(true);
+ }
+
+ /**
+ * Returns the wallclock time that the document began.
+ */
+ public Calendar getDocumentBeginTime() {
+ return documentBeginTime;
+ }
+
+ /**
+ * Converts an epoch time to document time.
+ */
+ public float convertEpochTime(long t) {
+ long begin = documentBeginTime.getTime().getTime();
+ return (t - begin) / 1000f;
+ }
+
+ /**
+ * Converts a wallclock time to document time.
+ */
+ public float convertWallclockTime(Calendar time) {
+ long begin = documentBeginTime.getTime().getTime();
+ long t = time.getTime().getTime();
+ return (t - begin) / 1000f;
+ }
+
+ /**
+ * Adds a {@link TimegraphListener} to the document.
+ */
+ public void addTimegraphListener(TimegraphListener l) {
+ listeners.add(l);
+ }
+
+ /**
+ * Removes a {@link TimegraphListener} from the document.
+ */
+ public void removeTimegraphListener(TimegraphListener l) {
+ listeners.remove(l);
+ }
+
+ /**
+ * Fires an {@link TimegraphListener#elementAdded} event on all
+ * timegraph listeners.
+ */
+ void fireElementAdded(TimedElement e) {
+ Iterator i = listeners.iterator();
+ while (i.hasNext()) {
+ ((TimegraphListener) i.next()).elementAdded(e);
+ }
+ }
+
+ /**
+ * Fires an {@link TimegraphListener#elementRemoved} event on all
+ * timegraph listeners.
+ */
+ void fireElementRemoved(TimedElement e) {
+ Iterator i = listeners.iterator();
+ while (i.hasNext()) {
+ ((TimegraphListener) i.next()).elementRemoved(e);
+ }
+ }
+
+ // XXX Add fire* methods for the other events in TimegraphListener, and make
+ // TimedElement fire them.
+
+ /**
+ * Returns whether the specified newly created {@link Interval} should
+ * propagate its times to the given {@link TimingSpecifier}.
+ * @param i the Interval that has just been created
+ * @param ts the TimingSpecifier that is a dependent of the Interval
+ * @param isBegin whether the dependency is on the begin or end time of
+ * the Interval
+ */
+ boolean shouldPropagate(Interval i, TimingSpecifier ts, boolean isBegin) {
+ InstanceTime it = isBegin ? i.getBeginInstanceTime()
+ : i.getEndInstanceTime();
+ if (propagationFlags.contains(it, ts)) {
+ return false;
+ }
+ propagationFlags.add(it, ts);
+ return true;
+ }
+
+ /**
+ * Invoked by timed elements in this document to indicate that the current
+ * interval will be re-evaluated at the next sample. This should be
+ * overridden in a concrete class so that ticks can be scheduled immediately
+ * if they are currently paused due to no animations being active.
+ */
+ protected void currentIntervalWillUpdate() {
+ }
+
+ /**
+ * Returns the namespace URI of the event that corresponds to the given
+ * animation event name.
+ */
+ protected abstract String getEventNamespaceURI(String eventName);
+
+ /**
+ * Returns the type of the event that corresponds to the given
+ * animation event name.
+ */
+ protected abstract String getEventType(String eventName);
+
+ /**
+ * Returns the name of the repeat event.
+ * @return either "repeat" or "repeatEvent"
+ */
+ protected abstract String getRepeatEventName();
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/TimedElement.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/TimedElement.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/TimedElement.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,1575 @@
+/*
+
+ 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.batik.anim.timing;
+
+import java.util.*;
+
+import org.apache.batik.anim.AnimationException;
+import org.apache.batik.i18n.LocalizableSupport;
+import org.apache.batik.parser.ClockHandler;
+import org.apache.batik.parser.ClockParser;
+import org.apache.batik.parser.ParseException;
+import org.apache.batik.util.SMILConstants;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.events.Event;
+import org.w3c.dom.events.EventTarget;
+
+/**
+ * An abstract base class for elements that can have timing applied to them.
+ * The concrete versions of this class do not necessarily have to be the
+ * same as the DOM class, and in fact, this will mostly be impossible unless
+ * creating new DOM classes that inherit from these elements.
+ *
+ * @author Cameron McCormack
+ * @version $Id: TimedElement.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public abstract class TimedElement implements SMILConstants {
+
+ // Constants for fill mode.
+ public static final int FILL_REMOVE = 0;
+ public static final int FILL_FREEZE = 1;
+
+ // Constants for restart mode.
+ public static final int RESTART_ALWAYS = 0;
+ public static final int RESTART_WHEN_NOT_ACTIVE = 1;
+ public static final int RESTART_NEVER = 2;
+
+ // Constants for time values.
+ public static final float INDEFINITE = Float.POSITIVE_INFINITY;
+ public static final float UNRESOLVED = Float.NaN;
+
+ /**
+ * The root time container.
+ */
+ protected TimedDocumentRoot root;
+
+ /**
+ * The parent time container.
+ */
+ protected TimeContainer parent;
+
+ /**
+ * Timing specifiers for the begin times of this element.
+ */
+ protected TimingSpecifier[] beginTimes;
+
+ /**
+ * Timing specifiers for the end times of this element.
+ */
+ protected TimingSpecifier[] endTimes;
+
+ /**
+ * Duration of this element, if {@link #durMedia} = false
.
+ * If unspecified, it will be {@link #UNRESOLVED}.
+ */
+ protected float simpleDur;
+
+ /**
+ * Whether the simple duration of this element should be equal
+ * to the implicit duration.
+ */
+ protected boolean durMedia;
+
+ /**
+ * The number of repeats. If unspecified, it will be
+ * {@link #UNRESOLVED}.
+ */
+ protected float repeatCount;
+
+ /**
+ * The duration of repeats. If unspecified, it will be
+ * {@link #UNRESOLVED}.
+ */
+ protected float repeatDur;
+
+ /**
+ * The current repeat iteration.
+ */
+ protected int currentRepeatIteration;
+
+ /**
+ * The local active time of the last repeat.
+ */
+ protected float lastRepeatTime;
+
+ /**
+ * The fill mode for this element. Uses the FILL_* constants
+ * defined in this class.
+ */
+ protected int fillMode;
+
+ /**
+ * The restart mode for this element. Uses the RESTART_* constants
+ * defined in this class.
+ */
+ protected int restartMode;
+
+ /**
+ * The minimum active duration of this element. If {@link #minMedia}
+ * = true
, it will be 0f
.
+ */
+ protected float min;
+
+ /**
+ * Whether the min value was specified as 'media'.
+ */
+ protected boolean minMedia;
+
+ /**
+ * The maximum active duration of this element. If {@link #maxMedia}
+ * = true
, it will be {@link #INDEFINITE}.
+ */
+ protected float max;
+
+ /**
+ * Whether the max value was specified as 'media'.
+ */
+ protected boolean maxMedia;
+
+ /**
+ * Whether the element is currently active.
+ */
+ protected boolean isActive;
+
+ /**
+ * Whether the element is currently frozen.
+ */
+ protected boolean isFrozen;
+
+ /**
+ * The current time of this element in local active time.
+ */
+ protected float lastSampleTime;
+
+ /**
+ * The computed repeat duration of the element.
+ */
+ protected float repeatDuration;
+
+ /**
+ * List of begin InstanceTimes.
+ */
+ protected List beginInstanceTimes = new ArrayList();
+
+ /**
+ * List of end InstanceTimes.
+ */
+ protected List endInstanceTimes = new ArrayList();
+
+ /**
+ * The current Interval.
+ */
+ protected Interval currentInterval;
+
+ /**
+ * The end time of the previous interval, initially
+ * {@link Float#NEGATIVE_INFINITY}.
+ */
+ protected float lastIntervalEnd;
+
+ /**
+ * List of previous intervals.
+ */
+ // protected LinkedList previousIntervals = new LinkedList();
+
+ /**
+ * The previous interval.
+ */
+ protected Interval previousInterval;
+
+ /**
+ * List of TimingSpecifiers on other elements that depend on this
+ * element's begin times.
+ */
+ protected LinkedList beginDependents = new LinkedList();
+
+ /**
+ * List of TimingSpecifiers on other elements that depend on this
+ * element's end times.
+ */
+ protected LinkedList endDependents = new LinkedList();
+
+ /**
+ * Whether the list of instance times should be checked to update
+ * the current interval.
+ */
+ protected boolean shouldUpdateCurrentInterval = true;
+
+ /**
+ * Whether this timed element has parsed its timing attributes yet.
+ */
+ protected boolean hasParsed;
+
+ /**
+ * Map of {@link Event} objects to {@link HashSet}s of {@link
+ * TimingSpecifier}s that caught them.
+ */
+ protected Map handledEvents = new HashMap();
+
+ /**
+ * Whether this timed element is currently being sampled.
+ */
+ protected boolean isSampling;
+
+ /**
+ * Whether an instance time update message has already been propagated to
+ * this timed element.
+ */
+ protected boolean hasPropagated;
+
+ /**
+ * Creates a new TimedElement.
+ */
+ public TimedElement() {
+ beginTimes = new TimingSpecifier[0];
+ endTimes = beginTimes;
+ simpleDur = UNRESOLVED;
+ repeatCount = UNRESOLVED;
+ repeatDur = UNRESOLVED;
+ lastRepeatTime = UNRESOLVED;
+ max = INDEFINITE;
+ lastSampleTime = UNRESOLVED;
+ lastIntervalEnd = Float.NEGATIVE_INFINITY;
+ }
+
+ /**
+ * Returns the root time container of this timed element.
+ */
+ public TimedDocumentRoot getRoot() {
+ return root;
+ }
+
+ /**
+ * Returns the current active time of this element.
+ */
+ public float getActiveTime() {
+ return lastSampleTime;
+ }
+
+ /**
+ * Returns the current simple time of this element.
+ */
+ public float getSimpleTime() {
+ return lastSampleTime - lastRepeatTime;
+ }
+
+ /**
+ * Called by a TimingSpecifier of this element when a new
+ * InstanceTime is created. This will be in response to an event
+ * firing, a DOM method being called or a new Instance being
+ * created by a syncbase element.
+ */
+ protected float addInstanceTime(InstanceTime time, boolean isBegin) {
+ // Trace.enter(this, "addInstanceTime", new Object[] { time, new Boolean(isBegin) } ); try {
+ hasPropagated = true;
+ List instanceTimes = isBegin ? beginInstanceTimes : endInstanceTimes;
+ int index = Collections.binarySearch(instanceTimes, time);
+ if (index < 0) {
+ index = -(index + 1);
+ }
+ instanceTimes.add(index, time);
+ shouldUpdateCurrentInterval = true;
+ float ret;
+ if (root.isSampling() && !isSampling) {
+ ret = sampleAt(root.getCurrentTime(), root.isHyperlinking());
+ } else {
+ ret = Float.POSITIVE_INFINITY;
+ }
+ hasPropagated = false;
+ root.currentIntervalWillUpdate();
+ return ret;
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Called by a TimingSpecifier of this element when an InstanceTime
+ * should be removed. This will be in response to the pruning of an
+ * Interval.
+ */
+ protected float removeInstanceTime(InstanceTime time, boolean isBegin) {
+ // Trace.enter(this, "removeInstanceTime", new Object[] { time, new Boolean(isBegin) } ); try {
+ hasPropagated = true;
+ List instanceTimes = isBegin ? beginInstanceTimes : endInstanceTimes;
+ int index = Collections.binarySearch(instanceTimes, time);
+ for (int i = index; i >= 0; i--) {
+ InstanceTime it = (InstanceTime) instanceTimes.get(i);
+ if (it == time) {
+ instanceTimes.remove(i);
+ break;
+ }
+ if (it.compareTo(time) != 0) {
+ break;
+ }
+ }
+ int len = instanceTimes.size();
+ for (int i = index + 1; i < len; i++) {
+ InstanceTime it = (InstanceTime) instanceTimes.get(i);
+ if (it == time) {
+ instanceTimes.remove(i);
+ break;
+ }
+ if (it.compareTo(time) != 0) {
+ break;
+ }
+ }
+ shouldUpdateCurrentInterval = true;
+ float ret;
+ if (root.isSampling() && !isSampling) {
+ ret = sampleAt(root.getCurrentTime(), root.isHyperlinking());
+ } else {
+ ret = Float.POSITIVE_INFINITY;
+ }
+ hasPropagated = false;
+ root.currentIntervalWillUpdate();
+ return ret;
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Called by a TimingSpecifier of this element when an InstanceTime
+ * has been updated. This will be in response to a dependent
+ * syncbase change.
+ */
+ protected float instanceTimeChanged(InstanceTime time, boolean isBegin) {
+ // Trace.enter(this, "instanceTimeChanged", new Object[] { time, new Boolean(isBegin) } ); try {
+ hasPropagated = true;
+ shouldUpdateCurrentInterval = true;
+ float ret;
+ if (root.isSampling() && !isSampling) {
+ ret = sampleAt(root.getCurrentTime(), root.isHyperlinking());
+ } else {
+ ret = Float.POSITIVE_INFINITY;
+ }
+ hasPropagated = false;
+ return ret;
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Adds a dependent TimingSpecifier for this element.
+ */
+ protected void addDependent(TimingSpecifier dependent, boolean forBegin) {
+ // Trace.enter(this, "addDependent", new Object[] { dependent, new Boolean(forBegin) } ); try {
+ if (forBegin) {
+ beginDependents.add(dependent);
+ } else {
+ endDependents.add(dependent);
+ }
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Removes a dependent TimingSpecifier for this element.
+ */
+ protected void removeDependent(TimingSpecifier dependent,
+ boolean forBegin) {
+ // Trace.enter(this, "removeDependent", new Object[] { dependent, new Boolean(forBegin) } ); try {
+ if (forBegin) {
+ beginDependents.remove(dependent);
+ } else {
+ endDependents.remove(dependent);
+ }
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Returns the simple duration time of this element.
+ */
+ public float getSimpleDur() {
+ if (durMedia) {
+ return getImplicitDur();
+ } else if (isUnresolved(simpleDur)) {
+ if (isUnresolved(repeatCount) && isUnresolved(repeatDur)
+ && endTimes.length > 0) {
+ return INDEFINITE;
+ }
+ return getImplicitDur();
+ } else {
+ return simpleDur;
+ }
+ }
+
+ /**
+ * Returns whether the given time value is equal to the
+ * {@link #UNRESOLVED} value.
+ */
+ public static boolean isUnresolved(float t) {
+ return Float.isNaN(t);
+ }
+
+ /**
+ * Returns the active duration time of this element.
+ */
+ public float getActiveDur(float B, float end) {
+ float d = getSimpleDur();
+ float PAD;
+ if (!isUnresolved(end) && d == INDEFINITE) {
+ PAD = minusTime(end, B);
+ repeatDuration = minTime(max, maxTime(min, PAD));
+ return repeatDuration;
+ }
+
+ float IAD;
+ if (d == 0) {
+ IAD = 0;
+ } else {
+ if (isUnresolved(repeatDur) && isUnresolved(repeatCount)) {
+ IAD = d;
+ } else {
+ float p1 = isUnresolved(repeatCount)
+ ? INDEFINITE
+ : multiplyTime(d, repeatCount);
+ float p2 = isUnresolved(repeatDur)
+ ? INDEFINITE
+ : repeatDur;
+ IAD = minTime(minTime(p1, p2), INDEFINITE);
+ }
+ }
+ if (isUnresolved(end) || end == INDEFINITE) {
+ PAD = IAD;
+ } else {
+ PAD = minTime(IAD, minusTime(end, B));
+ }
+ repeatDuration = IAD;
+ return minTime(max, maxTime(min, PAD));
+ }
+
+ /**
+ * Subtracts one simple time from another.
+ */
+ protected float minusTime(float t1, float t2) {
+ if (isUnresolved(t1) || isUnresolved(t2)) {
+ return UNRESOLVED;
+ }
+ if (t1 == INDEFINITE || t2 == INDEFINITE) {
+ return INDEFINITE;
+ }
+ return t1 - t2;
+ }
+
+ /**
+ * Multiplies one simple time by n.
+ */
+ protected float multiplyTime(float t, float n) {
+ if (isUnresolved(t) || t == INDEFINITE) {
+ return t;
+ }
+ return t * n;
+ }
+
+ /**
+ * Returns the minimum of two time values.
+ */
+ protected float minTime(float t1, float t2) {
+ if (t1 == 0.0f || t2 == 0.0f) {
+ return 0.0f;
+ }
+ if ((t1 == INDEFINITE || isUnresolved(t1))
+ && t2 != INDEFINITE && !isUnresolved(t2)) {
+ return t2;
+ }
+ if ((t2 == INDEFINITE || isUnresolved(t2))
+ && t1 != INDEFINITE && !isUnresolved(t1)) {
+ return t1;
+ }
+ if (t1 == INDEFINITE && isUnresolved(t2)
+ || isUnresolved(t1) && t2 == INDEFINITE) {
+ return INDEFINITE;
+ }
+ if (t1 < t2) {
+ return t1;
+ }
+ return t2;
+ }
+
+ /**
+ * Returns the maximum of two time values.
+ */
+ protected float maxTime(float t1, float t2) {
+ if ((t1 == INDEFINITE || isUnresolved(t1))
+ && t2 != INDEFINITE && !isUnresolved(t2)) {
+ return t1;
+ }
+ if ((t2 == INDEFINITE || isUnresolved(t2))
+ && t1 != INDEFINITE && !isUnresolved(t1)) {
+ return t2;
+ }
+ if (t1 == INDEFINITE && isUnresolved(t2)
+ || isUnresolved(t1) && t2 == INDEFINITE) {
+ return UNRESOLVED;
+ }
+ if (t1 > t2) {
+ return t1;
+ }
+ return t2;
+ }
+
+ /**
+ * Returns the implicit duration of the element. Currently, nested time
+ * containers are not supported by SVG so this just returns
+ * {@link #UNRESOLVED} by default. This should be overriden in derived
+ * classes that play media, since they will have an implicit duration.
+ */
+ protected float getImplicitDur() {
+ return UNRESOLVED;
+ }
+
+ /**
+ * Notifies dependents of a new interval.
+ */
+ protected float notifyNewInterval(Interval interval) {
+ // Trace.enter(this, "notifyNewInterval", new Object[] { interval } ); try {
+ float dependentMinTime = Float.POSITIVE_INFINITY;
+ Iterator i = beginDependents.iterator();
+ while (i.hasNext()) {
+ TimingSpecifier ts = (TimingSpecifier) i.next();
+ // Trace.print(ts.owner + "'s " + (ts.isBegin ? "begin" : "end" ) + ": " + ts);
+ float t = ts.newInterval(interval);
+ if (t < dependentMinTime) {
+ dependentMinTime = t;
+ }
+ }
+ i = endDependents.iterator();
+ while (i.hasNext()) {
+ TimingSpecifier ts = (TimingSpecifier) i.next();
+ // Trace.print(ts.owner + "'s " + (ts.isBegin ? "begin" : "end" ) + ": " + ts);
+ float t = ts.newInterval(interval);
+ if (t < dependentMinTime) {
+ dependentMinTime = t;
+ }
+ }
+ return dependentMinTime;
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Notifies dependents of a removed interval.
+ */
+ protected float notifyRemoveInterval(Interval interval) {
+ // Trace.enter(this, "notifyRemoveInterval", new Object[] { interval } ); try {
+ float dependentMinTime = Float.POSITIVE_INFINITY;
+ Iterator i = beginDependents.iterator();
+ while (i.hasNext()) {
+ TimingSpecifier ts = (TimingSpecifier) i.next();
+ float t = ts.removeInterval(interval);
+ if (t < dependentMinTime) {
+ dependentMinTime = t;
+ }
+ }
+ i = endDependents.iterator();
+ while (i.hasNext()) {
+ TimingSpecifier ts = (TimingSpecifier) i.next();
+ float t = ts.removeInterval(interval);
+ if (t < dependentMinTime) {
+ dependentMinTime = t;
+ }
+ }
+ return dependentMinTime;
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Calculates the local simple time. Currently the hyperlinking parameter
+ * is ignored, so DOM timing events are fired during hyperlinking seeks.
+ * If we were following SMIL 2.1 rather than SMIL Animation, then these
+ * events would have to be suppressed.
+ *
+ * @return the number of seconds until this element becomes active again
+ * if it currently is not, {@link Float#POSITIVE_INFINITY} if this
+ * element will become active at some undetermined point in the
+ * future (because of unresolved begin times, for example) or
+ * will never become active again, or 0f
if the
+ * element is currently active.
+ */
+ protected float sampleAt(float parentSimpleTime, boolean hyperlinking) {
+ // Trace.enter(this, "sampleAt", new Object[] { new Float(parentSimpleTime) } ); try {
+ isSampling = true;
+
+ float time = parentSimpleTime; // No time containers in SVG.
+
+ // First, process any events that occurred since the last sampling,
+ // taking into account event sensitivity.
+ Iterator i = handledEvents.entrySet().iterator();
+ while (i.hasNext()) {
+ Map.Entry e = (Map.Entry) i.next();
+ Event evt = (Event) e.getKey();
+ Set ts = (Set) e.getValue();
+ Iterator j = ts.iterator();
+ boolean hasBegin = false, hasEnd = false;
+ while (j.hasNext() && !(hasBegin && hasEnd)) {
+ EventLikeTimingSpecifier t =
+ (EventLikeTimingSpecifier) j.next();
+ if (t.isBegin()) {
+ hasBegin = true;
+ } else {
+ hasEnd = true;
+ }
+ }
+ boolean useBegin, useEnd;
+ if (hasBegin && hasEnd) {
+ useBegin = !isActive || restartMode == RESTART_ALWAYS;
+ useEnd = !useBegin;
+ } else if (hasBegin && (!isActive ||
+ restartMode == RESTART_ALWAYS)) {
+ useBegin = true;
+ useEnd = false;
+ } else if (hasEnd && isActive) {
+ useBegin = false;
+ useEnd = true;
+ } else {
+ continue;
+ }
+ j = ts.iterator();
+ while (j.hasNext()) {
+ EventLikeTimingSpecifier t =
+ (EventLikeTimingSpecifier) j.next();
+ boolean isBegin = t.isBegin();
+ if (isBegin && useBegin || !isBegin && useEnd) {
+ t.resolve(evt);
+ shouldUpdateCurrentInterval = true;
+ }
+ }
+ }
+ handledEvents.clear();
+
+ // Now process intervals.
+ if (currentInterval != null) {
+ float begin = currentInterval.getBegin();
+ if (lastSampleTime < begin && time >= begin) {
+ if (!isActive) {
+ toActive(begin);
+ }
+ isActive = true;
+ isFrozen = false;
+ lastRepeatTime = begin;
+ fireTimeEvent
+ (SMIL_BEGIN_EVENT_NAME, currentInterval.getBegin(), 0);
+ }
+ }
+ // For each sample, we might need to update the current interval's
+ // begin and end times, or end the current interval and compute
+ // a new one.
+ boolean hasEnded = currentInterval != null
+ && time >= currentInterval.getEnd();
+ // Fire any repeat events that should have been fired since the
+ // last sample.
+ if (currentInterval != null) {
+ float begin = currentInterval.getBegin();
+ if (time >= begin) {
+ float d = getSimpleDur();
+ while (time - lastRepeatTime >= d
+ && lastRepeatTime + d < begin + repeatDuration) {
+ lastRepeatTime += d;
+ currentRepeatIteration++;
+ fireTimeEvent(root.getRepeatEventName(), lastRepeatTime,
+ currentRepeatIteration);
+ }
+ }
+ }
+
+ // Trace.print("begin loop");
+ float dependentMinTime = Float.POSITIVE_INFINITY;
+ if (hyperlinking) {
+ shouldUpdateCurrentInterval = true;
+ }
+ while (shouldUpdateCurrentInterval || hasEnded) {
+ if (hasEnded) {
+ // previousIntervals.add(currentInterval);
+ previousInterval = currentInterval;
+ isActive = false;
+ isFrozen = fillMode == FILL_FREEZE;
+ toInactive(false, isFrozen);
+ fireTimeEvent(SMIL_END_EVENT_NAME, currentInterval.getEnd(), 0);
+ }
+ boolean first =
+ // currentInterval == null && previousIntervals.isEmpty();
+ currentInterval == null && previousInterval == null;
+ if (currentInterval != null && hyperlinking) {
+ // Hyperlinking, so remove the current interval and force a new
+ // one to be computed.
+ isActive = false;
+ isFrozen = false;
+ toInactive(false, false);
+ currentInterval = null;
+ // fireTimeEvent(SMIL_END_EVENT_NAME, currentInterval.getEnd(), 0);
+ }
+ if (currentInterval == null || hasEnded) {
+ if (first || hyperlinking || restartMode != RESTART_NEVER) {
+ float beginAfter;
+ boolean incl = true;
+ if (first || hyperlinking) {
+ beginAfter = Float.NEGATIVE_INFINITY;
+ } else {
+ // beginAfter = ((Interval) previousIntervals.getLast()).getEnd();
+ beginAfter = previousInterval.getEnd();
+ incl = beginAfter != previousInterval.getBegin();
+ }
+ Interval interval =
+ computeInterval(first, false, beginAfter, incl);
+ if (interval == null) {
+ currentInterval = null;
+ } else {
+ float dmt = selectNewInterval(time, interval);
+ if (dmt < dependentMinTime) {
+ dependentMinTime = dmt;
+ }
+ }
+ } else {
+ currentInterval = null;
+ }
+ } else {
+ float currentBegin = currentInterval.getBegin();
+ if (currentBegin > time) {
+ // Interval hasn't started yet.
+ float beginAfter;
+ boolean incl = true;
+ // if (previousIntervals.isEmpty()) {
+ if (previousInterval == null) {
+ beginAfter = Float.NEGATIVE_INFINITY;
+ } else {
+ // beginAfter = ((Interval) previousIntervals.getLast()).getEnd();
+ beginAfter = previousInterval.getEnd();
+ incl = beginAfter != previousInterval.getBegin();
+ }
+ Interval interval =
+ computeInterval(false, false, beginAfter, incl);
+ float dmt = notifyRemoveInterval(currentInterval);
+ if (dmt < dependentMinTime) {
+ dependentMinTime = dmt;
+ }
+ if (interval == null) {
+ currentInterval = null;
+ } else {
+ dmt = selectNewInterval(time, interval);
+ if (dmt < dependentMinTime) {
+ dependentMinTime = dmt;
+ }
+ }
+ } else {
+ // Interval has already started.
+ Interval interval =
+ computeInterval(false, true, currentBegin, true);
+ float newEnd = interval.getEnd();
+ if (currentInterval.getEnd() != newEnd) {
+ float dmt =
+ currentInterval.setEnd
+ (newEnd, interval.getEndInstanceTime());
+ if (dmt < dependentMinTime) {
+ dependentMinTime = dmt;
+ }
+ }
+ }
+ }
+ shouldUpdateCurrentInterval = false;
+ hyperlinking = false;
+ hasEnded = currentInterval != null && time >= currentInterval.getEnd();
+ }
+ // Trace.print("end loop");
+
+ float d = getSimpleDur();
+ if (isActive && !isFrozen) {
+ if (time - currentInterval.getBegin() >= repeatDuration) {
+ // Trace.print("element between repeat and active duration");
+ isFrozen = fillMode == FILL_FREEZE;
+ toInactive(true, isFrozen);
+ } else {
+ // Trace.print("element active, sampling at simple time " + (time - lastRepeatTime));
+ sampledAt(time - lastRepeatTime, d, currentRepeatIteration);
+ }
+ }
+ if (isFrozen) {
+ float t;
+ boolean atLast;
+ if (isActive) {
+ t = currentInterval.getBegin() + repeatDuration - lastRepeatTime;
+ atLast = lastRepeatTime + d == currentInterval.getBegin() + repeatDuration;
+ } else {
+ // Interval previousInterval = (Interval) previousIntervals.getLast();
+ t = previousInterval.getEnd() - lastRepeatTime;
+ atLast = lastRepeatTime + d == previousInterval.getEnd();
+ }
+ if (atLast) {
+ // Trace.print("element frozen" + (isActive ? " (but still active)" : "") + ", sampling last value");
+ sampledLastValue(currentRepeatIteration);
+ } else {
+ // Trace.print("element frozen" + (isActive ? " (but still active)" : "") + ", sampling at simple time " + (t % d));
+ sampledAt(t % d, d, currentRepeatIteration);
+ }
+ } else if (!isActive) {
+ // Trace.print("element not sampling");
+ }
+
+ isSampling = false;
+
+ lastSampleTime = time;
+ if (currentInterval != null) {
+ float t = currentInterval.getBegin() - time;
+ if (t <= 0) {
+ t = isConstantAnimation() || isFrozen ? currentInterval.getEnd() - time : 0;
+ }
+ if (dependentMinTime < t) {
+ return dependentMinTime;
+ }
+ return t;
+ }
+ return dependentMinTime;
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Sets the current interval to the one specified. This will notify
+ * dependents and fire the 'begin' and any necessary 'repeat' events.
+ * @param time the current sampling time
+ * @param interval the Interval object to select to be current
+ * @return the minimum time the animation engine can safely wait, as
+ * determined by dependents of the interval
+ */
+ protected float selectNewInterval(float time, Interval interval) {
+ // Trace.enter(this, "selectNewInterval", new Object[] { interval }); try {
+ currentInterval = interval;
+ float dmt = notifyNewInterval(currentInterval);
+ float beginEventTime = currentInterval.getBegin();
+ if (time >= beginEventTime) {
+ lastRepeatTime = beginEventTime;
+ if (beginEventTime < 0) {
+ beginEventTime = 0;
+ }
+ toActive(beginEventTime);
+ isActive = true;
+ isFrozen = false;
+ fireTimeEvent(SMIL_BEGIN_EVENT_NAME, beginEventTime, 0);
+ float d = getSimpleDur();
+ float end = currentInterval.getEnd();
+ while (time - lastRepeatTime >= d
+ && lastRepeatTime + d < end) {
+ lastRepeatTime += d;
+ currentRepeatIteration++;
+ fireTimeEvent(root.getRepeatEventName(), lastRepeatTime,
+ currentRepeatIteration);
+ }
+ }
+ return dmt;
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * 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
+ * beginAfter
is taken to be the actual begin
+ * time for the interval; only the end value is computed.
+ * @param beginAfter the earliest possible begin time for the computed
+ * interval.
+ * @param incl if true (and !fixedBegin
), specifies that the
+ * new interval's begin time must be greater than
+ * beginAfter
; otherwise, the begin time must be
+ * greater than or equal to beginAfter
.
+ */
+ protected Interval computeInterval(boolean first, boolean fixedBegin,
+ float beginAfter, boolean incl) {
+ // Trace.enter(this, "computeInterval", new Object[] { new Boolean(first), new Boolean(fixedBegin), new Float(beginAfter)} ); try {
+ // Trace.print("computing interval from begins=" + beginInstanceTimes + ", ends=" + endInstanceTimes);
+ Iterator beginIterator = beginInstanceTimes.iterator();
+ Iterator endIterator = endInstanceTimes.iterator();
+ float parentSimpleDur = parent.getSimpleDur();
+ InstanceTime endInstanceTime = endIterator.hasNext()
+ ? (InstanceTime) endIterator.next()
+ : null;
+ boolean firstEnd = true;
+ InstanceTime beginInstanceTime = null;
+ InstanceTime nextBeginInstanceTime = null;
+ for (;;) {
+ float tempBegin;
+ if (fixedBegin) {
+ tempBegin = beginAfter;
+ while (beginIterator.hasNext()) {
+ nextBeginInstanceTime = (InstanceTime) beginIterator.next();
+ if (nextBeginInstanceTime.getTime() > tempBegin) {
+ break;
+ }
+ }
+ } else {
+ for (;;) {
+ if (!beginIterator.hasNext()) {
+ // ran out of begin values
+ // Trace.print("returning null interval");
+ return null;
+ }
+ beginInstanceTime = (InstanceTime) beginIterator.next();
+ tempBegin = beginInstanceTime.getTime();
+ if (incl && tempBegin >= beginAfter
+ || !incl && tempBegin > beginAfter) {
+ if (beginIterator.hasNext()) {
+ nextBeginInstanceTime =
+ (InstanceTime) beginIterator.next();
+ if (beginInstanceTime.getTime()
+ == nextBeginInstanceTime.getTime()) {
+ // XXX Not sure if this is exactly correct to
+ // skip past these identical times, but it
+ // avoids an infinite loop of 0s intervals
+ // being created.
+ nextBeginInstanceTime = null;
+ continue;
+ }
+ }
+ break;
+ }
+ }
+ }
+ if (tempBegin >= parentSimpleDur) {
+ // the begin value is after the parent has ended
+ // Trace.print("returning null interval");
+ return null;
+ }
+ float tempEnd;
+ if (endTimes.length == 0) {
+ // no 'end' attribute specified
+ tempEnd = tempBegin + getActiveDur(tempBegin, INDEFINITE);
+ // Trace.print("no end specified, so tempEnd = " + tempEnd);
+ } else {
+ if (endInstanceTimes.isEmpty()) {
+ tempEnd = UNRESOLVED;
+ } else {
+ tempEnd = endInstanceTime.getTime();
+ if (first && !firstEnd && tempEnd == tempBegin
+ || !first && currentInterval != null
+ && tempEnd == currentInterval.getEnd()
+ && (incl && beginAfter >= tempEnd
+ || !incl && beginAfter > tempEnd)) {
+ for (;;) {
+ if (!endIterator.hasNext()) {
+ if (endHasEventConditions()) {
+ tempEnd = UNRESOLVED;
+ break;
+ }
+ // Trace.print("returning null interval");
+ return null;
+ }
+ endInstanceTime = (InstanceTime) endIterator.next();
+ tempEnd = endInstanceTime.getTime();
+ if (tempEnd > tempBegin) {
+ break;
+ }
+ }
+ }
+ firstEnd = false;
+ for (;;) {
+ if (tempEnd >= tempBegin) {
+ break;
+ }
+ if (!endIterator.hasNext()) {
+ if (endHasEventConditions()) {
+ tempEnd = UNRESOLVED;
+ break;
+ }
+ // Trace.print("returning null interval");
+ return null;
+ }
+ endInstanceTime = (InstanceTime) endIterator.next();
+ tempEnd = endInstanceTime.getTime();
+ }
+ }
+ float ad = getActiveDur(tempBegin, tempEnd);
+ tempEnd = tempBegin + ad;
+ }
+ if (!first || tempEnd > 0 || tempBegin == 0 && tempEnd == 0
+ || isUnresolved(tempEnd)) {
+ // Trace.print("considering restart semantics");
+ if (restartMode == RESTART_ALWAYS
+ && nextBeginInstanceTime != null) {
+ float nextBegin = nextBeginInstanceTime.getTime();
+ // Trace.print("nextBegin == " + nextBegin);
+ if (nextBegin < tempEnd || isUnresolved(tempEnd)) {
+ tempEnd = nextBegin;
+ endInstanceTime = nextBeginInstanceTime;
+ }
+ }
+ Interval i = new Interval(tempBegin, tempEnd,
+ beginInstanceTime, endInstanceTime);
+ // Trace.print("returning interval: " + i);
+ return i;
+ }
+ if (fixedBegin) {
+ // Trace.print("returning null interval");
+ return null;
+ }
+ beginAfter = tempEnd;
+ }
+ // } finally { Trace.exit(); }
+ }
+
+ /**
+ * Resets this element.
+ */
+ protected void reset(boolean clearCurrentBegin) {
+ Iterator i = beginInstanceTimes.iterator();
+ while (i.hasNext()) {
+ InstanceTime it = (InstanceTime) i.next();
+ if (it.getClearOnReset() &&
+ (clearCurrentBegin
+ || currentInterval == null
+ || currentInterval.getBeginInstanceTime() != it)) {
+ i.remove();
+ }
+ }
+ i = endInstanceTimes.iterator();
+ while (i.hasNext()) {
+ InstanceTime it = (InstanceTime) i.next();
+ if (it.getClearOnReset()) {
+ i.remove();
+ }
+ }
+ if (isFrozen) {
+ removeFill();
+ }
+ currentRepeatIteration = 0;
+ lastRepeatTime = UNRESOLVED;
+ isActive = false;
+ isFrozen = false;
+ lastSampleTime = UNRESOLVED;
+ // XXX should reconvert resolved syncbase/wallclock/media-marker time
+ // instances into the parent simple timespace
+ }
+
+ /**
+ * Parses the animation attributes for this timed element.
+ */
+ public void parseAttributes(String begin, String dur, String end,
+ String min, String max, String repeatCount,
+ String repeatDur, String fill,
+ String restart) {
+ if (!hasParsed) {
+ parseBegin(begin);
+ parseDur(dur);
+ parseEnd(end);
+ parseMin(min);
+ parseMax(max);
+ if (this.min > this.max) {
+ this.min = 0f;
+ this.max = INDEFINITE;
+ }
+ parseRepeatCount(repeatCount);
+ parseRepeatDur(repeatDur);
+ parseFill(fill);
+ parseRestart(restart);
+ hasParsed = true;
+ }
+ }
+
+ /**
+ * Parses a new 'begin' attribute.
+ */
+ protected void parseBegin(String begin) {
+ try {
+ if (begin.length() == 0) {
+ begin = SMIL_BEGIN_DEFAULT_VALUE;
+ }
+ beginTimes = TimingSpecifierListProducer.parseTimingSpecifierList
+ (TimedElement.this, true, begin,
+ root.useSVG11AccessKeys, root.useSVG12AccessKeys);
+ } catch (ParseException ex) {
+ throw createException
+ ("attribute.malformed",
+ new Object[] { null, SMIL_BEGIN_ATTRIBUTE });
+ }
+ }
+
+ /**
+ * Parses a new 'dur' attribute.
+ */
+ protected void parseDur(String dur) {
+ if (dur.equals(SMIL_MEDIA_VALUE)) {
+ durMedia = true;
+ simpleDur = UNRESOLVED;
+ } else {
+ durMedia = false;
+ if (dur.length() == 0 || dur.equals(SMIL_INDEFINITE_VALUE)) {
+ simpleDur = INDEFINITE;
+ } else {
+ try {
+ simpleDur = parseClockValue(dur, false);
+ } catch (ParseException e) {
+ throw createException
+ ("attribute.malformed",
+ new Object[] { null, SMIL_DUR_ATTRIBUTE });
+ }
+ if (simpleDur < 0) {
+ simpleDur = INDEFINITE;
+ }
+ }
+ }
+ }
+
+ /**
+ * Parses a clock value or offset and returns it as a float.
+ */
+ protected float parseClockValue(String s, boolean parseOffset)
+ throws ParseException {
+ ClockParser p = new ClockParser(parseOffset);
+ class Handler implements ClockHandler {
+ protected float v = 0;
+ public void clockValue(float newClockValue) {
+ v = newClockValue;
+ }
+ }
+
+ Handler h = new Handler();
+ p.setClockHandler(h);
+ p.parse(s);
+ return h.v;
+ }
+
+ /**
+ * Parses a new 'end' attribute.
+ */
+ protected void parseEnd(String end) {
+ try {
+ endTimes = TimingSpecifierListProducer.parseTimingSpecifierList
+ (TimedElement.this, false, end,
+ root.useSVG11AccessKeys, root.useSVG12AccessKeys);
+ } catch (ParseException ex) {
+ throw createException
+ ("attribute.malformed",
+ new Object[] { null, SMIL_END_ATTRIBUTE });
+ }
+ }
+
+ /**
+ * Parses a new 'min' attribute.
+ */
+ protected void parseMin(String min) {
+ if (min.equals(SMIL_MEDIA_VALUE)) {
+ this.min = 0;
+ minMedia = true;
+ } else {
+ minMedia = false;
+ if (min.length() == 0) {
+ this.min = 0;
+ } else {
+ try {
+ this.min = parseClockValue(min, false);
+ } catch (ParseException ex) {
+ this.min = 0;
+ }
+ if (this.min < 0) {
+ this.min = 0;
+ }
+ }
+ }
+ }
+
+ /**
+ * Parses a new 'max' attribute.
+ */
+ protected void parseMax(String max) {
+ if (max.equals(SMIL_MEDIA_VALUE)) {
+ this.max = INDEFINITE;
+ maxMedia = true;
+ } else {
+ maxMedia = false;
+ if (max.length() == 0 || max.equals(SMIL_INDEFINITE_VALUE)) {
+ this.max = INDEFINITE;
+ } else {
+ try {
+ this.max = parseClockValue(max, false);
+ } catch (ParseException ex) {
+ this.max = INDEFINITE;
+ }
+ if (this.max < 0) {
+ this.max = 0;
+ }
+ }
+ }
+ }
+
+ /**
+ * Parses a new 'repeatCount' attribute.
+ */
+ protected void parseRepeatCount(String repeatCount) {
+ if (repeatCount.length() == 0) {
+ this.repeatCount = UNRESOLVED;
+ } else if (repeatCount.equals(SMIL_INDEFINITE_VALUE)) {
+ this.repeatCount = INDEFINITE;
+ } else {
+ try {
+ this.repeatCount = Float.parseFloat(repeatCount);
+ if (this.repeatCount > 0) {
+ return;
+ }
+ } catch (NumberFormatException ex) {
+ throw createException
+ ("attribute.malformed",
+ new Object[] { null, SMIL_REPEAT_COUNT_ATTRIBUTE });
+ }
+ }
+ }
+
+ /**
+ * Parses a new 'repeatDur' attribute.
+ */
+ protected void parseRepeatDur(String repeatDur) {
+ try {
+ if (repeatDur.length() == 0) {
+ this.repeatDur = UNRESOLVED;
+ } else if (repeatDur.equals(SMIL_INDEFINITE_VALUE)) {
+ this.repeatDur = INDEFINITE;
+ } else {
+ this.repeatDur = parseClockValue(repeatDur, false);
+ }
+ } catch (ParseException ex) {
+ throw createException
+ ("attribute.malformed",
+ new Object[] { null, SMIL_REPEAT_DUR_ATTRIBUTE });
+ }
+ }
+
+ /**
+ * Parses a new 'fill' attribute.
+ */
+ protected void parseFill(String fill) {
+ if (fill.length() == 0 || fill.equals(SMIL_REMOVE_VALUE)) {
+ fillMode = FILL_REMOVE;
+ } else if (fill.equals(SMIL_FREEZE_VALUE)) {
+ fillMode = FILL_FREEZE;
+ } else {
+ throw createException
+ ("attribute.malformed",
+ new Object[] { null, SMIL_FILL_ATTRIBUTE });
+ }
+ }
+
+ /**
+ * Parses a new 'restart' attribute.
+ */
+ protected void parseRestart(String restart) {
+ if (restart.length() == 0 || restart.equals(SMIL_ALWAYS_VALUE)) {
+ restartMode = RESTART_ALWAYS;
+ } else if (restart.equals(SMIL_WHEN_NOT_ACTIVE_VALUE)) {
+ restartMode = RESTART_WHEN_NOT_ACTIVE;
+ } else if (restart.equals(SMIL_NEVER_VALUE)) {
+ restartMode = RESTART_NEVER;
+ } else {
+ throw createException
+ ("attribute.malformed",
+ new Object[] { null, SMIL_RESTART_ATTRIBUTE });
+ }
+ }
+
+ /**
+ * Initializes this timed element.
+ */
+ public void initialize() {
+ for (int i = 0; i < beginTimes.length; i++) {
+ beginTimes[i].initialize();
+ }
+ for (int i = 0; i < endTimes.length; i++) {
+ endTimes[i].initialize();
+ }
+ }
+
+ /**
+ * Deinitializes this timed element.
+ */
+ public void deinitialize() {
+ for (int i = 0; i < beginTimes.length; i++) {
+ beginTimes[i].deinitialize();
+ }
+ for (int i = 0; i < endTimes.length; i++) {
+ endTimes[i].deinitialize();
+ }
+ }
+
+ /**
+ * Adds a time to the begin time instance list that will cause
+ * the element to begin immediately (if restart semantics allow it).
+ */
+ public void beginElement() {
+ beginElement(0);
+ }
+
+ /**
+ * Adds a time to the begin time instance list that will cause
+ * the element to begin at some offset to the current time (if restart
+ * semantics allow it).
+ */
+ public void beginElement(float offset) {
+ float t = root.convertWallclockTime( Calendar.getInstance());
+ InstanceTime it = new InstanceTime(null, t + offset, true);
+ addInstanceTime(it, true);
+ }
+
+ /**
+ * Adds a time to the end time instance list that will cause
+ * the element to end immediately (if restart semantics allow it).
+ */
+ public void endElement() {
+ endElement(0);
+ }
+
+ /**
+ * Adds a time to the end time instance list that will cause
+ * the element to end at some offset to the current time (if restart
+ * semantics allow it).
+ */
+ public void endElement(float offset) {
+ float t = root.convertWallclockTime(Calendar.getInstance());
+ InstanceTime it = new InstanceTime(null, t + offset, true);
+ addInstanceTime(it, false);
+ }
+
+ /**
+ * Returns the last sample time of this element, in local active time.
+ */
+ public float getLastSampleTime() {
+ return lastSampleTime;
+ }
+
+ /**
+ * Returns the begin time of the current interval, in parent simple time,
+ * or Float.NaN
if the element is not active.
+ */
+ public float getCurrentBeginTime() {
+ float begin;
+ if (currentInterval == null
+ || (begin = currentInterval.getBegin()) < lastSampleTime) {
+ return Float.NaN;
+ }
+ return begin;
+ }
+
+ /**
+ * Returns whether this element can be begun or restarted currently.
+ */
+ public boolean canBegin() {
+ return currentInterval == null
+ || isActive && restartMode != RESTART_NEVER;
+ }
+
+ /**
+ * Returns whether this element can be ended currently.
+ */
+ public boolean canEnd() {
+ return isActive;
+ }
+
+ /**
+ * Returns the time that the document would seek to if this animation
+ * element were hyperlinked to, or NaN
if there is no
+ * such begin time.
+ */
+ public float getHyperlinkBeginTime() {
+ if (isActive) {
+ return currentInterval.getBegin();
+ }
+ if (!beginInstanceTimes.isEmpty()) {
+ return ((InstanceTime) beginInstanceTimes.get(0)).getTime();
+ }
+ return Float.NaN;
+ }
+
+ /**
+ * Fires a TimeEvent of the given type on this element.
+ * @param eventType the type of TimeEvent ("beginEvent", "endEvent"
+ * or "repeatEvent").
+ * @param time the timestamp of the event object
+ * @param detail the repeat iteration, if this event is a repeat event
+ */
+ protected void fireTimeEvent(String eventType, float time, int detail) {
+ Calendar t = (Calendar) root.getDocumentBeginTime().clone();
+ t.add(Calendar.MILLISECOND, (int) Math.round(time * 1e3));
+ fireTimeEvent(eventType, t, detail);
+ }
+
+ /**
+ * Invoked by a {@link TimingSpecifier} to indicate that an event occurred
+ * that would create a new instance time for this timed element. These
+ * will be processed at the beginning of the next tick.
+ */
+ void eventOccurred(TimingSpecifier t, Event e) {
+ Set ts = (HashSet) handledEvents.get(e);
+ if (ts == null) {
+ ts = new HashSet();
+ handledEvents.put(e, ts);
+ }
+ ts.add(t);
+ root.currentIntervalWillUpdate();
+ }
+
+ /**
+ * Fires a TimeEvent of the given type on this element.
+ * @param eventType the type of TimeEvent ("beginEvent", "endEvent"
+ * or "repeatEvent").
+ * @param time the timestamp of the event object
+ */
+ protected abstract void fireTimeEvent(String eventType, Calendar time,
+ int 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 abstract 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 abstract void toInactive(boolean stillActive, boolean isFrozen);
+
+ /**
+ * Invoked to indicate that this timed element has had its fill removed.
+ */
+ protected abstract 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 abstract 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 abstract void sampledLastValue(int repeatIteration);
+
+ /**
+ * Returns the timed element with the given ID.
+ */
+ protected abstract TimedElement getTimedElementById(String id);
+
+ /**
+ * Returns the event target with the given ID.
+ */
+ protected abstract EventTarget getEventTargetById(String id);
+
+ /**
+ * Returns the event target that should be listened to for
+ * access key events.
+ */
+ protected abstract EventTarget getRootEventTarget();
+
+ /**
+ * Returns the DOM element that corresponds to this timed element, if
+ * such a DOM element exists.
+ */
+ public abstract Element getElement();
+
+ /**
+ * Returns the target of this animation as an {@link EventTarget}. Used
+ * for eventbase timing specifiers where the element ID is omitted.
+ */
+ protected abstract EventTarget getAnimationEventTarget();
+
+ /**
+ * Returns whether this timed element comes before the given timed element
+ * in document order.
+ */
+ public abstract boolean isBefore(TimedElement other);
+
+ /**
+ * Returns whether this timed element is for a constant animation (i.e., a
+ * 'set' animation.
+ */
+ protected abstract boolean isConstantAnimation();
+
+ /**
+ * Creates and returns a new {@link AnimationException}.
+ */
+ public AnimationException createException(String code, Object[] params) {
+ Element e = getElement();
+ if (e != null) {
+ params[0] = e.getNodeName();
+ }
+ return new AnimationException(this, code, params);
+ }
+
+ /**
+ * The error messages bundle class name.
+ */
+ protected static final String RESOURCES =
+ "org.apache.batik.anim.resources.Messages";
+
+ /**
+ * The localizable support for the error messages.
+ */
+ protected static LocalizableSupport localizableSupport =
+ new LocalizableSupport(RESOURCES, TimedElement.class.getClassLoader());
+
+ /**
+ * Implements {@link org.apache.batik.i18n.Localizable#setLocale(java.util.Locale)}.
+ */
+ public static void setLocale( Locale l) {
+ localizableSupport.setLocale(l);
+ }
+
+ /**
+ * Implements {@link org.apache.batik.i18n.Localizable#getLocale()}.
+ */
+ public static Locale getLocale() {
+ return localizableSupport.getLocale();
+ }
+
+ /**
+ * Implements {@link
+ * org.apache.batik.i18n.Localizable#formatMessage(String,Object[])}.
+ */
+ public static String formatMessage(String key, Object[] args)
+ throws MissingResourceException {
+ return localizableSupport.formatMessage(key, args);
+ }
+
+ /**
+ * Returns a string representation of the given time value.
+ */
+ public static String toString(float time) {
+ if (Float.isNaN(time)) {
+ return "UNRESOLVED";
+ } else if (time == Float.POSITIVE_INFINITY) {
+ return "INDEFINITE";
+ } else {
+ return Float.toString(time);
+ }
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/TimegraphAdapter.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/TimegraphAdapter.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/TimegraphAdapter.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,106 @@
+/*
+
+ 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.batik.anim.timing;
+
+/**
+ * An adapter class for {@link TimegraphListener}s.
+ *
+ * @author Cameron McCormack
+ * @version $Id: TimegraphAdapter.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public class TimegraphAdapter implements TimegraphListener {
+
+ /**
+ * Invoked to indicate that a timed element has been added to the
+ * document.
+ */
+ public void elementAdded(TimedElement e) {
+ }
+
+ /**
+ * Invoked to indicate that a timed element has been removed from the
+ * document.
+ */
+ public void elementRemoved(TimedElement e) {
+ }
+
+ /**
+ * Invoked to indicate that a timed element has become active.
+ * @param e the TimedElement that became active
+ * @param t the time (in parent simple time) that the element became active
+ */
+ public void elementActivated(TimedElement e, float t) {
+ }
+
+ /**
+ * Invoked to indicate that a timed element has become inactive
+ * and is filling.
+ */
+ public void elementFilled(TimedElement e, float t) {
+ }
+
+ /**
+ * Invoked to indicate that a timed element has become inactive
+ * and is not filling.
+ */
+ public void elementDeactivated(TimedElement e, float t) {
+ }
+
+ /**
+ * Invoked to indivate that an interval was created for the given
+ * timed element.
+ */
+ public void intervalCreated(TimedElement e, Interval i) {
+ }
+
+ /**
+ * Invoked to indivate that an interval was removed for the given
+ * timed element.
+ */
+ public void intervalRemoved(TimedElement e, Interval i) {
+ }
+
+ /**
+ * Invoked to indivate that an interval's endpoints were changed.
+ */
+ public void intervalChanged(TimedElement e, Interval i) {
+ }
+
+ /**
+ * Invoked to indivate that the given interval began.
+ * @param i the Interval that began, or null if no interval is
+ * active for the given timed element.
+ */
+ public void intervalBegan(TimedElement e, Interval i) {
+ }
+
+ /**
+ * Invoked to indicate that the given timed element began a repeat
+ * iteration at the specified time.
+ */
+ public void elementRepeated(TimedElement e, int i, float t) {
+ }
+
+ /**
+ * Invoked to indicate that the list of instance times for the given
+ * timed element has been updated.
+ */
+ public void elementInstanceTimesChanged(TimedElement e, float isBegin) {
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/TimegraphListener.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/TimegraphListener.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/TimegraphListener.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,95 @@
+/*
+
+ 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.batik.anim.timing;
+
+/**
+ * An interface for listening to timing events in a timed document.
+ *
+ * @author Cameron McCormack
+ * @version $Id: TimegraphListener.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public interface TimegraphListener {
+
+ /**
+ * Invoked to indicate that a timed element has been added to the
+ * document.
+ */
+ void elementAdded(TimedElement e);
+
+ /**
+ * Invoked to indicate that a timed element has been removed from the
+ * document.
+ */
+ void elementRemoved(TimedElement e);
+
+ /**
+ * Invoked to indicate that a timed element has become active.
+ * @param e the TimedElement that became active
+ * @param t the time (in parent simple time) that the element became active
+ */
+ void elementActivated(TimedElement e, float t);
+
+ /**
+ * Invoked to indicate that a timed element has become inactive
+ * and is filling.
+ */
+ void elementFilled(TimedElement e, float t);
+
+ /**
+ * Invoked to indicate that a timed element has become inactive
+ * and is not filling.
+ */
+ void elementDeactivated(TimedElement e, float t);
+
+ /**
+ * Invoked to indivate that an interval was created for the given
+ * timed element.
+ */
+ void intervalCreated(TimedElement e, Interval i);
+
+ /**
+ * Invoked to indivate that an interval was removed for the given
+ * timed element.
+ */
+ void intervalRemoved(TimedElement e, Interval i);
+
+ /**
+ * Invoked to indivate that an interval's endpoints were changed.
+ */
+ void intervalChanged(TimedElement e, Interval i);
+
+ /**
+ * Invoked to indivate that the given interval began.
+ * @param i the Interval that began, or null if no interval is
+ * active for the given timed element.
+ */
+ void intervalBegan(TimedElement e, Interval i);
+
+ /**
+ * Invoked to indicate that the given timed element began a repeat
+ * iteration at the specified time.
+ */
+ void elementRepeated(TimedElement e, int i, float t);
+
+ /**
+ * Invoked to indicate that the list of instance times for the given
+ * timed element has been updated.
+ */
+ void elementInstanceTimesChanged(TimedElement e, float isBegin);
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/TimingSpecifier.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/TimingSpecifier.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/TimingSpecifier.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,110 @@
+/*
+
+ 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.batik.anim.timing;
+
+/**
+ * An abstract class for SMIL timing specifiers.
+ *
+ * @author Cameron McCormack
+ * @version $Id: TimingSpecifier.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public abstract class TimingSpecifier {
+
+ /**
+ * The element that owns this timing specifier.
+ */
+ protected TimedElement owner;
+
+ /**
+ * Whether this timing specifier is for a begin time or an end time.
+ */
+ protected boolean isBegin;
+
+ /**
+ * Creates a new TimingSpecifier object.
+ */
+ protected TimingSpecifier(TimedElement owner, boolean isBegin) {
+ this.owner = owner;
+ this.isBegin = isBegin;
+ }
+
+ /**
+ * Returns the element that owns this timing specifier.
+ */
+ public TimedElement getOwner() {
+ return owner;
+ }
+
+ /**
+ * Returns true if this timing specifier is in the owner's begin list,
+ * false if it is in the owner's end list.
+ */
+ public boolean isBegin() {
+ return isBegin;
+ }
+
+ /**
+ * Initializes this timing specifier by adding the initial instance time
+ * to the owner's instance time list or setting up any event listeners.
+ * This should be overriden in descendant classes.
+ */
+ public void initialize() {
+ }
+
+ /**
+ * Deinitializes this timing specifier by removing any event listeners.
+ * This should be overriden in descendant classes.
+ */
+ public void deinitialize() {
+ }
+
+ /**
+ * 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.
+ */
+ float newInterval(Interval interval) {
+ return Float.POSITIVE_INFINITY;
+ }
+
+ /**
+ * Called by the timebase element when it deletes an Interval.
+ * This should be overridden in descendant classes that generate
+ * time instances based on the interval of a timebase element.
+ */
+ float removeInterval(Interval interval) {
+ return Float.POSITIVE_INFINITY;
+ }
+
+ /**
+ * Called by an {@link InstanceTime} created by this TimingSpecifier
+ * to indicate that its value has changed. This should be overriden
+ * in descendant classes that generate time instances based on the
+ * interval of a timebase element.
+ */
+ float handleTimebaseUpdate(InstanceTime instanceTime, float newTime) {
+ return Float.POSITIVE_INFINITY;
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/TimingSpecifierListProducer.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/TimingSpecifierListProducer.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/TimingSpecifierListProducer.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,177 @@
+/*
+
+ 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.batik.anim.timing;
+
+import java.util.Calendar;
+import java.util.LinkedList;
+
+import org.apache.batik.parser.DefaultTimingSpecifierListHandler;
+import org.apache.batik.parser.TimingSpecifierListParser;
+
+/**
+ * A {@link org.apache.batik.parser.TimingSpecifierListHandler} that creates
+ * {@link TimingSpecifier}s.
+ *
+ * @author Cameron McCormack
+ * @version $Id: TimingSpecifierListProducer.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public class TimingSpecifierListProducer
+ extends DefaultTimingSpecifierListHandler {
+
+ /**
+ * The list of parsed timing specifiers.
+ */
+ protected LinkedList timingSpecifiers = new LinkedList();
+
+ /**
+ * The owner TimedElement used when creating the TimingSpecifiers.
+ */
+ protected TimedElement owner;
+
+ /**
+ * Whether the created TimingSpecifiers should be begin times.
+ */
+ protected boolean isBegin;
+
+ /**
+ * Creates a new TimingSpecifierListProducer.
+ */
+ public TimingSpecifierListProducer(TimedElement owner, boolean isBegin) {
+ this.owner = owner;
+ this.isBegin = isBegin;
+ }
+
+ /**
+ * Returns an array of the parsed TimingSpecifiers.
+ */
+ public TimingSpecifier[] getTimingSpecifiers() {
+ return (TimingSpecifier[]) timingSpecifiers.toArray(new TimingSpecifier[0]);
+ }
+
+ /**
+ * Parses a timing specifier list.
+ */
+ public static TimingSpecifier[] parseTimingSpecifierList
+ (TimedElement owner, boolean isBegin, String spec,
+ boolean useSVG11AccessKeys, boolean useSVG12AccessKeys) {
+ TimingSpecifierListParser p =
+ new TimingSpecifierListParser(useSVG11AccessKeys,
+ useSVG12AccessKeys);
+ TimingSpecifierListProducer pp =
+ new TimingSpecifierListProducer(owner, isBegin);
+ p.setTimingSpecifierListHandler(pp);
+ p.parse(spec);
+ TimingSpecifier[] specs = pp.getTimingSpecifiers();
+ return specs;
+ }
+
+ // TimingSpecifierHandler ////////////////////////////////////////////////
+
+ /**
+ * Invoked when an offset value timing specifier is parsed.
+ */
+ public void offset(float offset) {
+ TimingSpecifier ts = new OffsetTimingSpecifier(owner, isBegin, offset);
+ timingSpecifiers.add(ts);
+ }
+
+ /**
+ * Invoked when a syncbase value timing specifier is parsed.
+ */
+ public void syncbase(float offset, String syncbaseID,
+ String timeSymbol) {
+ TimingSpecifier ts = new SyncbaseTimingSpecifier
+ (owner, isBegin, offset, syncbaseID, timeSymbol.charAt(0) == 'b');
+ timingSpecifiers.add(ts);
+ }
+
+ /**
+ * Invoked when an eventbase value timing specifier is parsed.
+ */
+ public void eventbase(float offset, String eventbaseID,
+ String eventType) {
+ TimingSpecifier ts = new EventbaseTimingSpecifier
+ (owner, isBegin, offset, eventbaseID, eventType);
+ timingSpecifiers.add(ts);
+ }
+
+ /**
+ * Invoked when a repeat value timing specifier with no iteration
+ * is parsed.
+ */
+ public void repeat(float offset, String syncbaseID) {
+ TimingSpecifier ts = new RepeatTimingSpecifier
+ (owner, isBegin, offset, syncbaseID);
+ timingSpecifiers.add(ts);
+ }
+
+ /**
+ * Invoked when a repeat value timing specifier with an iteration
+ * is parsed.
+ */
+ public void repeat(float offset, String syncbaseID,
+ int repeatIteration) {
+ TimingSpecifier ts = new RepeatTimingSpecifier
+ (owner, isBegin, offset, syncbaseID, repeatIteration);
+ timingSpecifiers.add(ts);
+ }
+
+ /**
+ * Invoked when an accesskey value timing specifier is parsed.
+ */
+ public void accesskey(float offset, char key) {
+ TimingSpecifier ts = new AccesskeyTimingSpecifier
+ (owner, isBegin, offset, key);
+ timingSpecifiers.add(ts);
+ }
+
+ /**
+ * Invoked when an SVG 1.2 accessKey value timing specifier is parsed.
+ */
+ public void accessKeySVG12(float offset, String keyName) {
+ TimingSpecifier ts = new AccesskeyTimingSpecifier
+ (owner, isBegin, offset, keyName);
+ timingSpecifiers.add(ts);
+ }
+
+ /**
+ * Invoked when a media marker value timing specifier is parsed.
+ */
+ public void mediaMarker(String syncbaseID, String markerName) {
+ TimingSpecifier ts = new MediaMarkerTimingSpecifier
+ (owner, isBegin, syncbaseID, markerName);
+ timingSpecifiers.add(ts);
+ }
+
+ /**
+ * Invoked when a wallclock value timing specifier is parsed.
+ */
+ public void wallclock(Calendar time) {
+ TimingSpecifier ts = new WallclockTimingSpecifier(owner, isBegin, time);
+ timingSpecifiers.add(ts);
+ }
+
+ /**
+ * Invoked when an indefinite value timing specifier is parsed.
+ */
+ public void indefinite() {
+ TimingSpecifier ts = new IndefiniteTimingSpecifier(owner, isBegin);
+ timingSpecifiers.add(ts);
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/Trace.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/Trace.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/Trace.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,68 @@
+/*
+
+ 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.batik.anim.timing;
+
+/**
+ * Animation debugging support. To be removed.
+ *
+ * @author Cameron McCormack
+ * @version $Id: Trace.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public class Trace {
+
+ private static int level;
+
+ private static boolean enabled = false;
+
+ public static void enter(Object o, String fn, Object[] args) {
+ if (enabled) {
+ System.err.print("LOG\t");
+ for (int i = 0; i < level; i++) {
+ System.err.print(" ");
+ }
+ if (fn == null) {
+ System.err.print("new " + o.getClass().getName() + "(");
+ } else {
+ System.err.print(o + "." + fn + "(");
+ }
+ if (args != null) {
+ System.err.print(args[0]);
+ for (int i = 1; i < args.length; i++) {
+ System.err.print(", " + args[i]);
+ }
+ }
+ System.err.println(")");
+ }
+ level++;
+ }
+
+ public static void exit() {
+ level--;
+ }
+
+ public static void print(String s) {
+ if (enabled) {
+ System.err.print("LOG\t");
+ for (int i = 0; i < level; i++) {
+ System.err.print(" ");
+ }
+ System.err.println(s);
+ }
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/timing/WallclockTimingSpecifier.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/timing/WallclockTimingSpecifier.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/timing/WallclockTimingSpecifier.java 8 Apr 2013 10:54:57 -0000 1.1
@@ -0,0 +1,74 @@
+/*
+
+ 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.batik.anim.timing;
+
+import java.util.Calendar;
+
+/**
+ * A class to handle wallclock SMIL timing specifiers.
+ *
+ * @author Cameron McCormack
+ * @version $Id: WallclockTimingSpecifier.java,v 1.1 2013/04/08 10:54:57 marcin Exp $
+ */
+public class WallclockTimingSpecifier extends TimingSpecifier {
+
+ /**
+ * The wallclock time.
+ */
+ protected Calendar time;
+
+ /**
+ * The instance time.
+ */
+ protected InstanceTime instance;
+
+ /**
+ * Creates a new WallclockTimingSpecifier object.
+ */
+ public WallclockTimingSpecifier(TimedElement owner, boolean isBegin,
+ Calendar time) {
+ super(owner, isBegin);
+ this.time = time;
+ }
+
+ /**
+ * Returns a string representation of this timing specifier.
+ */
+ public String toString() {
+ return "wallclock(" + time.toString() + ")";
+ }
+
+ /**
+ * Initializes this timing specifier by adding the initial instance time
+ * to the owner's instance time list or setting up any event listeners.
+ */
+ public void initialize() {
+ float t = owner.getRoot().convertWallclockTime(time);
+ instance = new InstanceTime(this, t, 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;
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableAngleOrIdentValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableAngleOrIdentValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableAngleOrIdentValue.java 8 Apr 2013 10:55:47 -0000 1.1
@@ -0,0 +1,179 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+import org.w3c.dom.svg.SVGAngle;
+
+/**
+ * An SVG angle-or-identifier value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableAngleOrIdentValue.java,v 1.1 2013/04/08 10:55:47 marcin Exp $
+ */
+public class AnimatableAngleOrIdentValue extends AnimatableAngleValue {
+
+ /**
+ * Whether this value is an identifier.
+ */
+ protected boolean isIdent;
+
+ /**
+ * The identifier.
+ */
+ protected String ident;
+
+ /**
+ * Creates a new, uninitialized AnimatableAngleOrIdentValue.
+ */
+ protected AnimatableAngleOrIdentValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableAngleOrIdentValue for an angle value.
+ */
+ public AnimatableAngleOrIdentValue(AnimationTarget target, float v, short unit) {
+ super(target, v, unit);
+ }
+
+ /**
+ * Creates a new AnimatableAngleOrIdentValue for an identifier value.
+ */
+ public AnimatableAngleOrIdentValue(AnimationTarget target, String ident) {
+ super(target);
+ this.ident = ident;
+ this.isIdent = true;
+ }
+
+ /**
+ * Returns whether the value is an identifier.
+ */
+ public boolean isIdent() {
+ return isIdent;
+ }
+
+ /**
+ * Returns the identifiers.
+ */
+ public String getIdent() {
+ return ident;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return false;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ return 0f;
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatableAngleOrIdentValue
+ (target, 0, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String getCssText() {
+ if (isIdent) {
+ return ident;
+ }
+ return super.getCssText();
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to, float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableAngleOrIdentValue res;
+ if (result == null) {
+ res = new AnimatableAngleOrIdentValue(target);
+ } else {
+ res = (AnimatableAngleOrIdentValue) result;
+ }
+
+ if (to == null) {
+ if (isIdent) {
+ res.hasChanged = !res.isIdent || !res.ident.equals(ident);
+ res.ident = ident;
+ res.isIdent = true;
+ } else {
+ short oldUnit = res.unit;
+ float oldValue = res.value;
+ super.interpolate(res, to, interpolation, accumulation,
+ multiplier);
+ if (res.unit != oldUnit || res.value != oldValue) {
+ res.hasChanged = true;
+ }
+ }
+ } else {
+ AnimatableAngleOrIdentValue toValue
+ = (AnimatableAngleOrIdentValue) to;
+ if (isIdent || toValue.isIdent) {
+ if (interpolation >= 0.5) {
+ if (res.isIdent != toValue.isIdent
+ || res.unit != toValue.unit
+ || res.value != toValue.value
+ || res.isIdent && toValue.isIdent
+ && !toValue.ident.equals(ident)) {
+ res.isIdent = toValue.isIdent;
+ res.ident = toValue.ident;
+ res.unit = toValue.unit;
+ res.value = toValue.value;
+ res.hasChanged = true;
+ }
+ } else {
+ if (res.isIdent != isIdent
+ || res.unit != unit
+ || res.value != value
+ || res.isIdent && isIdent
+ && !res.ident.equals(ident)) {
+ res.isIdent = isIdent;
+ res.ident = ident;
+ res.unit = unit;
+ res.value = value;
+ res.hasChanged = true;
+ }
+ }
+ } else {
+ super.interpolate(res, to, interpolation, accumulation,
+ multiplier);
+ }
+ }
+
+ return res;
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableAngleValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableAngleValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableAngleValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,149 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+import org.w3c.dom.svg.SVGAngle;
+
+/**
+ * An SVG angle value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableAngleValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatableAngleValue extends AnimatableNumberValue {
+
+ /**
+ * The unit string representations.
+ */
+ protected static final String[] UNITS = {
+ "", "", "deg", "rad", "grad"
+ };
+
+ /**
+ * The angle unit.
+ */
+ protected short unit;
+
+ /**
+ * Creates a new, uninitialized AnimatableAngleValue.
+ */
+ public AnimatableAngleValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableAngleValue.
+ */
+ public AnimatableAngleValue(AnimationTarget target, float v, short unit) {
+ super(target, v);
+ this.unit = unit;
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableAngleValue res;
+ if (result == null) {
+ res = new AnimatableAngleValue(target);
+ } else {
+ res = (AnimatableAngleValue) result;
+ }
+
+ float v = value;
+ short u = unit;
+ if (to != null) {
+ AnimatableAngleValue toAngle = (AnimatableAngleValue) to;
+ if (toAngle.unit != u) {
+ v = rad(v, u);
+ v += interpolation * (rad(toAngle.value, toAngle.unit) - v);
+ u = SVGAngle.SVG_ANGLETYPE_RAD;
+ } else {
+ v += interpolation * (toAngle.value - v);
+ }
+ }
+ if (accumulation != null) {
+ AnimatableAngleValue accAngle = (AnimatableAngleValue) accumulation;
+ if (accAngle.unit != u) {
+ v += multiplier * rad(accAngle.value, accAngle.unit);
+ u = SVGAngle.SVG_ANGLETYPE_RAD;
+ } else {
+ v += multiplier * accAngle.value;
+ }
+ }
+
+ if (res.value != v || res.unit != u) {
+ res.value = v;
+ res.unit = u;
+ res.hasChanged = true;
+ }
+ return res;
+ }
+
+ /**
+ * Returns the angle unit.
+ */
+ public short getUnit() {
+ return unit;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ AnimatableAngleValue o = (AnimatableAngleValue) other;
+ return Math.abs(rad(value, unit) - rad(o.value, o.unit));
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatableAngleValue
+ (target, 0, SVGAngle.SVG_ANGLETYPE_UNSPECIFIED);
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String getCssText() {
+ return super.getCssText() + UNITS[unit];
+ }
+
+ /**
+ * Converts an angle value to radians.
+ */
+ public static float rad(float v, short unit) {
+ switch (unit) {
+ case SVGAngle.SVG_ANGLETYPE_RAD:
+ return v;
+ case SVGAngle.SVG_ANGLETYPE_GRAD:
+ return (float) Math.PI * v / 200;
+ default:
+ return (float) Math.PI * v / 180;
+ }
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableBooleanValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableBooleanValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableBooleanValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,117 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * A boolean value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableBooleanValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatableBooleanValue extends AnimatableValue {
+
+ /**
+ * The boolean value.
+ */
+ protected boolean value;
+
+ /**
+ * Creates a new, uninitialized AnimatableBooleanValue.
+ */
+ protected AnimatableBooleanValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableBooleanValue.
+ */
+ public AnimatableBooleanValue(AnimationTarget target, boolean b) {
+ super(target);
+ value = b;
+ }
+
+ /**
+ * Performs interpolation to the given value. Boolean values cannot be
+ * interpolated.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to, float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableBooleanValue res;
+ if (result == null) {
+ res = new AnimatableBooleanValue(target);
+ } else {
+ res = (AnimatableBooleanValue) result;
+ }
+
+ boolean newValue;
+ if (to != null && interpolation >= 0.5) {
+ AnimatableBooleanValue toValue = (AnimatableBooleanValue) to;
+ newValue = toValue.value;
+ } else {
+ newValue = value;
+ }
+
+ if (res.value != newValue) {
+ res.value = newValue;
+ res.hasChanged = true;
+ }
+ return res;
+ }
+
+ /**
+ * Returns the boolean value.
+ */
+ public boolean getValue() {
+ return value;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return false;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ return 0f;
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatableBooleanValue(target, false);
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String getCssText() {
+ return (value)?"true":"false";
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableColorValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableColorValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableColorValue.java 8 Apr 2013 10:55:47 -0000 1.1
@@ -0,0 +1,145 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * An SVG color value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableColorValue.java,v 1.1 2013/04/08 10:55:47 marcin Exp $
+ */
+public class AnimatableColorValue extends AnimatableValue {
+
+ /**
+ * The red component.
+ */
+ protected float red;
+
+ /**
+ * The green component.
+ */
+ protected float green;
+
+ /**
+ * The blue component.
+ */
+ protected float blue;
+
+ /**
+ * Creates a new AnimatableColorValue.
+ */
+ protected AnimatableColorValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableColorValue.
+ */
+ public AnimatableColorValue(AnimationTarget target,
+ float r, float g, float b) {
+ super(target);
+ red = r;
+ green = g;
+ blue = b;
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableColorValue res;
+ if (result == null) {
+ res = new AnimatableColorValue(target);
+ } else {
+ res = (AnimatableColorValue) result;
+ }
+
+ float oldRed = res.red;
+ float oldGreen = res.green;
+ float oldBlue = res.blue;
+
+ res.red = red;
+ res.green = green;
+ res.blue = blue;
+
+ AnimatableColorValue toColor = (AnimatableColorValue) to;
+ AnimatableColorValue accColor = (AnimatableColorValue) accumulation;
+
+ // XXX Should handle non-sRGB colours and non-sRGB interpolation.
+
+ if (to != null) {
+ res.red += interpolation * (toColor.red - res.red);
+ res.green += interpolation * (toColor.green - res.green);
+ res.blue += interpolation * (toColor.blue - res.blue);
+ }
+
+ if (accumulation != null) {
+ res.red += multiplier * accColor.red;
+ res.green += multiplier * accColor.green;
+ res.blue += multiplier * accColor.blue;
+ }
+
+ if (res.red != oldRed || res.green != oldGreen || res.blue != oldBlue) {
+ res.hasChanged = true;
+ }
+ return res;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return true;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ AnimatableColorValue o = (AnimatableColorValue) other;
+ float dr = red - o.red;
+ float dg = green - o.green;
+ float db = blue - o.blue;
+ return (float) Math.sqrt(dr * dr + dg * dg + db * db);
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatableColorValue(target, 0f, 0f, 0f);
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String getCssText() {
+ return "rgb(" + Math.round(red * 255) + ','
+ + Math.round(green * 255) + ','
+ + Math.round(blue * 255) + ')';
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableIntegerValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableIntegerValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableIntegerValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,121 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * An integer in the animation engine.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableIntegerValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatableIntegerValue extends AnimatableValue {
+
+ /**
+ * The value.
+ */
+ protected int value;
+
+ /**
+ * Creates a new, uninitialized AnimatableIntegerValue.
+ */
+ protected AnimatableIntegerValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableIntegerValue.
+ */
+ public AnimatableIntegerValue(AnimationTarget target, int v) {
+ super(target);
+ value = v;
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableIntegerValue res;
+ if (result == null) {
+ res = new AnimatableIntegerValue(target);
+ } else {
+ res = (AnimatableIntegerValue) result;
+ }
+
+ int v = value;
+ if (to != null) {
+ AnimatableIntegerValue toInteger = (AnimatableIntegerValue) to;
+ v += value + interpolation * (toInteger.getValue() - value);
+ }
+ if (accumulation != null) {
+ AnimatableIntegerValue accInteger =
+ (AnimatableIntegerValue) accumulation;
+ v += multiplier * accInteger.getValue();
+ }
+
+ if (res.value != v) {
+ res.value = v;
+ res.hasChanged = true;
+ }
+ return res;
+ }
+
+ /**
+ * Returns the integer value.
+ */
+ public int getValue() {
+ return value;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return true;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ AnimatableIntegerValue o = (AnimatableIntegerValue) other;
+ return Math.abs(value - o.value);
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatableIntegerValue(target, 0);
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String getCssText() {
+ return Integer.toString(value);
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableLengthListValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableLengthListValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableLengthListValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,224 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+import org.w3c.dom.svg.SVGLength;
+
+/**
+ * An SVG length list value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableLengthListValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatableLengthListValue extends AnimatableValue {
+
+ /**
+ * The length types.
+ */
+ protected short[] lengthTypes;
+
+ /**
+ * The length values. These should be one of the constants defined in
+ * {@link SVGLength}.
+ */
+ protected float[] lengthValues;
+
+ /**
+ * How to interpret percentage values. These should be one of the
+ * {@link AnimationTarget}.PERCENTAGE_* constants.
+ */
+ protected short percentageInterpretation;
+
+ /**
+ * Creates a new, uninitialized AnimatableLengthListValue.
+ */
+ protected AnimatableLengthListValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableLengthListValue.
+ */
+ public AnimatableLengthListValue(AnimationTarget target, short[] types,
+ float[] values, short pcInterp) {
+ super(target);
+ this.lengthTypes = types;
+ this.lengthValues = values;
+ this.percentageInterpretation = pcInterp;
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableLengthListValue toLengthList = (AnimatableLengthListValue) to;
+ AnimatableLengthListValue accLengthList
+ = (AnimatableLengthListValue) accumulation;
+
+ boolean hasTo = to != null;
+ boolean hasAcc = accumulation != null;
+ boolean canInterpolate =
+ !(hasTo && toLengthList.lengthTypes.length != lengthTypes.length)
+ && !(hasAcc && accLengthList.lengthTypes.length != lengthTypes.length);
+
+ short[] baseLengthTypes;
+ float[] baseLengthValues;
+ if (!canInterpolate && hasTo && interpolation >= 0.5) {
+ baseLengthTypes = toLengthList.lengthTypes;
+ baseLengthValues = toLengthList.lengthValues;
+ } else {
+ baseLengthTypes = lengthTypes;
+ baseLengthValues = lengthValues;
+ }
+ int len = baseLengthTypes.length;
+
+ AnimatableLengthListValue res;
+ if (result == null) {
+ res = new AnimatableLengthListValue(target);
+ res.lengthTypes = new short[len];
+ res.lengthValues = new float[len];
+ } else {
+ res = (AnimatableLengthListValue) result;
+ if (res.lengthTypes == null || res.lengthTypes.length != len) {
+ res.lengthTypes = new short[len];
+ res.lengthValues = new float[len];
+ }
+ }
+
+ res.hasChanged =
+ percentageInterpretation != res.percentageInterpretation;
+ res.percentageInterpretation = percentageInterpretation;
+
+ for (int i = 0; i < len; i++) {
+ float toV = 0, accV = 0;
+ short newLengthType = baseLengthTypes[i];
+ float newLengthValue = baseLengthValues[i];
+ if (canInterpolate) {
+ if (hasTo && !AnimatableLengthValue.compatibleTypes
+ (newLengthType,
+ percentageInterpretation,
+ toLengthList.lengthTypes[i],
+ toLengthList.percentageInterpretation)
+ || hasAcc && !AnimatableLengthValue.compatibleTypes
+ (newLengthType,
+ percentageInterpretation,
+ accLengthList.lengthTypes[i],
+ accLengthList.percentageInterpretation)) {
+ newLengthValue = target.svgToUserSpace
+ (newLengthValue, newLengthType,
+ percentageInterpretation);
+ newLengthType = SVGLength.SVG_LENGTHTYPE_NUMBER;
+ if (hasTo) {
+ toV = to.target.svgToUserSpace
+ (toLengthList.lengthValues[i],
+ toLengthList.lengthTypes[i],
+ toLengthList.percentageInterpretation);
+ }
+ if (hasAcc) {
+ accV = accumulation.target.svgToUserSpace
+ (accLengthList.lengthValues[i],
+ accLengthList.lengthTypes[i],
+ accLengthList.percentageInterpretation);
+ }
+ } else {
+ if (hasTo) {
+ toV = toLengthList.lengthValues[i];
+ }
+ if (hasAcc) {
+ accV = accLengthList.lengthValues[i];
+ }
+ }
+ newLengthValue +=
+ interpolation * (toV - newLengthValue)
+ + multiplier * accV;
+ }
+ if (!res.hasChanged) {
+ res.hasChanged = newLengthType != res.lengthTypes[i]
+ || newLengthValue != res.lengthValues[i];
+ }
+ res.lengthTypes[i] = newLengthType;
+ res.lengthValues[i] = newLengthValue;
+ }
+
+ return res;
+ }
+
+ /**
+ * Gets the length types.
+ */
+ public short[] getLengthTypes() {
+ return lengthTypes;
+ }
+
+ /**
+ * Gets the length values.
+ */
+ public float[] getLengthValues() {
+ return lengthValues;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return false;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ return 0f;
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ float[] vs = new float[lengthValues.length];
+ return new AnimatableLengthListValue
+ (target, lengthTypes, vs, percentageInterpretation);
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ * Length lists can never be used for CSS properties.
+ */
+ public String getCssText() {
+ StringBuffer sb = new StringBuffer();
+ if (lengthValues.length > 0) {
+ sb.append(formatNumber(lengthValues[0]));
+ sb.append(AnimatableLengthValue.UNITS[lengthTypes[0] - 1]);
+ }
+ for (int i = 1; i < lengthValues.length; i++) {
+ sb.append(',');
+ sb.append(formatNumber(lengthValues[i]));
+ sb.append(AnimatableLengthValue.UNITS[lengthTypes[i] - 1]);
+ }
+ return sb.toString();
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableLengthOrIdentValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableLengthOrIdentValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableLengthOrIdentValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,185 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+import org.w3c.dom.svg.SVGLength;
+
+/**
+ * An SVG length-or-identifier value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableLengthOrIdentValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatableLengthOrIdentValue extends AnimatableLengthValue {
+
+ /**
+ * Whether this value is an identifier.
+ */
+ protected boolean isIdent;
+
+ /**
+ * The identifier.
+ */
+ protected String ident;
+
+ /**
+ * Creates a new, uninitialized AnimatableLengthOrIdentValue.
+ */
+ protected AnimatableLengthOrIdentValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableLengthOrIdentValue for a length value.
+ */
+ public AnimatableLengthOrIdentValue(AnimationTarget target, short type,
+ float v, short pcInterp) {
+ super(target, type, v, pcInterp);
+ }
+
+ /**
+ * Creates a new AnimatableLengthOrIdentValue for an identifier value.
+ */
+ public AnimatableLengthOrIdentValue(AnimationTarget target, String ident) {
+ super(target);
+ this.ident = ident;
+ this.isIdent = true;
+ }
+
+ /**
+ * Returns whether this value is an identifier or a length.
+ */
+ public boolean isIdent() {
+ return isIdent;
+ }
+
+ /**
+ * Returns the identifier.
+ */
+ public String getIdent() {
+ return ident;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return false;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ return 0f;
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatableLengthOrIdentValue
+ (target, SVGLength.SVG_LENGTHTYPE_NUMBER, 0f,
+ percentageInterpretation);
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String getCssText() {
+ if (isIdent) {
+ return ident;
+ }
+ return super.getCssText();
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to, float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableLengthOrIdentValue res;
+ if (result == null) {
+ res = new AnimatableLengthOrIdentValue(target);
+ } else {
+ res = (AnimatableLengthOrIdentValue) result;
+ }
+
+ if (to == null) {
+ if (isIdent) {
+ res.hasChanged = !res.isIdent || !res.ident.equals(ident);
+ res.ident = ident;
+ res.isIdent = true;
+ } else {
+ short oldLengthType = res.lengthType;
+ float oldLengthValue = res.lengthValue;
+ short oldPercentageInterpretation = res.percentageInterpretation;
+ super.interpolate(res, to, interpolation, accumulation,
+ multiplier);
+ if (res.lengthType != oldLengthType
+ || res.lengthValue != oldLengthValue
+ || res.percentageInterpretation
+ != oldPercentageInterpretation) {
+ res.hasChanged = true;
+ }
+ }
+ } else {
+ AnimatableLengthOrIdentValue toValue
+ = (AnimatableLengthOrIdentValue) to;
+ if (isIdent || toValue.isIdent) {
+ if (interpolation >= 0.5) {
+ if (res.isIdent != toValue.isIdent
+ || res.lengthType != toValue.lengthType
+ || res.lengthValue != toValue.lengthValue
+ || res.isIdent && toValue.isIdent
+ && !toValue.ident.equals(ident)) {
+ res.isIdent = toValue.isIdent;
+ res.ident = toValue.ident;
+ res.lengthType = toValue.lengthType;
+ res.lengthValue = toValue.lengthValue;
+ res.hasChanged = true;
+ }
+ } else {
+ if (res.isIdent != isIdent
+ || res.lengthType != lengthType
+ || res.lengthValue != lengthValue
+ || res.isIdent && isIdent
+ && !res.ident.equals(ident)) {
+ res.isIdent = isIdent;
+ res.ident = ident;
+ res.ident = ident;
+ res.lengthType = lengthType;
+ res.hasChanged = true;
+ }
+ }
+ } else {
+ super.interpolate(res, to, interpolation, accumulation,
+ multiplier);
+ }
+ }
+
+ return res;
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableLengthValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableLengthValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableLengthValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,214 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+import org.w3c.dom.svg.SVGLength;
+
+/**
+ * An SVG length value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableLengthValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatableLengthValue extends AnimatableValue {
+
+ /**
+ * Length units.
+ */
+ protected static final String[] UNITS = {
+ "", "%", "em", "ex", "px", "cm", "mm", "in", "pt", "pc"
+ };
+
+ /**
+ * The length type.
+ */
+ protected short lengthType;
+
+ /**
+ * The length value. This should be one of the constants defined in
+ * {@link SVGLength}.
+ */
+ protected float lengthValue;
+
+ /**
+ * How to interpret percentage values. One of the
+ * {@link AnimationTarget}.PERCENTAGE_* constants.
+ */
+ protected short percentageInterpretation;
+
+ /**
+ * Creates a new AnimatableLengthValue with no length.
+ */
+ protected AnimatableLengthValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableLengthValue.
+ */
+ public AnimatableLengthValue(AnimationTarget target, short type, float v,
+ short pcInterp) {
+ super(target);
+ lengthType = type;
+ lengthValue = v;
+ percentageInterpretation = pcInterp;
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableLengthValue res;
+ if (result == null) {
+ res = new AnimatableLengthValue(target);
+ } else {
+ res = (AnimatableLengthValue) result;
+ }
+
+ short oldLengthType = res.lengthType;
+ float oldLengthValue = res.lengthValue;
+ short oldPercentageInterpretation = res.percentageInterpretation;
+
+ res.lengthType = lengthType;
+ res.lengthValue = lengthValue;
+ res.percentageInterpretation = percentageInterpretation;
+
+ if (to != null) {
+ AnimatableLengthValue toLength = (AnimatableLengthValue) to;
+ float toValue;
+ if (!compatibleTypes
+ (res.lengthType, res.percentageInterpretation,
+ toLength.lengthType, toLength.percentageInterpretation)) {
+ res.lengthValue = target.svgToUserSpace
+ (res.lengthValue, res.lengthType,
+ res.percentageInterpretation);
+ res.lengthType = SVGLength.SVG_LENGTHTYPE_NUMBER;
+ toValue = toLength.target.svgToUserSpace
+ (toLength.lengthValue, toLength.lengthType,
+ toLength.percentageInterpretation);
+ } else {
+ toValue = toLength.lengthValue;
+ }
+ res.lengthValue += interpolation * (toValue - res.lengthValue);
+ }
+
+ if (accumulation != null) {
+ AnimatableLengthValue accLength = (AnimatableLengthValue) accumulation;
+ float accValue;
+ if (!compatibleTypes
+ (res.lengthType, res.percentageInterpretation,
+ accLength.lengthType,
+ accLength.percentageInterpretation)) {
+ res.lengthValue = target.svgToUserSpace
+ (res.lengthValue, res.lengthType,
+ res.percentageInterpretation);
+ res.lengthType = SVGLength.SVG_LENGTHTYPE_NUMBER;
+ accValue = accLength.target.svgToUserSpace
+ (accLength.lengthValue, accLength.lengthType,
+ accLength.percentageInterpretation);
+ } else {
+ accValue = accLength.lengthValue;
+ }
+ res.lengthValue += multiplier * accValue;
+ }
+
+ if (oldPercentageInterpretation != res.percentageInterpretation
+ || oldLengthType != res.lengthType
+ || oldLengthValue != res.lengthValue) {
+ res.hasChanged = true;
+ }
+ return res;
+ }
+
+ /**
+ * Determines if two SVG length types are compatible.
+ * @param t1 the first SVG length type
+ * @param pi1 the first percentage interpretation type
+ * @param t2 the second SVG length type
+ * @param pi2 the second percentage interpretation type
+ */
+ public static boolean compatibleTypes(short t1, short pi1, short t2,
+ short pi2) {
+ return t1 == t2
+ && (t1 != SVGLength.SVG_LENGTHTYPE_PERCENTAGE || pi1 == pi2)
+ || t1 == SVGLength.SVG_LENGTHTYPE_NUMBER
+ && t2 == SVGLength.SVG_LENGTHTYPE_PX
+ || t1 == SVGLength.SVG_LENGTHTYPE_PX
+ && t2 == SVGLength.SVG_LENGTHTYPE_NUMBER;
+ }
+
+ /**
+ * Returns the unit type of this length value.
+ */
+ public int getLengthType() {
+ return lengthType;
+ }
+
+ /**
+ * Returns the magnitude of this length value.
+ */
+ public float getLengthValue() {
+ return lengthValue;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return true;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ AnimatableLengthValue o = (AnimatableLengthValue) other;
+ float v1 = target.svgToUserSpace(lengthValue, lengthType,
+ percentageInterpretation);
+ float v2 = target.svgToUserSpace(o.lengthValue, o.lengthType,
+ o.percentageInterpretation);
+ return Math.abs(v1 - v2);
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatableLengthValue
+ (target, SVGLength.SVG_LENGTHTYPE_NUMBER, 0f,
+ percentageInterpretation);
+ }
+
+ /**
+ * Returns the CSS text representation of the value. This could use
+ * org.apache.batik.css.engine.value.FloatValue.getCssText, but we don't
+ * want a dependency on the CSS package.
+ */
+ public String getCssText() {
+ return formatNumber(lengthValue) + UNITS[lengthType - 1];
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableMotionPointValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableMotionPointValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableMotionPointValue.java 8 Apr 2013 10:55:49 -0000 1.1
@@ -0,0 +1,169 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * A point value in the animation system from a motion animation.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableMotionPointValue.java,v 1.1 2013/04/08 10:55:49 marcin Exp $
+ */
+public class AnimatableMotionPointValue extends AnimatableValue {
+
+ /**
+ * The x coordinate.
+ */
+ protected float x;
+
+ /**
+ * The y coordinate.
+ */
+ protected float y;
+
+ /**
+ * The rotation angle in radians.
+ */
+ protected float angle;
+
+ /**
+ * Creates a new, uninitialized AnimatableMotionPointValue.
+ */
+ protected AnimatableMotionPointValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableMotionPointValue with one x.
+ */
+ public AnimatableMotionPointValue(AnimationTarget target, float x, float y,
+ float angle) {
+ super(target);
+ this.x = x;
+ this.y = y;
+ this.angle = angle;
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableMotionPointValue res;
+ if (result == null) {
+ res = new AnimatableMotionPointValue(target);
+ } else {
+ res = (AnimatableMotionPointValue) result;
+ }
+
+ float newX = x, newY = y, newAngle = angle;
+ int angleCount = 1;
+
+ if (to != null) {
+ AnimatableMotionPointValue toValue =
+ (AnimatableMotionPointValue) to;
+ newX += interpolation * (toValue.x - x);
+ newY += interpolation * (toValue.y - y);
+ newAngle += toValue.angle;
+ angleCount++;
+ }
+ if (accumulation != null && multiplier != 0) {
+ AnimatableMotionPointValue accValue =
+ (AnimatableMotionPointValue) accumulation;
+ newX += multiplier * accValue.x;
+ newY += multiplier * accValue.y;
+ newAngle += accValue.angle;
+ angleCount++;
+ }
+ newAngle /= angleCount;
+
+ if (res.x != newX || res.y != newY || res.angle != newAngle) {
+ res.x = newX;
+ res.y = newY;
+ res.angle = newAngle;
+ res.hasChanged = true;
+ }
+ return res;
+ }
+
+ /**
+ * Returns the x coordinate.
+ */
+ public float getX() {
+ return x;
+ }
+
+ /**
+ * Returns the y coordinate.
+ */
+ public float getY() {
+ return y;
+ }
+
+ /**
+ * Returns the rotation angle.
+ */
+ public float getAngle() {
+ return angle;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return true;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ AnimatableMotionPointValue o = (AnimatableMotionPointValue) other;
+ float dx = x - o.x;
+ float dy = y - o.y;
+ return (float) Math.sqrt(dx * dx + dy * dy);
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatableMotionPointValue(target, 0f, 0f, 0f);
+ }
+
+ /**
+ * Returns a string representation of this object.
+ */
+ public String toStringRep() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(formatNumber(x));
+ sb.append(',');
+ sb.append(formatNumber(y));
+ sb.append(',');
+ sb.append(formatNumber(angle));
+ sb.append("rad");
+ return sb.toString();
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableNumberListValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableNumberListValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableNumberListValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,151 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * A number list in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableNumberListValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatableNumberListValue extends AnimatableValue {
+
+ /**
+ * The numbers.
+ */
+ protected float[] numbers;
+
+ /**
+ * Creates a new, uninitialized AnimatableNumberListValue.
+ */
+ protected AnimatableNumberListValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableNumberListValue.
+ */
+ public AnimatableNumberListValue(AnimationTarget target, float[] numbers) {
+ super(target);
+ this.numbers = numbers;
+ }
+
+ /**
+ * Performs interpolation to the given value. Number list values cannot
+ * be interpolated.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableNumberListValue toNumList = (AnimatableNumberListValue) to;
+ AnimatableNumberListValue accNumList =
+ (AnimatableNumberListValue) accumulation;
+
+ boolean hasTo = to != null;
+ boolean hasAcc = accumulation != null;
+ boolean canInterpolate =
+ !(hasTo && toNumList.numbers.length != numbers.length)
+ && !(hasAcc && accNumList.numbers.length != numbers.length);
+
+ float[] baseValues;
+ if (!canInterpolate && hasTo && interpolation >= 0.5) {
+ baseValues = toNumList.numbers;
+ } else {
+ baseValues = numbers;
+ }
+ int len = baseValues.length;
+
+ AnimatableNumberListValue res;
+ if (result == null) {
+ res = new AnimatableNumberListValue(target);
+ res.numbers = new float[len];
+ } else {
+ res = (AnimatableNumberListValue) result;
+ if (res.numbers == null || res.numbers.length != len) {
+ res.numbers = new float[len];
+ }
+ }
+
+ for (int i = 0; i < len; i++) {
+ float newValue = baseValues[i];
+ if (canInterpolate) {
+ if (hasTo) {
+ newValue += interpolation * (toNumList.numbers[i] - newValue);
+ }
+ if (hasAcc) {
+ newValue += multiplier * accNumList.numbers[i];
+ }
+ }
+ if (res.numbers[i] != newValue) {
+ res.numbers[i] = newValue;
+ res.hasChanged = true;
+ }
+ }
+
+ return res;
+ }
+
+ /**
+ * Gets the numbers.
+ */
+ public float[] getNumbers() {
+ return numbers;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return false;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ return 0f;
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ float[] ns = new float[numbers.length];
+ return new AnimatableNumberListValue(target, ns);
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String getCssText() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(numbers[0]);
+ for (int i = 1; i < numbers.length; i++) {
+ sb.append(' ');
+ sb.append(numbers[i]);
+ }
+ return sb.toString();
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableNumberOptionalNumberValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableNumberOptionalNumberValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableNumberOptionalNumberValue.java 8 Apr 2013 10:55:47 -0000 1.1
@@ -0,0 +1,174 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * A number-optional-number value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableNumberOptionalNumberValue.java,v 1.1 2013/04/08 10:55:47 marcin Exp $
+ */
+public class AnimatableNumberOptionalNumberValue extends AnimatableValue {
+
+ /**
+ * The first number.
+ */
+ protected float number;
+
+ /**
+ * Whether the optional number is present.
+ */
+ protected boolean hasOptionalNumber;
+
+ /**
+ * The optional number.
+ */
+ protected float optionalNumber;
+
+ /**
+ * Creates a new, uninitialized AnimatableNumberOptionalNumberValue.
+ */
+ protected AnimatableNumberOptionalNumberValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableNumberOptionalNumberValue with one number.
+ */
+ public AnimatableNumberOptionalNumberValue(AnimationTarget target,
+ float n) {
+ super(target);
+ number = n;
+ }
+
+ /**
+ * Creates a new AnimatableNumberOptionalNumberValue with two numbers.
+ */
+ public AnimatableNumberOptionalNumberValue(AnimationTarget target, float n,
+ float on) {
+ super(target);
+ number = n;
+ optionalNumber = on;
+ hasOptionalNumber = true;
+ }
+
+ /**
+ * Performs interpolation to the given value. Number-optional-number
+ * values cannot be interpolated.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableNumberOptionalNumberValue res;
+ if (result == null) {
+ res = new AnimatableNumberOptionalNumberValue(target);
+ } else {
+ res = (AnimatableNumberOptionalNumberValue) result;
+ }
+
+ float newNumber, newOptionalNumber;
+ boolean newHasOptionalNumber;
+
+ if (to != null && interpolation >= 0.5) {
+ AnimatableNumberOptionalNumberValue toValue
+ = (AnimatableNumberOptionalNumberValue) to;
+ newNumber = toValue.number;
+ newOptionalNumber = toValue.optionalNumber;
+ newHasOptionalNumber = toValue.hasOptionalNumber;
+ } else {
+ newNumber = number;
+ newOptionalNumber = optionalNumber;
+ newHasOptionalNumber = hasOptionalNumber;
+ }
+
+ if (res.number != newNumber
+ || res.hasOptionalNumber != newHasOptionalNumber
+ || res.optionalNumber != newOptionalNumber) {
+ res.number = number;
+ res.optionalNumber = optionalNumber;
+ res.hasOptionalNumber = hasOptionalNumber;
+ res.hasChanged = true;
+ }
+ return res;
+ }
+
+ /**
+ * Returns the first number.
+ */
+ public float getNumber() {
+ return number;
+ }
+
+ /**
+ * Returns whether the optional number is present.
+ */
+ public boolean hasOptionalNumber() {
+ return hasOptionalNumber;
+ }
+
+ /**
+ * Returns the optional number.
+ */
+ public float getOptionalNumber() {
+ return optionalNumber;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return false;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ return 0f;
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ if (hasOptionalNumber) {
+ return new AnimatableNumberOptionalNumberValue(target, 0f, 0f);
+ }
+ return new AnimatableNumberOptionalNumberValue(target, 0f);
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String getCssText() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(formatNumber(number));
+ if (hasOptionalNumber) {
+ sb.append(' ');
+ sb.append(formatNumber(optionalNumber));
+ }
+ return sb.toString();
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableNumberOrIdentValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableNumberOrIdentValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableNumberOrIdentValue.java 8 Apr 2013 10:55:47 -0000 1.1
@@ -0,0 +1,177 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * A number-or-identifier value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableNumberOrIdentValue.java,v 1.1 2013/04/08 10:55:47 marcin Exp $
+ */
+public class AnimatableNumberOrIdentValue extends AnimatableNumberValue {
+
+ /**
+ * Whether this value is an identifier.
+ */
+ protected boolean isIdent;
+
+ /**
+ * The identifier.
+ */
+ protected String ident;
+
+ /**
+ * Whether numbers should be considered as numeric keywords, as with the
+ * font-weight property.
+ */
+ protected boolean numericIdent;
+
+ /**
+ * Creates a new, uninitialized AnimatableNumberOrIdentValue.
+ */
+ protected AnimatableNumberOrIdentValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableNumberOrIdentValue for a Number value.
+ */
+ public AnimatableNumberOrIdentValue(AnimationTarget target, float v,
+ boolean numericIdent) {
+ super(target, v);
+ this.numericIdent = numericIdent;
+ }
+
+ /**
+ * Creates a new AnimatableNumberOrIdentValue for an identifier value.
+ */
+ public AnimatableNumberOrIdentValue(AnimationTarget target, String ident) {
+ super(target);
+ this.ident = ident;
+ this.isIdent = true;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return false;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ return 0f;
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatableNumberOrIdentValue(target, 0f, numericIdent);
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String getCssText() {
+ if (isIdent) {
+ return ident;
+ }
+ if (numericIdent) {
+ return Integer.toString((int) value);
+ }
+ return super.getCssText();
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to, float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableNumberOrIdentValue res;
+ if (result == null) {
+ res = new AnimatableNumberOrIdentValue(target);
+ } else {
+ res = (AnimatableNumberOrIdentValue) result;
+ }
+
+ if (to == null) {
+ if (isIdent) {
+ res.hasChanged = !res.isIdent || !res.ident.equals(ident);
+ res.ident = ident;
+ res.isIdent = true;
+ } else if (numericIdent) {
+ res.hasChanged = res.value != value || res.isIdent;
+ res.value = value;
+ res.isIdent = false;
+ res.hasChanged = true;
+ res.numericIdent = true;
+ } else {
+ float oldValue = res.value;
+ super.interpolate(res, to, interpolation, accumulation,
+ multiplier);
+ res.numericIdent = false;
+ if (res.value != oldValue) {
+ res.hasChanged = true;
+ }
+ }
+ } else {
+ AnimatableNumberOrIdentValue toValue
+ = (AnimatableNumberOrIdentValue) to;
+ if (isIdent || toValue.isIdent || numericIdent) {
+ if (interpolation >= 0.5) {
+ if (res.isIdent != toValue.isIdent
+ || res.value != toValue.value
+ || res.isIdent && toValue.isIdent
+ && !toValue.ident.equals(ident)) {
+ res.isIdent = toValue.isIdent;
+ res.ident = toValue.ident;
+ res.value = toValue.value;
+ res.numericIdent = toValue.numericIdent;
+ res.hasChanged = true;
+ }
+ } else {
+ if (res.isIdent != isIdent
+ || res.value != value
+ || res.isIdent && isIdent
+ && !res.ident.equals(ident)) {
+ res.isIdent = isIdent;
+ res.ident = ident;
+ res.value = value;
+ res.numericIdent = numericIdent;
+ res.hasChanged = true;
+ }
+ }
+ } else {
+ super.interpolate(res, to, interpolation, accumulation,
+ multiplier);
+ res.numericIdent = false;
+ }
+ }
+ return res;
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableNumberOrPercentageValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableNumberOrPercentageValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableNumberOrPercentageValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,155 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * A number-or-percentage value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableNumberOrPercentageValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatableNumberOrPercentageValue extends AnimatableNumberValue {
+
+ /**
+ * Whether the number is a percentage.
+ */
+ protected boolean isPercentage;
+
+ /**
+ * Creates a new, uninitialized AnimatableNumberOrPercentageValue.
+ */
+ protected AnimatableNumberOrPercentageValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableNumberOrPercentageValue with a number.
+ */
+ public AnimatableNumberOrPercentageValue(AnimationTarget target, float n) {
+ super(target, n);
+ }
+
+ /**
+ * Creates a new AnimatableNumberOrPercentageValue with either a number
+ * or a percentage.
+ */
+ public AnimatableNumberOrPercentageValue(AnimationTarget target, float n,
+ boolean isPercentage) {
+ super(target, n);
+ this.isPercentage = isPercentage;
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableNumberOrPercentageValue res;
+ if (result == null) {
+ res = new AnimatableNumberOrPercentageValue(target);
+ } else {
+ res = (AnimatableNumberOrPercentageValue) result;
+ }
+
+ float newValue;
+ boolean newIsPercentage;
+
+ AnimatableNumberOrPercentageValue toValue
+ = (AnimatableNumberOrPercentageValue) to;
+ AnimatableNumberOrPercentageValue accValue
+ = (AnimatableNumberOrPercentageValue) accumulation;
+
+ if (to != null) {
+ if (toValue.isPercentage == isPercentage) {
+ newValue = value + interpolation * (toValue.value - value);
+ newIsPercentage = isPercentage;
+ } else {
+ if (interpolation >= 0.5) {
+ newValue = toValue.value;
+ newIsPercentage = toValue.isPercentage;
+ } else {
+ newValue = value;
+ newIsPercentage = isPercentage;
+ }
+ }
+ } else {
+ newValue = value;
+ newIsPercentage = isPercentage;
+ }
+
+ if (accumulation != null && accValue.isPercentage == newIsPercentage) {
+ newValue += multiplier * accValue.value;
+ }
+
+ if (res.value != newValue
+ || res.isPercentage != newIsPercentage) {
+ res.value = newValue;
+ res.isPercentage = newIsPercentage;
+ res.hasChanged = true;
+ }
+ return res;
+ }
+
+ /**
+ * Returns whether the value is a percentage.
+ */
+ public boolean isPercentage() {
+ return isPercentage;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return false;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ return 0f;
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatableNumberOrPercentageValue(target, 0, isPercentage);
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String getCssText() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(formatNumber(value));
+ if (isPercentage) {
+ sb.append('%');
+ }
+ return sb.toString();
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableNumberValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableNumberValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableNumberValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,120 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * A number value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableNumberValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatableNumberValue extends AnimatableValue {
+
+ /**
+ * The value.
+ */
+ protected float value;
+
+ /**
+ * Creates a new, uninitialized AnimatableNumberValue.
+ */
+ protected AnimatableNumberValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableNumberValue.
+ */
+ public AnimatableNumberValue(AnimationTarget target, float v) {
+ super(target);
+ value = v;
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableNumberValue res;
+ if (result == null) {
+ res = new AnimatableNumberValue(target);
+ } else {
+ res = (AnimatableNumberValue) result;
+ }
+
+ float v = value;
+ if (to != null) {
+ AnimatableNumberValue toNumber = (AnimatableNumberValue) to;
+ v += interpolation * (toNumber.value - value);
+ }
+ if (accumulation != null) {
+ AnimatableNumberValue accNumber = (AnimatableNumberValue) accumulation;
+ v += multiplier * accNumber.value;
+ }
+
+ if (res.value != v) {
+ res.value = v;
+ res.hasChanged = true;
+ }
+ return res;
+ }
+
+ /**
+ * Returns the number value.
+ */
+ public float getValue() {
+ return value;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return true;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ AnimatableNumberValue o = (AnimatableNumberValue) other;
+ return Math.abs(value - o.value);
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatableNumberValue(target, 0);
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String getCssText() {
+ return formatNumber(value);
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatablePaintValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatablePaintValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatablePaintValue.java 8 Apr 2013 10:55:49 -0000 1.1
@@ -0,0 +1,283 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * An SVG paint value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatablePaintValue.java,v 1.1 2013/04/08 10:55:49 marcin Exp $
+ */
+public class AnimatablePaintValue extends AnimatableColorValue {
+
+ // Constants for paintType.
+ public static final int PAINT_NONE = 0;
+ public static final int PAINT_CURRENT_COLOR = 1;
+ public static final int PAINT_COLOR = 2;
+ public static final int PAINT_URI = 3;
+ public static final int PAINT_URI_NONE = 4;
+ public static final int PAINT_URI_CURRENT_COLOR = 5;
+ public static final int PAINT_URI_COLOR = 6;
+ public static final int PAINT_INHERIT = 7;
+
+ /**
+ * The type of paint.
+ */
+ protected int paintType;
+
+ /**
+ * The URI of the referenced paint server.
+ */
+ protected String uri;
+
+ /**
+ * Creates a new, uninitialized AnimatablePaintValue.
+ */
+ protected AnimatablePaintValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatablePaintValue.
+ */
+ protected AnimatablePaintValue(AnimationTarget target, float r, float g,
+ float b) {
+ super(target, r, g, b);
+ }
+
+ /**
+ * Creates a new AnimatablePaintValue for a 'none' value.
+ */
+ public static AnimatablePaintValue createNonePaintValue
+ (AnimationTarget target) {
+ AnimatablePaintValue v = new AnimatablePaintValue(target);
+ v.paintType = PAINT_NONE;
+ return v;
+ }
+
+ /**
+ * Creates a new AnimatablePaintValue for a 'currentColor' value.
+ */
+ public static AnimatablePaintValue createCurrentColorPaintValue
+ (AnimationTarget target) {
+ AnimatablePaintValue v = new AnimatablePaintValue(target);
+ v.paintType = PAINT_CURRENT_COLOR;
+ return v;
+ }
+
+ /**
+ * Creates a new AnimatablePaintValue for a color value.
+ */
+ public static AnimatablePaintValue createColorPaintValue
+ (AnimationTarget target, float r, float g, float b) {
+ AnimatablePaintValue v = new AnimatablePaintValue(target, r, g, b);
+ v.paintType = PAINT_COLOR;
+ return v;
+ }
+
+ /**
+ * Creates a new AnimatablePaintValue for a URI reference.
+ */
+ public static AnimatablePaintValue createURIPaintValue
+ (AnimationTarget target, String uri) {
+ AnimatablePaintValue v = new AnimatablePaintValue(target);
+ v.uri = uri;
+ v.paintType = PAINT_URI;
+ return v;
+ }
+
+ /**
+ * Creates a new AnimatablePaintValue for a URI reference with a
+ * 'none' fallback.
+ */
+ public static AnimatablePaintValue createURINonePaintValue
+ (AnimationTarget target, String uri) {
+ AnimatablePaintValue v = new AnimatablePaintValue(target);
+ v.uri = uri;
+ v.paintType = PAINT_URI_NONE;
+ return v;
+ }
+
+ /**
+ * Creates a new AnimatablePaintValue for a URI reference with a
+ * 'currentColor' fallback.
+ */
+ public static AnimatablePaintValue createURICurrentColorPaintValue
+ (AnimationTarget target, String uri) {
+ AnimatablePaintValue v = new AnimatablePaintValue(target);
+ v.uri = uri;
+ v.paintType = PAINT_URI_CURRENT_COLOR;
+ return v;
+ }
+
+ /**
+ * Creates a new AnimatablePaintValue for a URI reference with a
+ * color fallback.
+ */
+ public static AnimatablePaintValue createURIColorPaintValue
+ (AnimationTarget target, String uri, float r, float g, float b) {
+ AnimatablePaintValue v = new AnimatablePaintValue(target, r, g, b);
+ v.uri = uri;
+ v.paintType = PAINT_URI_COLOR;
+ return v;
+ }
+
+ /**
+ * Creates a new AnimatablePaintValue for a 'inherit' value.
+ */
+ public static AnimatablePaintValue createInheritPaintValue
+ (AnimationTarget target) {
+ AnimatablePaintValue v = new AnimatablePaintValue(target);
+ v.paintType = PAINT_INHERIT;
+ return v;
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatablePaintValue res;
+ if (result == null) {
+ res = new AnimatablePaintValue(target);
+ } else {
+ res = (AnimatablePaintValue) result;
+ }
+
+ if (paintType == PAINT_COLOR) {
+ boolean canInterpolate = true;
+ if (to != null) {
+ AnimatablePaintValue toPaint = (AnimatablePaintValue) to;
+ canInterpolate = toPaint.paintType == PAINT_COLOR;
+ }
+ if (accumulation != null) {
+ AnimatablePaintValue accPaint =
+ (AnimatablePaintValue) accumulation;
+ canInterpolate =
+ canInterpolate && accPaint.paintType == PAINT_COLOR;
+ }
+ if (canInterpolate) {
+ res.paintType = PAINT_COLOR;
+ return super.interpolate
+ (res, to, interpolation, accumulation, multiplier);
+ }
+ }
+
+ int newPaintType;
+ String newURI;
+ float newRed, newGreen, newBlue;
+
+ if (to != null && interpolation >= 0.5) {
+ AnimatablePaintValue toValue = (AnimatablePaintValue) to;
+ newPaintType = toValue.paintType;
+ newURI = toValue.uri;
+ newRed = toValue.red;
+ newGreen = toValue.green;
+ newBlue = toValue.blue;
+ } else {
+ newPaintType = paintType;
+ newURI = uri;
+ newRed = red;
+ newGreen = green;
+ newBlue = blue;
+ }
+
+ if (res.paintType != newPaintType
+ || res.uri == null
+ || !res.uri.equals(newURI)
+ || res.red != newRed
+ || res.green != newGreen
+ || res.blue != newBlue) {
+ res.paintType = newPaintType;
+ res.uri = newURI;
+ res.red = newRed;
+ res.green = newGreen;
+ res.blue = newBlue;
+ res.hasChanged = true;
+ }
+
+ return res;
+ }
+
+ /**
+ * Returns the type of paint this value represents.
+ */
+ public int getPaintType() {
+ return paintType;
+ }
+
+ /**
+ * Returns the paint server URI.
+ */
+ public String getURI() {
+ return uri;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return false;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ return 0f;
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return AnimatablePaintValue.createColorPaintValue(target, 0f, 0f, 0f);
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String getCssText() {
+ switch (paintType) {
+ case PAINT_NONE:
+ return "none";
+ case PAINT_CURRENT_COLOR:
+ return "currentColor";
+ case PAINT_COLOR:
+ return super.getCssText();
+ case PAINT_URI:
+ return "url(" + uri + ")";
+ case PAINT_URI_NONE:
+ return "url(" + uri + ") none";
+ case PAINT_URI_CURRENT_COLOR:
+ return "url(" + uri + ") currentColor";
+ case PAINT_URI_COLOR:
+ return "url(" + uri + ") " + super.getCssText();
+ default: // PAINT_INHERIT
+ return "inherit";
+ }
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatablePathDataValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatablePathDataValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatablePathDataValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,198 @@
+/*
+
+ 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.batik.anim.values;
+
+import java.util.Arrays;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * An SVG path value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatablePathDataValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatablePathDataValue extends AnimatableValue {
+
+ /**
+ * The path commands. These must be one of the PATHSEG_*
+ * constants defined in {@link org.w3c.dom.svg.SVGPathSeg}.
+ */
+ protected short[] commands;
+
+ /**
+ * The path parameters. Also includes the booleans.
+ */
+ protected float[] parameters;
+
+ /**
+ * Creates a new, uninitialized AnimatablePathDataValue.
+ */
+ protected AnimatablePathDataValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatablePathDataValue.
+ */
+ public AnimatablePathDataValue(AnimationTarget target, short[] commands,
+ float[] parameters) {
+ super(target);
+ this.commands = commands;
+ this.parameters = parameters;
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to, float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatablePathDataValue toValue = (AnimatablePathDataValue) to;
+ AnimatablePathDataValue accValue =
+ (AnimatablePathDataValue) accumulation;
+
+ boolean hasTo = to != null;
+ boolean hasAcc = accumulation != null;
+ boolean canInterpolate = hasTo
+ && toValue.parameters.length == parameters.length
+ && Arrays.equals(toValue.commands, commands);
+ boolean canAccumulate = hasAcc
+ && accValue.parameters.length == parameters.length
+ && Arrays.equals(accValue.commands, commands);
+
+ AnimatablePathDataValue base;
+ if (!canInterpolate && hasTo && interpolation >= 0.5) {
+ base = toValue;
+ } else {
+ base = this;
+ }
+ int cmdCount = base.commands.length;
+ int paramCount = base.parameters.length;
+
+ AnimatablePathDataValue res;
+ if (result == null) {
+ res = new AnimatablePathDataValue(target);
+ res.commands = new short[cmdCount];
+ res.parameters = new float[paramCount];
+ System.arraycopy(base.commands, 0, res.commands, 0, cmdCount);
+ } else {
+ res = (AnimatablePathDataValue) result;
+ if (res.commands == null || res.commands.length != cmdCount) {
+ res.commands = new short[cmdCount];
+ System.arraycopy(base.commands, 0, res.commands, 0, cmdCount);
+ res.hasChanged = true;
+ } else {
+ if (!Arrays.equals(base.commands, res.commands)) {
+ System.arraycopy(base.commands, 0, res.commands, 0,
+ cmdCount);
+ res.hasChanged = true;
+ }
+ }
+ }
+
+ for (int i = 0; i < paramCount; i++) {
+ float newValue = base.parameters[i];
+ if (canInterpolate) {
+ newValue += interpolation * (toValue.parameters[i] - newValue);
+ }
+ if (canAccumulate) {
+ newValue += multiplier * accValue.parameters[i];
+ }
+ if (res.parameters[i] != newValue) {
+ res.parameters[i] = newValue;
+ res.hasChanged = true;
+ }
+ }
+
+ return res;
+ }
+
+ /**
+ * Returns the array of path data commands.
+ */
+ public short[] getCommands() {
+ return commands;
+ }
+
+ /**
+ * Returns the array of path data parameters.
+ */
+ public float[] getParameters() {
+ return parameters;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return false;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ return 0f;
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ short[] cmds = new short[commands.length];
+ System.arraycopy(commands, 0, cmds, 0, commands.length);
+ float[] params = new float[parameters.length];
+ return new AnimatablePathDataValue(target, cmds, params);
+ }
+
+ /**
+ * The path data commands.
+ */
+ protected static final char[] PATH_COMMANDS = {
+ ' ', 'z', 'M', 'm', 'L', 'l', 'C', 'c', 'Q', 'q', 'A', 'a', 'H', 'h',
+ 'V', 'v', 'S', 's', 'T', 't'
+ };
+
+ /**
+ * The number of parameters for each path command.
+ */
+ protected static final int[] PATH_PARAMS = {
+ 0, 0, 2, 2, 2, 2, 6, 6, 4, 4, 7, 7, 1, 1, 1, 1, 4, 4, 2, 2
+ };
+
+ /**
+ * Returns a string representation of this object.
+ */
+ public String toStringRep() {
+ StringBuffer sb = new StringBuffer();
+ int k = 0;
+ for (int i = 0; i < commands.length; i++) {
+ sb.append(PATH_COMMANDS[commands[i]]);
+ for (int j = 0; j < PATH_PARAMS[commands[i]]; j++) {
+ sb.append(' ');
+ sb.append(parameters[k++]);
+ }
+ }
+ return sb.toString();
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatablePercentageValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatablePercentageValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatablePercentageValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,73 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * A percentage value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatablePercentageValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatablePercentageValue extends AnimatableNumberValue {
+
+ /**
+ * Creates a new, uninitialized AnimatablePercentageValue.
+ */
+ protected AnimatablePercentageValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatablePercentageValue.
+ */
+ public AnimatablePercentageValue(AnimationTarget target, float v) {
+ super(target, v);
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ if (result == null) {
+ result = new AnimatablePercentageValue(target);
+ }
+ return super.interpolate
+ (result, to, interpolation, accumulation, multiplier);
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatablePercentageValue(target, 0);
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String getCssText() {
+ return super.getCssText() + "%";
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatablePointListValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatablePointListValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatablePointListValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,83 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * An SVG point list value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatablePointListValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatablePointListValue extends AnimatableNumberListValue {
+
+ /**
+ * Creates a new, uninitialized AnimatablePointListValue.
+ */
+ protected AnimatablePointListValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatablePointListValue.
+ */
+ public AnimatablePointListValue(AnimationTarget target, float[] numbers) {
+ super(target, numbers);
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ if (result == null) {
+ result = new AnimatablePointListValue(target);
+ }
+ return super.interpolate
+ (result, to, interpolation, accumulation, multiplier);
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return false;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ return 0f;
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ float[] ns = new float[numbers.length];
+ return new AnimatablePointListValue(target, ns);
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatablePreserveAspectRatioValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatablePreserveAspectRatioValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatablePreserveAspectRatioValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,176 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+import org.apache.batik.util.SVGConstants;
+
+import org.w3c.dom.svg.SVGPreserveAspectRatio;
+
+/**
+ * An SVG preserveAspectRatio value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatablePreserveAspectRatioValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatablePreserveAspectRatioValue extends AnimatableValue {
+
+ /**
+ * Strings for the 'align' values.
+ */
+ protected static final String[] ALIGN_VALUES = {
+ null,
+ SVGConstants.SVG_NONE_VALUE,
+ SVGConstants.SVG_XMINYMIN_VALUE,
+ SVGConstants.SVG_XMIDYMIN_VALUE,
+ SVGConstants.SVG_XMAXYMIN_VALUE,
+ SVGConstants.SVG_XMINYMID_VALUE,
+ SVGConstants.SVG_XMIDYMID_VALUE,
+ SVGConstants.SVG_XMAXYMID_VALUE,
+ SVGConstants.SVG_XMINYMAX_VALUE,
+ SVGConstants.SVG_XMIDYMAX_VALUE,
+ SVGConstants.SVG_XMAXYMAX_VALUE
+ };
+
+ /**
+ * Strings for the 'meet-or-slice' values.
+ */
+ protected static final String[] MEET_OR_SLICE_VALUES = {
+ null,
+ SVGConstants.SVG_MEET_VALUE,
+ SVGConstants.SVG_SLICE_VALUE
+ };
+
+ /**
+ * The align value.
+ */
+ protected short align;
+
+ /**
+ * The meet-or-slice value.
+ */
+ protected short meetOrSlice;
+
+ /**
+ * Creates a new, uninitialized AnimatablePreserveAspectRatioValue.
+ */
+ protected AnimatablePreserveAspectRatioValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatablePreserveAspectRatioValue.
+ */
+ public AnimatablePreserveAspectRatioValue(AnimationTarget target,
+ short align, short meetOrSlice) {
+ super(target);
+ this.align = align;
+ this.meetOrSlice = meetOrSlice;
+ }
+
+ /**
+ * Performs interpolation to the given value. Preserve aspect ratio values
+ * cannot be interpolated.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to, float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatablePreserveAspectRatioValue res;
+ if (result == null) {
+ res = new AnimatablePreserveAspectRatioValue(target);
+ } else {
+ res = (AnimatablePreserveAspectRatioValue) result;
+ }
+
+ short newAlign, newMeetOrSlice;
+ if (to != null && interpolation >= 0.5) {
+ AnimatablePreserveAspectRatioValue toValue =
+ (AnimatablePreserveAspectRatioValue) to;
+ newAlign = toValue.align;
+ newMeetOrSlice = toValue.meetOrSlice;
+ } else {
+ newAlign = align;
+ newMeetOrSlice = meetOrSlice;
+ }
+
+ if (res.align != newAlign || res.meetOrSlice != newMeetOrSlice) {
+ res.align = align;
+ res.meetOrSlice = meetOrSlice;
+ res.hasChanged = true;
+ }
+ return res;
+ }
+
+ /**
+ * Returns the align value.
+ */
+ public short getAlign() {
+ return align;
+ }
+
+ /**
+ * Returns the meet-or-slice value.
+ */
+ public short getMeetOrSlice() {
+ return meetOrSlice;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return false;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ return 0f;
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatablePreserveAspectRatioValue
+ (target, SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE,
+ SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET);
+ }
+
+ /**
+ * Returns a string representation of this object.
+ */
+ public String toStringRep() {
+ if (align < 1 || align > 10) {
+ return null;
+ }
+ String value = ALIGN_VALUES[align];
+ if (align == SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE) {
+ return value;
+ }
+ if (meetOrSlice < 1 || meetOrSlice > 2) {
+ return null;
+ }
+ return value + ' ' + MEET_OR_SLICE_VALUES[meetOrSlice];
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableRectValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableRectValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableRectValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,177 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * An SVG rect value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableRectValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatableRectValue extends AnimatableValue {
+
+ /**
+ * The x coordinate.
+ */
+ protected float x;
+
+ /**
+ * The y coordinate.
+ */
+ protected float y;
+
+ /**
+ * The width.
+ */
+ protected float width;
+
+ /**
+ * The height.
+ */
+ protected float height;
+
+ /**
+ * Creates a new, uninitialized AnimatableRectValue.
+ */
+ protected AnimatableRectValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableRectValue with one number.
+ */
+ public AnimatableRectValue(AnimationTarget target, float x, float y,
+ float w, float h) {
+ super(target);
+ this.x = x;
+ this.y = y;
+ this.width = w;
+ this.height = h;
+ }
+
+ /**
+ * Performs interpolation to the given value. Rect values cannot be
+ * interpolated.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableRectValue res;
+ if (result == null) {
+ res = new AnimatableRectValue(target);
+ } else {
+ res = (AnimatableRectValue) result;
+ }
+
+ float newX = x, newY = y, newWidth = width, newHeight = height;
+ if (to != null) {
+ AnimatableRectValue toValue = (AnimatableRectValue) to;
+ newX += interpolation * (toValue.x - x);
+ newY += interpolation * (toValue.y - y);
+ newWidth += interpolation * (toValue.width - width);
+ newHeight += interpolation * (toValue.height - height);
+ }
+ if (accumulation != null && multiplier != 0) {
+ AnimatableRectValue accValue = (AnimatableRectValue) accumulation;
+ newX += multiplier * accValue.x;
+ newY += multiplier * accValue.y;
+ newWidth += multiplier * accValue.width;
+ newHeight += multiplier * accValue.height;
+ }
+ if (res.x != newX || res.y != newY
+ || res.width != newWidth || res.height != newHeight) {
+ res.x = newX;
+ res.y = newY;
+ res.width = newWidth;
+ res.height = newHeight;
+ res.hasChanged = true;
+ }
+ return res;
+ }
+
+ /**
+ * Returns the x coordinate.
+ */
+ public float getX() {
+ return x;
+ }
+
+ /**
+ * Returns the y coordinate.
+ */
+ public float getY() {
+ return y;
+ }
+
+ /**
+ * Returns the width.
+ */
+ public float getWidth() {
+ return width;
+ }
+
+ /**
+ * Returns the height.
+ */
+ public float getHeight() {
+ return height;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return false;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ return 0f;
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatableRectValue(target, 0f, 0f, 0f, 0f);
+ }
+
+ /**
+ * Returns a string representation of this object.
+ */
+ public String toStringRep() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(x);
+ sb.append(',');
+ sb.append(y);
+ sb.append(',');
+ sb.append(width);
+ sb.append(',');
+ sb.append(height);
+ return sb.toString();
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableStringValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableStringValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableStringValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,118 @@
+/*
+
+ 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.batik.anim.values;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * A string value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableStringValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatableStringValue extends AnimatableValue {
+
+ /**
+ * The string value.
+ */
+ protected String string;
+
+ /**
+ * Creates a new, uninitialized AnimatableStringValue.
+ */
+ protected AnimatableStringValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableStringValue.
+ */
+ public AnimatableStringValue(AnimationTarget target, String s) {
+ super(target);
+ string = s;
+ }
+
+ /**
+ * Performs interpolation to the given value. String values cannot be
+ * interpolated.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to, float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+ AnimatableStringValue res;
+ if (result == null) {
+ res = new AnimatableStringValue(target);
+ } else {
+ res = (AnimatableStringValue) result;
+ }
+
+ String newString;
+ if (to != null && interpolation >= 0.5) {
+ AnimatableStringValue toValue =
+ (AnimatableStringValue) to;
+ newString = toValue.string;
+ } else {
+ newString = string;
+ }
+
+ if (res.string == null || !res.string.equals(newString)) {
+ res.string = newString;
+ res.hasChanged = true;
+ }
+ return res;
+ }
+
+ /**
+ * Returns the string.
+ */
+ public String getString() {
+ return string;
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return false;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ return 0f;
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatableStringValue(target, "");
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String getCssText() {
+ return string;
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableTransformListValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableTransformListValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableTransformListValue.java 8 Apr 2013 10:55:48 -0000 1.1
@@ -0,0 +1,611 @@
+/*
+
+ 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.batik.anim.values;
+
+import java.util.Iterator;
+import java.util.Vector;
+import java.util.List;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+import org.apache.batik.dom.svg.AbstractSVGTransform;
+import org.apache.batik.dom.svg.SVGOMTransform;
+
+import org.w3c.dom.svg.SVGMatrix;
+import org.w3c.dom.svg.SVGTransform;
+
+/**
+ * An SVG transform list value in the animation system.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableTransformListValue.java,v 1.1 2013/04/08 10:55:48 marcin Exp $
+ */
+public class AnimatableTransformListValue extends AnimatableValue {
+
+ /**
+ * Identity transform value of type 'skewX'.
+ */
+ protected static SVGOMTransform IDENTITY_SKEWX = new SVGOMTransform();
+
+ /**
+ * Identity transform value of type 'skewY'.
+ */
+ protected static SVGOMTransform IDENTITY_SKEWY = new SVGOMTransform();
+
+ /**
+ * Identity transform value of type 'scale'.
+ */
+ protected static SVGOMTransform IDENTITY_SCALE = new SVGOMTransform();
+
+ /**
+ * Identity transform value of type 'rotate'.
+ */
+ protected static SVGOMTransform IDENTITY_ROTATE = new SVGOMTransform();
+
+ /**
+ * Identity transform value of type 'translate'.
+ */
+ protected static SVGOMTransform IDENTITY_TRANSLATE = new SVGOMTransform();
+
+ static {
+ IDENTITY_SKEWX.setSkewX(0f);
+ IDENTITY_SKEWY.setSkewY(0f);
+ IDENTITY_SCALE.setScale(0f, 0f);
+ IDENTITY_ROTATE.setRotate(0f, 0f, 0f);
+ IDENTITY_TRANSLATE.setTranslate(0f, 0f);
+ }
+
+ /**
+ * List of transforms.
+ */
+ protected Vector transforms;
+
+ /**
+ * Creates a new, uninitialized AnimatableTransformListValue.
+ */
+ protected AnimatableTransformListValue(AnimationTarget target) {
+ super(target);
+ }
+
+ /**
+ * Creates a new AnimatableTransformListValue with a single transform.
+ */
+ public AnimatableTransformListValue(AnimationTarget target,
+ AbstractSVGTransform t) {
+ super(target);
+ this.transforms = new Vector();
+ this.transforms.add(t);
+ }
+
+ /**
+ * Creates a new AnimatableTransformListValue with a transform list.
+ */
+ public AnimatableTransformListValue(AnimationTarget target,
+ List transforms) {
+ super(target);
+
+ this.transforms = new Vector( transforms );
+
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ */
+ public AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier) {
+
+ AnimatableTransformListValue toTransformList =
+ (AnimatableTransformListValue) to;
+ AnimatableTransformListValue accTransformList =
+ (AnimatableTransformListValue) accumulation;
+
+ int accSize = accumulation == null ? 0 : accTransformList.transforms.size();
+ int newSize = transforms.size() + accSize * multiplier;
+
+ AnimatableTransformListValue res;
+ if (result == null) {
+ res = new AnimatableTransformListValue(target);
+ res.transforms = new Vector(newSize);
+ res.transforms.setSize(newSize);
+ } else {
+ res = (AnimatableTransformListValue) result;
+ if (res.transforms == null) {
+ res.transforms = new Vector(newSize);
+ res.transforms.setSize(newSize);
+ } else if (res.transforms.size() != newSize) {
+ res.transforms.setSize(newSize);
+ }
+ }
+
+ int index = 0;
+ for (int j = 0; j < multiplier; j++) {
+ for (int i = 0; i < accSize; i++, index++) {
+ res.transforms.setElementAt
+ (accTransformList.transforms.elementAt(i), index);
+ }
+ }
+ for (int i = 0; i < transforms.size() - 1; i++, index++) {
+ res.transforms.setElementAt(transforms.elementAt(i), index);
+ }
+
+ if (to != null) {
+ AbstractSVGTransform tt =
+ (AbstractSVGTransform) toTransformList.transforms.lastElement();
+ AbstractSVGTransform ft = null;
+ int type;
+ if (transforms.isEmpty()) {
+ // For the case of an additive animation with an underlying
+ // transform list of zero elements.
+ type = tt.getType();
+ switch (type) {
+ case SVGTransform.SVG_TRANSFORM_SKEWX:
+ ft = IDENTITY_SKEWX;
+ break;
+ case SVGTransform.SVG_TRANSFORM_SKEWY:
+ ft = IDENTITY_SKEWY;
+ break;
+ case SVGTransform.SVG_TRANSFORM_SCALE:
+ ft = IDENTITY_SCALE;
+ break;
+ case SVGTransform.SVG_TRANSFORM_ROTATE:
+ ft = IDENTITY_ROTATE;
+ break;
+ case SVGTransform.SVG_TRANSFORM_TRANSLATE:
+ ft = IDENTITY_TRANSLATE;
+ break;
+ }
+ } else {
+ ft = (AbstractSVGTransform) transforms.lastElement();
+ type = ft.getType();
+ }
+ if (type == tt.getType()) {
+ AbstractSVGTransform t;
+ if (res.transforms.isEmpty()) {
+ t = new SVGOMTransform();
+ res.transforms.add(t);
+ } else {
+ t = (AbstractSVGTransform) res.transforms.elementAt(index);
+ if (t == null) {
+ t = new SVGOMTransform();
+ res.transforms.setElementAt(t, index);
+ }
+ }
+ float x, y, r = 0;
+ switch (type) {
+ case SVGTransform.SVG_TRANSFORM_SKEWX:
+ case SVGTransform.SVG_TRANSFORM_SKEWY:
+ r = ft.getAngle();
+ r += interpolation * (tt.getAngle() - r);
+ if (type == SVGTransform.SVG_TRANSFORM_SKEWX) {
+ t.setSkewX(r);
+ } else if (type == SVGTransform.SVG_TRANSFORM_SKEWY) {
+ t.setSkewY(r);
+ }
+ break;
+ case SVGTransform.SVG_TRANSFORM_SCALE: {
+ SVGMatrix fm = ft.getMatrix();
+ SVGMatrix tm = tt.getMatrix();
+ x = fm.getA();
+ y = fm.getD();
+ x += interpolation * (tm.getA() - x);
+ y += interpolation * (tm.getD() - y);
+ t.setScale(x, y);
+ break;
+ }
+ case SVGTransform.SVG_TRANSFORM_ROTATE: {
+ x = ft.getX();
+ y = ft.getY();
+ x += interpolation * (tt.getX() - x);
+ y += interpolation * (tt.getY() - y);
+ r = ft.getAngle();
+ r += interpolation * (tt.getAngle() - r);
+ t.setRotate(r, x, y);
+ break;
+ }
+ case SVGTransform.SVG_TRANSFORM_TRANSLATE: {
+ SVGMatrix fm = ft.getMatrix();
+ SVGMatrix tm = tt.getMatrix();
+ x = fm.getE();
+ y = fm.getF();
+ x += interpolation * (tm.getE() - x);
+ y += interpolation * (tm.getF() - y);
+ t.setTranslate(x, y);
+ break;
+ }
+ }
+ }
+ } else {
+ AbstractSVGTransform ft =
+ (AbstractSVGTransform) transforms.lastElement();
+ AbstractSVGTransform t =
+ (AbstractSVGTransform) res.transforms.elementAt(index);
+ if (t == null) {
+ t = new SVGOMTransform();
+ res.transforms.setElementAt(t, index);
+ }
+ t.assign(ft);
+ }
+
+ // XXX Do better checking for changes.
+ res.hasChanged = true;
+
+ return res;
+ }
+
+ /**
+ * Performs a two-way interpolation between the specified values.
+ * value[12] and to[12] must all be of the same type, either scale or
+ * translation transforms, or all null.
+ */
+ public static AnimatableTransformListValue interpolate
+ (AnimatableTransformListValue res,
+ AnimatableTransformListValue value1,
+ AnimatableTransformListValue value2,
+ AnimatableTransformListValue to1,
+ AnimatableTransformListValue to2,
+ float interpolation1,
+ float interpolation2,
+ AnimatableTransformListValue accumulation,
+ int multiplier) {
+
+ int accSize = accumulation == null ? 0 : accumulation.transforms.size();
+ int newSize = accSize * multiplier + 1;
+
+ if (res == null) {
+ res = new AnimatableTransformListValue(to1.target);
+ res.transforms = new Vector(newSize);
+ res.transforms.setSize(newSize);
+ } else {
+ if (res.transforms == null) {
+ res.transforms = new Vector(newSize);
+ res.transforms.setSize(newSize);
+ } else if (res.transforms.size() != newSize) {
+ res.transforms.setSize(newSize);
+ }
+ }
+
+ int index = 0;
+ for (int j = 0; j < multiplier; j++) {
+ for (int i = 0; i < accSize; i++, index++) {
+ res.transforms.setElementAt
+ (accumulation.transforms.elementAt(i), index);
+ }
+ }
+
+ AbstractSVGTransform ft1 =
+ (AbstractSVGTransform) value1.transforms.lastElement();
+ AbstractSVGTransform ft2 =
+ (AbstractSVGTransform) value2.transforms.lastElement();
+
+ AbstractSVGTransform t =
+ (AbstractSVGTransform) res.transforms.elementAt(index);
+ if (t == null) {
+ t = new SVGOMTransform();
+ res.transforms.setElementAt(t, index);
+ }
+
+ int type = ft1.getType();
+
+ float x, y;
+ if (type == SVGTransform.SVG_TRANSFORM_SCALE) {
+ x = ft1.getMatrix().getA();
+ y = ft2.getMatrix().getD();
+ } else {
+ x = ft1.getMatrix().getE();
+ y = ft2.getMatrix().getF();
+ }
+
+ if (to1 != null) {
+ AbstractSVGTransform tt1 =
+ (AbstractSVGTransform) to1.transforms.lastElement();
+ AbstractSVGTransform tt2 =
+ (AbstractSVGTransform) to2.transforms.lastElement();
+
+ if (type == SVGTransform.SVG_TRANSFORM_SCALE) {
+ x += interpolation1 * (tt1.getMatrix().getA() - x);
+ y += interpolation2 * (tt2.getMatrix().getD() - y);
+ } else {
+ x += interpolation1 * (tt1.getMatrix().getE() - x);
+ y += interpolation2 * (tt2.getMatrix().getF() - y);
+ }
+ }
+
+ if (type == SVGTransform.SVG_TRANSFORM_SCALE) {
+ t.setScale(x, y);
+ } else {
+ t.setTranslate(x, y);
+ }
+
+ // XXX Do better checking for changes.
+ res.hasChanged = true;
+
+ return res;
+ }
+
+ /**
+ * Performs a three-way interpolation between the specified values.
+ * value[123] and to[123] must all be single rotation transforms,
+ * or all null.
+ */
+ public static AnimatableTransformListValue interpolate
+ (AnimatableTransformListValue res,
+ AnimatableTransformListValue value1,
+ AnimatableTransformListValue value2,
+ AnimatableTransformListValue value3,
+ AnimatableTransformListValue to1,
+ AnimatableTransformListValue to2,
+ AnimatableTransformListValue to3,
+ float interpolation1,
+ float interpolation2,
+ float interpolation3,
+ AnimatableTransformListValue accumulation,
+ int multiplier) {
+
+ int accSize = accumulation == null ? 0 : accumulation.transforms.size();
+ int newSize = accSize * multiplier + 1;
+
+ if (res == null) {
+ res = new AnimatableTransformListValue(to1.target);
+ res.transforms = new Vector(newSize);
+ res.transforms.setSize(newSize);
+ } else {
+ if (res.transforms == null) {
+ res.transforms = new Vector(newSize);
+ res.transforms.setSize(newSize);
+ } else if (res.transforms.size() != newSize) {
+ res.transforms.setSize(newSize);
+ }
+ }
+
+ int index = 0;
+ for (int j = 0; j < multiplier; j++) {
+ for (int i = 0; i < accSize; i++, index++) {
+ res.transforms.setElementAt
+ (accumulation.transforms.elementAt(i), index);
+ }
+ }
+
+ AbstractSVGTransform ft1 =
+ (AbstractSVGTransform) value1.transforms.lastElement();
+ AbstractSVGTransform ft2 =
+ (AbstractSVGTransform) value2.transforms.lastElement();
+ AbstractSVGTransform ft3 =
+ (AbstractSVGTransform) value3.transforms.lastElement();
+
+ AbstractSVGTransform t =
+ (AbstractSVGTransform) res.transforms.elementAt(index);
+ if (t == null) {
+ t = new SVGOMTransform();
+ res.transforms.setElementAt(t, index);
+ }
+
+ float x, y, r;
+ r = ft1.getAngle();
+ x = ft2.getX();
+ y = ft3.getY();
+
+ if (to1 != null) {
+ AbstractSVGTransform tt1 =
+ (AbstractSVGTransform) to1.transforms.lastElement();
+ AbstractSVGTransform tt2 =
+ (AbstractSVGTransform) to2.transforms.lastElement();
+ AbstractSVGTransform tt3 =
+ (AbstractSVGTransform) to3.transforms.lastElement();
+
+ r += interpolation1 * (tt1.getAngle() - r);
+ x += interpolation2 * (tt2.getX() - x);
+ y += interpolation3 * (tt3.getY() - y);
+ }
+ t.setRotate(r, x, y);
+
+ // XXX Do better checking for changes.
+ res.hasChanged = true;
+
+ return res;
+ }
+
+ /**
+ * Gets the transforms.
+ */
+ public Iterator getTransforms() {
+ return transforms.iterator();
+ }
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public boolean canPace() {
+ return true;
+ }
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public float distanceTo(AnimatableValue other) {
+ AnimatableTransformListValue o = (AnimatableTransformListValue) other;
+ if (transforms.isEmpty() || o.transforms.isEmpty()) {
+ return 0f;
+ }
+ AbstractSVGTransform t1 = (AbstractSVGTransform) transforms.lastElement();
+ AbstractSVGTransform t2 = (AbstractSVGTransform) o.transforms.lastElement();
+ short type1 = t1.getType();
+ if (type1 != t2.getType()) {
+ return 0f;
+ }
+ SVGMatrix m1 = t1.getMatrix();
+ SVGMatrix m2 = t2.getMatrix();
+ switch (type1) {
+ case SVGTransform.SVG_TRANSFORM_TRANSLATE:
+ return Math.abs(m1.getE() - m2.getE()) + Math.abs(m1.getF() - m2.getF());
+ case SVGTransform.SVG_TRANSFORM_SCALE:
+ return Math.abs(m1.getA() - m2.getA()) + Math.abs(m1.getD() - m2.getD());
+ case SVGTransform.SVG_TRANSFORM_ROTATE:
+ case SVGTransform.SVG_TRANSFORM_SKEWX:
+ case SVGTransform.SVG_TRANSFORM_SKEWY:
+ return Math.abs(t1.getAngle() - t2.getAngle());
+ }
+ return 0f;
+ }
+
+ /**
+ * Returns the distance between this value's first component and the
+ * specified other value's first component.
+ */
+ public float distanceTo1(AnimatableValue other) {
+ AnimatableTransformListValue o = (AnimatableTransformListValue) other;
+ if (transforms.isEmpty() || o.transforms.isEmpty()) {
+ return 0f;
+ }
+ AbstractSVGTransform t1 = (AbstractSVGTransform) transforms.lastElement();
+ AbstractSVGTransform t2 = (AbstractSVGTransform) o.transforms.lastElement();
+ short type1 = t1.getType();
+ if (type1 != t2.getType()) {
+ return 0f;
+ }
+ SVGMatrix m1 = t1.getMatrix();
+ SVGMatrix m2 = t2.getMatrix();
+ switch (type1) {
+ case SVGTransform.SVG_TRANSFORM_TRANSLATE:
+ return Math.abs(m1.getE() - m2.getE());
+ case SVGTransform.SVG_TRANSFORM_SCALE:
+ return Math.abs(m1.getA() - m2.getA());
+ case SVGTransform.SVG_TRANSFORM_ROTATE:
+ case SVGTransform.SVG_TRANSFORM_SKEWX:
+ case SVGTransform.SVG_TRANSFORM_SKEWY:
+ return Math.abs(t1.getAngle() - t2.getAngle());
+ }
+ return 0f;
+ }
+
+ /**
+ * Returns the distance between this value's second component and the
+ * specified other value's second component.
+ */
+ public float distanceTo2(AnimatableValue other) {
+ AnimatableTransformListValue o = (AnimatableTransformListValue) other;
+ if (transforms.isEmpty() || o.transforms.isEmpty()) {
+ return 0f;
+ }
+ AbstractSVGTransform t1 = (AbstractSVGTransform) transforms.lastElement();
+ AbstractSVGTransform t2 = (AbstractSVGTransform) o.transforms.lastElement();
+ short type1 = t1.getType();
+ if (type1 != t2.getType()) {
+ return 0f;
+ }
+ SVGMatrix m1 = t1.getMatrix();
+ SVGMatrix m2 = t2.getMatrix();
+ switch (type1) {
+ case SVGTransform.SVG_TRANSFORM_TRANSLATE:
+ return Math.abs(m1.getF() - m2.getF());
+ case SVGTransform.SVG_TRANSFORM_SCALE:
+ return Math.abs(m1.getD() - m2.getD());
+ case SVGTransform.SVG_TRANSFORM_ROTATE:
+ return Math.abs(t1.getX() - t2.getX());
+ }
+ return 0f;
+ }
+
+ /**
+ * Returns the distance between this value's third component and the
+ * specified other value's third component.
+ */
+ public float distanceTo3(AnimatableValue other) {
+ AnimatableTransformListValue o = (AnimatableTransformListValue) other;
+ if (transforms.isEmpty() || o.transforms.isEmpty()) {
+ return 0f;
+ }
+ AbstractSVGTransform t1 = (AbstractSVGTransform) transforms.lastElement();
+ AbstractSVGTransform t2 = (AbstractSVGTransform) o.transforms.lastElement();
+ short type1 = t1.getType();
+ if (type1 != t2.getType()) {
+ return 0f;
+ }
+ if (type1 == SVGTransform.SVG_TRANSFORM_ROTATE) {
+ return Math.abs(t1.getY() - t2.getY());
+ }
+ return 0f;
+ }
+
+ /**
+ * Returns a zero value of this AnimatableValue's type. This returns an
+ * empty transform list.
+ */
+ public AnimatableValue getZeroValue() {
+ return new AnimatableTransformListValue(target, new Vector(5));
+ }
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String toStringRep() {
+ StringBuffer sb = new StringBuffer();
+ Iterator i = transforms.iterator();
+ while (i.hasNext()) {
+ AbstractSVGTransform t = (AbstractSVGTransform) i.next();
+ if (t == null) {
+ sb.append("null");
+ } else {
+ SVGMatrix m = t.getMatrix();
+ switch (t.getType()) {
+ case SVGTransform.SVG_TRANSFORM_TRANSLATE:
+ sb.append("translate(");
+ sb.append(m.getE());
+ sb.append(',');
+ sb.append(m.getF());
+ sb.append(')');
+ break;
+ case SVGTransform.SVG_TRANSFORM_SCALE:
+ sb.append("scale(");
+ sb.append(m.getA());
+ sb.append(',');
+ sb.append(m.getD());
+ sb.append(')');
+ break;
+ case SVGTransform.SVG_TRANSFORM_SKEWX:
+ sb.append("skewX(");
+ sb.append(t.getAngle());
+ sb.append(')');
+ break;
+ case SVGTransform.SVG_TRANSFORM_SKEWY:
+ sb.append("skewY(");
+ sb.append(t.getAngle());
+ sb.append(')');
+ break;
+ case SVGTransform.SVG_TRANSFORM_ROTATE:
+ sb.append("rotate(");
+ sb.append(t.getAngle());
+ sb.append(',');
+ sb.append(t.getX());
+ sb.append(',');
+ sb.append(t.getY());
+ sb.append(')');
+ break;
+ }
+ }
+ if (i.hasNext()) {
+ sb.append(' ');
+ }
+ }
+ return sb.toString();
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableValue.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableValue.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/anim/values/AnimatableValue.java 8 Apr 2013 10:55:49 -0000 1.1
@@ -0,0 +1,134 @@
+/*
+
+ 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.batik.anim.values;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+
+import org.apache.batik.dom.anim.AnimationTarget;
+
+/**
+ * An abstract class for values in the animation engine.
+ *
+ * @author Cameron McCormack
+ * @version $Id: AnimatableValue.java,v 1.1 2013/04/08 10:55:49 marcin Exp $
+ */
+public abstract class AnimatableValue {
+
+ /**
+ * A formatting object to get CSS compatible float strings.
+ */
+ protected static DecimalFormat decimalFormat = new DecimalFormat
+ ("0.0###########################################################",
+ new DecimalFormatSymbols(Locale.ENGLISH));
+
+ /**
+ * The target of the animation.
+ */
+ protected AnimationTarget target;
+
+ /**
+ * Whether this value has changed since the last call to
+ * {@link #hasChanged()}. This must be updated within {@link #interpolate}
+ * in descendant classes.
+ */
+ protected boolean hasChanged = true;
+
+ /**
+ * Creates a new AnimatableValue.
+ */
+ protected AnimatableValue(AnimationTarget target) {
+ this.target = target;
+ }
+
+ /**
+ * Returns a CSS compatible string version of the specified float.
+ */
+ public static String formatNumber(float f) {
+ return decimalFormat.format(f);
+ }
+
+ /**
+ * Performs interpolation to the given value.
+ * @param result the object in which to store the result of the
+ * interpolation, or null if a new object should be created
+ * @param to the value this value should be interpolated towards, or null
+ * if no actual interpolation should be performed
+ * @param interpolation the interpolation distance, 0 <= interpolation
+ * <= 1
+ * @param accumulation an accumulation to add to the interpolated value
+ * @param multiplier an amount the accumulation values should be multiplied
+ * by before being added to the interpolated value
+ */
+ public abstract AnimatableValue interpolate(AnimatableValue result,
+ AnimatableValue to,
+ float interpolation,
+ AnimatableValue accumulation,
+ int multiplier);
+
+ /**
+ * Returns whether two values of this type can have their distance
+ * computed, as needed by paced animation.
+ */
+ public abstract boolean canPace();
+
+ /**
+ * Returns the absolute distance between this value and the specified other
+ * value.
+ */
+ public abstract float distanceTo(AnimatableValue other);
+
+ /**
+ * Returns a zero value of this AnimatableValue's type.
+ */
+ public abstract AnimatableValue getZeroValue();
+
+ /**
+ * Returns the CSS text representation of the value.
+ */
+ public String getCssText() {
+ return null;
+ }
+
+ /**
+ * Returns whether the value in this AnimatableValue has been modified.
+ */
+ public boolean hasChanged() {
+ boolean ret = hasChanged;
+ hasChanged = false;
+ return ret;
+ }
+
+ /**
+ * Returns a string representation of this object. This should be
+ * overridden in classes that do not have a CSS representation.
+ */
+ public String toStringRep() {
+ return getCssText();
+ }
+
+ /**
+ * Returns a string representation of this object prefixed with its
+ * class name.
+ */
+ public String toString() {
+ return getClass().getName() + "[" + toStringRep() + "]";
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/DefaultSVGConverterController.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/rasterizer/DefaultSVGConverterController.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/DefaultSVGConverterController.java 8 Apr 2013 10:55:05 -0000 1.1
@@ -0,0 +1,87 @@
+/*
+
+ 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.batik.apps.rasterizer;
+
+import java.io.File;
+import java.util.Map;
+import java.util.List;
+
+import org.apache.batik.transcoder.Transcoder;
+
+/**
+ * Default controller for the
+ * SVGConverter operation.
+ *
+ * @author Vincent Hardy
+ * @version $Id: DefaultSVGConverterController.java,v 1.1 2013/04/08 10:55:05 marcin Exp $
+ */
+public class DefaultSVGConverterController implements SVGConverterController {
+ /**
+ * Invoked when the rasterizer has computed the
+ * exact description of what it should do. The controller
+ * should return true if the transcoding process should
+ * proceed or false otherwise.
+ *
+ * @param transcoder Transcoder which will be used for the conversion
+ * @param hints set of hints that were set on the transcoder
+ * @param sources list of SVG sources it will convert.
+ * @param dest list of destination file it will use
+ */
+ public boolean proceedWithComputedTask(Transcoder transcoder,
+ Map hints,
+ List sources,
+ List dest){
+ return true;
+ }
+
+ /**
+ * Invoked when the rasterizer is about to start transcoding
+ * of a given source.
+ * The controller should return true if the source should be
+ * transcoded and false otherwise.
+ */
+ public boolean proceedWithSourceTranscoding(SVGConverterSource source,
+ File dest) {
+ System.out.println("About to transcoder source of type: " + source.getClass().getName());
+ return true;
+ }
+
+ /**
+ * Invoked when the rasterizer got an error while
+ * transcoding the input source.
+ * The controller should return true if the transcoding process
+ * should continue on other sources and it should return false
+ * if it should not.
+ *
+ * @param errorCode see the {@link SVGConverter} error code descriptions.
+ */
+ public boolean proceedOnSourceTranscodingFailure(SVGConverterSource source,
+ File dest,
+ String errorCode){
+ return true;
+ }
+
+ /**
+ * Invoked when the rasterizer successfully transcoded
+ * the input source.
+ */
+ public void onSourceTranscodingSuccess(SVGConverterSource source,
+ File dest){
+ }
+}
\ No newline at end of file
Index: 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/DestinationType.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/rasterizer/DestinationType.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/DestinationType.java 8 Apr 2013 10:55:05 -0000 1.1
@@ -0,0 +1,130 @@
+/*
+
+ 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.batik.apps.rasterizer;
+
+import org.apache.batik.transcoder.Transcoder;
+import org.apache.batik.transcoder.image.JPEGTranscoder;
+import org.apache.batik.transcoder.image.PNGTranscoder;
+import org.apache.batik.transcoder.image.TIFFTranscoder;
+
+/**
+ * Describes the type of destination for an SVGConverter
+ * operation.
+ *
+ * @author Henri Ruini
+ * @author Vincent Hardy
+ * @version $Id: DestinationType.java,v 1.1 2013/04/08 10:55:05 marcin Exp $
+ */
+public final class DestinationType {
+ public static final String PNG_STR = "image/png";
+ public static final String JPEG_STR = "image/jpeg";
+ public static final String TIFF_STR = "image/tiff";
+ public static final String PDF_STR = "application/pdf";
+
+ public static final int PNG_CODE = 0;
+ public static final int JPEG_CODE = 1;
+ public static final int TIFF_CODE = 2;
+ public static final int PDF_CODE = 3;
+
+ public static final String PNG_EXTENSION = ".png";
+ public static final String JPEG_EXTENSION = ".jpg";
+ public static final String TIFF_EXTENSION = ".tif";
+ public static final String PDF_EXTENSION = ".pdf";
+
+ public static final DestinationType PNG
+ = new DestinationType(PNG_STR, PNG_CODE, PNG_EXTENSION);
+ public static final DestinationType JPEG
+ = new DestinationType(JPEG_STR, JPEG_CODE, JPEG_EXTENSION);
+ public static final DestinationType TIFF
+ = new DestinationType(TIFF_STR, TIFF_CODE, TIFF_EXTENSION);
+ public static final DestinationType PDF
+ = new DestinationType(PDF_STR, PDF_CODE, PDF_EXTENSION);
+
+ private String type;
+ private int code;
+ private String extension;
+
+ private DestinationType(String type, int code, String extension){
+ this.type = type;
+ this.code = code;
+ this.extension = extension;
+ }
+
+ public String getExtension(){
+ return extension;
+ }
+
+ public String toString(){
+ return type;
+ }
+
+ public int toInt(){
+ return code;
+ }
+
+ /**
+ * Returns a transcoder object of the result image type.
+ *
+ * @return Transcoder object or null if there isn't a proper transcoder.
+ */
+ protected Transcoder getTranscoder(){
+ switch(code) {
+ case PNG_CODE:
+ return new PNGTranscoder();
+ case JPEG_CODE:
+ return new JPEGTranscoder();
+ case TIFF_CODE:
+ return new TIFFTranscoder();
+ case PDF_CODE:
+ try {
+ Class pdfClass = Class.forName("org.apache.fop.svg.PDFTranscoder");
+ return (Transcoder)pdfClass.newInstance();
+ } catch(Exception e) {
+ return null;
+ }
+ default:
+ return null;
+ }
+
+ }
+
+ /**
+ * Defines valid image types.
+ *
+ * @return Array of valid values as strings.
+ */
+ public DestinationType[] getValues() {
+ return new DestinationType[]{PNG, JPEG, TIFF, PDF};
+ }
+
+ public Object readResolve(){
+ switch(code){
+ case PNG_CODE:
+ return PNG;
+ case JPEG_CODE:
+ return JPEG;
+ case TIFF_CODE:
+ return TIFF;
+ case PDF_CODE:
+ return PDF;
+ default:
+ throw new Error("unknown code:" + code );
+ }
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/Main.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/rasterizer/Main.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/Main.java 8 Apr 2013 10:55:05 -0000 1.1
@@ -0,0 +1,1043 @@
+/*
+
+ 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.batik.apps.rasterizer;
+
+import java.awt.Color;
+import java.awt.geom.Rectangle2D;
+import java.io.File;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.apache.batik.transcoder.Transcoder;
+import org.apache.batik.parser.ClockHandler;
+import org.apache.batik.parser.ClockParser;
+import org.apache.batik.parser.ParseException;
+import org.apache.batik.util.ApplicationSecurityEnforcer;
+
+/**
+ * Handles command line parameters to configure the SVGConverter
+ * and rasterizer images. f
is found to be a file if
+ * it exists and is a file. If it does not exist, it is declared
+ * to be a file if it has the same extension as the DestinationType.
+ */
+ protected boolean isFile(File f){
+ if (f.exists()){
+ return f.isFile();
+ } else {
+ if (f.toString().toLowerCase().endsWith(destinationType.getExtension())){
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Starts the conversion process.
+ * @throws SVGConverterException thrown if parameters are not set correctly.
+ */
+ public void execute() throws SVGConverterException {
+ // Compute the set of SVGConverterSource from the source properties
+ // (srcDir and srcFile);
+ // This throws an exception if there is not at least one src file.
+ List sources = computeSources();
+
+ // Compute the destination files from dest
+ List dstFiles = null;
+ if(sources.size() == 1 && dst != null && isFile(dst)){
+ dstFiles = new ArrayList();
+ dstFiles.add(dst);
+ }
+ else{
+ dstFiles = computeDstFiles(sources);
+ }
+
+ // Now, get the transcoder to use for the operation
+ Transcoder transcoder = destinationType.getTranscoder();
+ if(transcoder == null) {
+ throw new SVGConverterException(ERROR_CANNOT_ACCESS_TRANSCODER,
+ new Object[]{destinationType.toString()},
+ true /* fatal error */);
+ }
+
+ // Now, compute the set of transcoding hints to use
+ Map hints = computeTranscodingHints();
+ transcoder.setTranscodingHints(hints);
+
+ // Notify listener that task has been computed
+ if(!controller.proceedWithComputedTask(transcoder,
+ hints,
+ sources,
+ dstFiles)){
+ return;
+ }
+
+ // Convert files one by one
+ for(int i = 0 ; i < sources.size() ; i++) {
+ // Get the file from the vector.
+ SVGConverterSource currentFile
+ = (SVGConverterSource)sources.get(i);
+ File outputFile = (File)dstFiles.get(i);
+
+ createOutputDir(outputFile);
+ transcode(currentFile, outputFile, transcoder);
+ }
+ }
+
+ /**
+ * Populates a vector with destination files names
+ * computed from the names of the files in the sources vector
+ * and the value of the dst property
+ */
+ protected List computeDstFiles(List sources)
+ throws SVGConverterException {
+ List dstFiles = new ArrayList();
+ if (dst != null) {
+ if (dst.exists() && dst.isFile()) {
+ throw new SVGConverterException(ERROR_CANNOT_USE_DST_FILE);
+ }
+
+ //
+ // Either dst exist and is a directory or dst does not
+ // exist and we may fail later on in createOutputDir
+ //
+ int n = sources.size();
+ for(int i=0; iThis method modifies the result filename, it changes the existing + * suffix to correspong the result file type. It also adds the suffix + * if the file doesn't have one.
+ * + * @param file Result file name as a String object. + * + * @return Name of the file. The directory of the file is not returned. + * The returned string is empty if the parameter is not a file. + */ + protected String getDestinationFile(String file) { + int suffixStart; // Location of the first char of + // the suffix in a String. + String oldName; // Existing filename. + String newSuffix = destinationType.getExtension(); + // New suffix. + + oldName = file; + // Find the first char of the suffix. + suffixStart = oldName.lastIndexOf( '.' ); + String dest = null; + if (suffixStart != -1) { + // Replace existing suffix. + dest = oldName.substring(0, suffixStart) + newSuffix; + } else { + // Add new suffix. + dest = oldName + newSuffix; + } + + return dest; + } + + /** + * Creates directories for output files if needed. + * + * @param output Output file with path. + * + * @throws SVGConverterException Output directory doesn't exist and it can't be created. + */ + protected void createOutputDir(File output) + throws SVGConverterException { + + File outputDir; // Output directory object. + boolean success = true; // false if the output directory + // doesn't exist and it can't be created + // true otherwise + + + // Create object from output directory. + String parentDir = output.getParent(); + if (parentDir != null){ + outputDir = new File(output.getParent()); + if ( ! outputDir.exists() ) { + // Output directory doesn't exist, so create it. + success = outputDir.mkdirs(); + } else { + if ( ! outputDir.isDirectory() ) { + // File, which have a same name as the output directory, exists. + // Create output directory. + success = outputDir.mkdirs(); + } + } + } + + if (!success) { + throw new SVGConverterException(ERROR_UNABLE_TO_CREATE_OUTPUT_DIR); + } + } + + /** + * Checks if the application is allowed to write to the file. + * + * @param file File to be checked. + * + * @return true if the file is writeable and false otherwise. + */ + protected boolean isWriteable(File file) { + if (file.exists()) { + // Check the existing file. + if (!file.canWrite()) { + return false; + } + } else { + // Check the file that doesn't exist yet. + // Create a new file. The file is writeable if + // the creation succeeds. + try { + file.createNewFile(); + } catch(IOException ioe) { + return false; + } + } + return true; + } + + // ----------------------------------------------------------------------- + // Inner classes + // ----------------------------------------------------------------------- + + /** + * Convenience class to filter svg files + */ + public static class SVGFileFilter implements FileFilter { + public static final String SVG_EXTENSION = ".svg"; + + public boolean accept(File file){ + if (file != null && file.getName().toLowerCase().endsWith(SVG_EXTENSION)){ + return true; + } + + return false; + } + } + +} + Index: 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/SVGConverterController.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/rasterizer/SVGConverterController.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/SVGConverterController.java 8 Apr 2013 10:55:06 -0000 1.1 @@ -0,0 +1,81 @@ +/* + + 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.batik.apps.rasterizer; + +import java.io.File; +import java.util.Map; +import java.util.List; + +import org.apache.batik.transcoder.Transcoder; + +/** + * Interface for controlling some aspectes of the + * SVGConverter operation. + * + * @author Vincent Hardy + * @version $Id: SVGConverterController.java,v 1.1 2013/04/08 10:55:06 marcin Exp $ + */ +public interface SVGConverterController { + /** + * Invoked when the rasterizer has computed the + * exact description of what it should do. The controller + * should return true if the transcoding process should + * proceed or false otherwise. + * + * @param transcoder Transcoder which will be used + * @param hints set of hints that were set on the transcoder + * @param sources list of SVG sources it will convert. + * @param dest list of destination file it will use + */ + boolean proceedWithComputedTask(Transcoder transcoder, + Map hints, + List sources, + List dest); + + /** + * Invoked when the rasterizer is about to start transcoding + * of a given source. + * The controller should return true if the source should be + * transcoded and false otherwise. + */ + boolean proceedWithSourceTranscoding(SVGConverterSource source, + File dest); + + /** + * Invoked when the rasterizer got an error while + * transcoding the input source. + * The controller should return true if the transcoding process + * should continue on other sources and it should return false + * if it should not. + * + * @param errorCode see the {@link SVGConverter} error code descriptions. + */ + boolean proceedOnSourceTranscodingFailure(SVGConverterSource source, + File dest, + String errorCode); + + /** + * Invoked when the rasterizer successfully transcoded + * the input source. + */ + void onSourceTranscodingSuccess(SVGConverterSource source, + File dest); + +} + Index: 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/SVGConverterException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/rasterizer/SVGConverterException.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/SVGConverterException.java 8 Apr 2013 10:55:05 -0000 1.1 @@ -0,0 +1,76 @@ +/* + + 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.batik.apps.rasterizer; + +/** + * Describes an error condition in SVGConverter + * + * @author Vincent Hardy + * @version $Id: SVGConverterException.java,v 1.1 2013/04/08 10:55:05 marcin Exp $ + */ +public class SVGConverterException extends Exception { + /** + * Error code + */ + protected String errorCode; + + /** + * Additional information about the error condition + */ + protected Object[] errorInfo; + + /** + * Defines whether or not this is a fatal error condition + */ + protected boolean isFatal; + + public SVGConverterException(String errorCode){ + this(errorCode, null, false); + } + + public SVGConverterException(String errorCode, + Object[] errorInfo){ + this(errorCode, errorInfo, false); + } + + public SVGConverterException(String errorCode, + Object[] errorInfo, + boolean isFatal){ + this.errorCode = errorCode; + this.errorInfo = errorInfo; + this.isFatal = isFatal; + } + + public SVGConverterException(String errorCode, + boolean isFatal){ + this(errorCode, null, isFatal); + } + + public boolean isFatal(){ + return isFatal; + } + + public String getMessage(){ + return Messages.formatMessage(errorCode, errorInfo); + } + + public String getErrorCode(){ + return errorCode; + } +} Index: 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/SVGConverterFileSource.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/rasterizer/SVGConverterFileSource.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/SVGConverterFileSource.java 8 Apr 2013 10:55:05 -0000 1.1 @@ -0,0 +1,102 @@ +/* + + 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.batik.apps.rasterizer; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.net.MalformedURLException; + +/** + * Describes a file source for the SVGConverter + * + * @author Vincent Hardy + * @version $Id: SVGConverterFileSource.java,v 1.1 2013/04/08 10:55:05 marcin Exp $ + */ +public class SVGConverterFileSource implements SVGConverterSource { + File file; + String ref; + + public SVGConverterFileSource(File file){ + this.file = file; + } + + public SVGConverterFileSource(File file, String ref){ + this.file = file; + this.ref = ref; + } + + public String getName(){ + String name = file.getName(); + if (ref != null && !"".equals(ref)){ + name += '#' + ref; + } + return name; + } + + public File getFile(){ + return file; + } + + public String toString(){ + return getName(); + } + + public String getURI(){ + try{ + String uri = file.toURL().toString(); + if (ref != null && !"".equals(ref)){ + uri += '#' + ref; + } + return uri; + } catch(MalformedURLException e){ + throw new Error( e.getMessage() ); + } + } + + public boolean equals(Object o){ + if (o == null || !(o instanceof SVGConverterFileSource)){ + return false; + } + + return file.equals(((SVGConverterFileSource)o).file); + } + + public int hashCode() { + return file.hashCode(); + } + + public InputStream openStream() throws FileNotFoundException{ + return new FileInputStream(file); + } + + public boolean isSameAs(String srcStr){ + if (file.toString().equals(srcStr)){ + return true; + } + + return false; + } + + public boolean isReadable(){ + return file.canRead(); + } +} + Index: 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/SVGConverterSource.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/rasterizer/SVGConverterSource.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/SVGConverterSource.java 8 Apr 2013 10:55:05 -0000 1.1 @@ -0,0 +1,58 @@ +/* + + 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.batik.apps.rasterizer; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Interface used to handle both Files and URLs in the + * SVGConverter + * + * @author Vincent Hardy + * @version $Id: SVGConverterSource.java,v 1.1 2013/04/08 10:55:05 marcin Exp $ + */ +public interface SVGConverterSource { + /** + * Returns the name of the source. That would be the + * name for a File or URL + */ + String getName(); + + /** + * Gets a TranscoderInput for that source + */ + InputStream openStream() throws IOException; + + /** + * Checks if same as source described by srcStr + */ + boolean isSameAs(String srcStr); + + /** + * Checks if source can be read + */ + boolean isReadable(); + + /** + * Returns a URI string corresponding to this source + */ + String getURI(); +} + Index: 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/SVGConverterURLSource.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/rasterizer/SVGConverterURLSource.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/batik/org/apache/batik/apps/rasterizer/SVGConverterURLSource.java 8 Apr 2013 10:55:05 -0000 1.1 @@ -0,0 +1,129 @@ +/* + + 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.batik.apps.rasterizer; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.batik.util.ParsedURL; + +/* + * @author Vincent Hardy + * @version $Id: SVGConverterURLSource.java,v 1.1 2013/04/08 10:55:05 marcin Exp $ + */ +public class SVGConverterURLSource implements SVGConverterSource { + /** + * SVG file extension + */ + protected static final String SVG_EXTENSION = ".svg"; + protected static final String SVGZ_EXTENSION = ".svgz"; + + // + // Reported when the URL for one of the sources is + // invalid. This will happen if the URL is malformed or + // if the URL file does not end with the ".svg" extension. + // This is needed to be able to create a file name for + // the ouptut automatically. + // + public static final String ERROR_INVALID_URL + = "SVGConverterURLSource.error.invalid.url"; + + ParsedURL purl; + String name; + + public SVGConverterURLSource(String url) throws SVGConverterException{ + this.purl = new ParsedURL(url); + + // Get the path portion + String path = this.purl.getPath(); + int n = path.lastIndexOf('/'); + String file = path; + if (n != -1){ + // The following is safe because we know there is at least ".svg" + // after the slash. + file = path.substring(n+1); + } + if (file.length() == 0) { + int idx = path.lastIndexOf('/', n-1); + file = path.substring(idx+1, n); + } + if (file.length() == 0) { + throw new SVGConverterException(ERROR_INVALID_URL, + new Object[]{url}); + } + n = file.indexOf('?'); + String args = ""; + if (n != -1) { + args = file.substring(n+1); + file = file.substring(0, n); + } + + name = file; + + // + // The following will force creation of different output file names + // for urls with references (e.g., anne.svg#svgView(viewBox(0,0,4,5))) + // + String ref = this.purl.getRef(); + if ((ref != null) && (ref.length()!=0)) { + name += "_" + ref.hashCode(); + } + if ((args != null) && (args.length()!=0)) { + name += "_" + args.hashCode(); + } + } + + public String toString(){ + return purl.toString(); + } + + public String getURI(){ + return toString(); + } + + public boolean equals(Object o){ + if (o == null || !(o instanceof SVGConverterURLSource)){ + return false; + } + + return purl.equals(((SVGConverterURLSource)o).purl); + } + + public int hashCode() { + return purl.hashCode(); + } + + + public InputStream openStream() throws IOException { + return purl.openStream(); + } + + public boolean isSameAs(String srcStr){ + return toString().equals(srcStr); + } + + public boolean isReadable(){ + return true; + } + + public String getName(){ + return name; + } +} Index: 3rdParty_sources/batik/org/apache/batik/apps/slideshow/Main.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/slideshow/Main.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/batik/org/apache/batik/apps/slideshow/Main.java 8 Apr 2013 10:55:59 -0000 1.1 @@ -0,0 +1,458 @@ +/* + + 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.batik.apps.slideshow; + +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.List; +import java.util.ArrayList; + +import javax.swing.JComponent; +import javax.swing.JWindow; + +import org.apache.batik.bridge.BridgeContext; +import org.apache.batik.bridge.DocumentLoader; +import org.apache.batik.bridge.GVTBuilder; +import org.apache.batik.bridge.UserAgent; +import org.apache.batik.bridge.UserAgentAdapter; +import org.apache.batik.bridge.ViewBox; +import org.apache.batik.gvt.GraphicsNode; +import org.apache.batik.gvt.renderer.StaticRenderer; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.svg.SVGDocument; + +/** + * + * @version $Id: Main.java,v 1.1 2013/04/08 10:55:59 marcin Exp $ + */ +public class Main extends JComponent { + + StaticRenderer renderer; + UserAgent userAgent; + DocumentLoader loader; + BridgeContext ctx; + + BufferedImage image; + BufferedImage display; + File [] files; + + static int duration = 3000; + static int frameDelay = duration+7000; + + volatile boolean done = false; + + public Main(File []files, Dimension size) { + setBackground(Color.black); + this.files = files; + UserAgentAdapter ua = new UserAgentAdapter(); + renderer = new StaticRenderer(); + userAgent = ua; + loader = new DocumentLoader(userAgent); + ctx = new BridgeContext(userAgent, loader); + ua.setBridgeContext(ctx); + + if (size == null) { + size = Toolkit.getDefaultToolkit().getScreenSize(); + } + + setPreferredSize(size); + setDoubleBuffered(false); + addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent me) { + if (done) + System.exit(0); + else + togglePause(); + } + }); + + size.width += 2; + size.height += 2; + display = new BufferedImage(size.width, size.height, + BufferedImage.TYPE_INT_BGR); + + Thread t = new RenderThread(); + t.start(); + + JWindow w = new JWindow(); + w.setBackground(Color.black); + w.getContentPane().setBackground(Color.black); + w.getContentPane().add(this); + w.pack(); + w.setLocation(new Point(-1, -1)); + w.setVisible(true); + } + + class RenderThread extends Thread { + RenderThread(){ + super("RenderThread"); + setDaemon( true ); + } + + public void run() { + renderer.setDoubleBuffered(true); + for (int i=0; ir
+ */
+ protected Rectangle outset(Rectangle r, int amount) {
+ r.x -= amount;
+ r.y -= amount;
+ r.width += 2 * amount;
+ r.height += 2 * amount;
+ return r;
+ }
+
+ /**
+ * Repaints the canvas.
+ */
+ public void repaint() {
+ canvas.repaint();
+ }
+
+ /**
+ * The element overlay.
+ */
+ public class ElementOverlay implements Overlay {
+
+ /**
+ * Paints this overlay.
+ */
+ public void paint(Graphics g) {
+ if (controller.isOverlayEnabled() && isOverlayEnabled()) {
+ int n = elements.size();
+ for (int i = 0; i < n; i++) {
+ Element currentElement = (Element) elements.get(i);
+ GraphicsNode nodeToPaint = canvas.getUpdateManager()
+ .getBridgeContext().getGraphicsNode(currentElement);
+ if (nodeToPaint != null) {
+ AffineTransform elementsAt =
+ nodeToPaint.getGlobalTransform();
+ Shape selectionHighlight = nodeToPaint.getOutline();
+ AffineTransform at = canvas.getRenderingTransform();
+ at.concatenate(elementsAt);
+ Shape s = at.createTransformedShape(selectionHighlight);
+ if (s == null) {
+ break;
+ }
+ Graphics2D g2d = (Graphics2D) g;
+ if (xorMode) {
+ g2d.setColor(Color.black);
+ g2d.setXORMode(Color.yellow);
+ g2d.fill(s);
+ g2d.draw(s);
+ } else {
+ g2d.setColor(elementOverlayColor);
+ g2d.setStroke(new BasicStroke(1.8f));
+ g2d.setColor(elementOverlayStrokeColor);
+ g2d.draw(s);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets the elementOverlayColor.
+ *
+ * @return the elementOverlayColor
+ */
+ public Color getElementOverlayColor() {
+ return elementOverlayColor;
+ }
+
+ /**
+ * Sets the color to use for the element overlay.
+ *
+ * @param selectionOverlayColor The new element overlay color.
+ */
+ public void setElementOverlayColor(Color selectionOverlayColor) {
+ this.elementOverlayColor = selectionOverlayColor;
+ }
+
+ /**
+ * Gets the elementOverlayStrokeColor.
+ *
+ * @return the elementOverlayStrokeColor
+ */
+ public Color getElementOverlayStrokeColor() {
+ return elementOverlayStrokeColor;
+ }
+
+ /**
+ * Sets the color to use for stroking the element overlay.
+ *
+ * @param selectionOverlayStrokeColor
+ * The new element overlay stroking color.
+ */
+ public void setElementOverlayStrokeColor
+ (Color selectionOverlayStrokeColor) {
+ this.elementOverlayStrokeColor = selectionOverlayStrokeColor;
+ }
+
+ /**
+ * Gets the xorMode.
+ *
+ * @return the xorMode
+ */
+ public boolean isXorMode() {
+ return xorMode;
+ }
+
+ /**
+ * Sets the xor mode.
+ *
+ * @param xorMode
+ * the xorMode to set
+ */
+ public void setXorMode(boolean xorMode) {
+ this.xorMode = xorMode;
+ }
+
+ /**
+ * Gets the elementOverlay.
+ *
+ * @return the elementOverlay
+ */
+ public Overlay getElementOverlay() {
+ return elementOverlay;
+ }
+
+ /**
+ * Removes the elementOverlay.
+ */
+ public void removeOverlay() {
+ canvas.getOverlays().remove(elementOverlay);
+ }
+
+ /**
+ * Sets the element overlay controller.
+ *
+ * @param controller
+ * The element overlay controller
+ */
+ public void setController(ElementOverlayController controller) {
+ this.controller = controller;
+ }
+
+ /**
+ * If the element overlay is enabled.
+ *
+ * @return isOverlayEnabled
+ */
+ public boolean isOverlayEnabled() {
+ return isOverlayEnabled;
+ }
+
+ /**
+ * Enables / disables the Element overlay.
+ */
+ public void setOverlayEnabled(boolean isOverlayEnabled) {
+ this.isOverlayEnabled = isOverlayEnabled;
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/FindDialog.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/FindDialog.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/FindDialog.java 8 Apr 2013 10:55:09 -0000 1.1
@@ -0,0 +1,452 @@
+/*
+
+ 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.batik.apps.svgbrowser;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.Shape;
+import java.awt.event.ActionEvent;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.text.AttributedCharacterIterator;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.BorderFactory;
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JTextField;
+
+import org.apache.batik.gvt.GVTTreeWalker;
+import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.gvt.TextNode;
+import org.apache.batik.gvt.text.Mark;
+import org.apache.batik.swing.JSVGCanvas;
+import org.apache.batik.util.resources.ResourceManager;
+import org.apache.batik.util.gui.ExtendedGridBagConstraints;
+import org.apache.batik.util.gui.resource.ActionMap;
+import org.apache.batik.util.gui.resource.ButtonFactory;
+import org.apache.batik.util.gui.resource.MissingListenerException;
+
+/**
+ * This class represents a Dialog that lets the user searching for text inside
+ * an SVG document.
+ *
+ * @author Thierry Kormann
+ * @version $Id: FindDialog.java,v 1.1 2013/04/08 10:55:09 marcin Exp $
+ */
+public class FindDialog extends JDialog implements ActionMap {
+
+ /**
+ * The resource file name
+ */
+ protected static final String RESOURCES =
+ "org.apache.batik.apps.svgbrowser.resources.FindDialog";
+
+ // action names
+ public static final String FIND_ACTION = "FindButtonAction";
+
+ public static final String CLEAR_ACTION = "ClearButtonAction";
+
+ public static final String CLOSE_ACTION = "CloseButtonAction";
+
+ /**
+ * The resource bundle
+ */
+ protected static ResourceBundle bundle;
+
+ /**
+ * The resource manager
+ */
+ protected static ResourceManager resources;
+
+ static {
+ bundle = ResourceBundle.getBundle(RESOURCES, Locale.getDefault());
+ resources = new ResourceManager(bundle);
+ }
+
+ /** The button factory */
+ protected ButtonFactory buttonFactory;
+
+ /** The GVT root into which text is searched. */
+ protected GraphicsNode gvtRoot;
+
+ /** The GVTTreeWalker used to scan the GVT Tree. */
+ protected GVTTreeWalker walker;
+
+ /** The current index in the TextNode's string. */
+ protected int currentIndex;
+
+ /** The TextField that owns the text to search. */
+ protected JTextField search;
+
+ /** The next button. */
+ protected JButton findButton;
+
+ /** The next button. */
+ protected JButton clearButton;
+
+ /** The cancel button. */
+ protected JButton closeButton;
+
+ /** The case sensitive button. */
+ protected JCheckBox caseSensitive;
+
+ /** The canvas. */
+ protected JSVGCanvas svgCanvas;
+
+ /** The highlight button. */
+ protected JRadioButton highlightButton;
+
+ /** The highlight and center button. */
+ protected JRadioButton highlightCenterButton;
+
+ /** The highlight center and zoom button. */
+ protected JRadioButton highlightCenterZoomButton;
+ /**
+ * Constructs a new FindDialog.
+ */
+ public FindDialog(JSVGCanvas svgCanvas) {
+ this(null, svgCanvas);
+ }
+
+ /**
+ * Constructs a new FindDialog.
+ */
+ public FindDialog(Frame owner, JSVGCanvas svgCanvas) {
+ super(owner, resources.getString("Dialog.title"));
+ this.svgCanvas = svgCanvas;
+
+ buttonFactory = new ButtonFactory(bundle, this);
+
+ listeners.put(FIND_ACTION,
+ new FindButtonAction());
+
+ listeners.put(CLEAR_ACTION,
+ new ClearButtonAction());
+
+ listeners.put(CLOSE_ACTION,
+ new CloseButtonAction());
+
+ JPanel p = new JPanel(new BorderLayout());
+ p.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
+ p.add(createFindPanel(), BorderLayout.CENTER);
+ p.add(createShowResultPanel(), BorderLayout.SOUTH);
+
+ getContentPane().add(p, BorderLayout.CENTER);
+ getContentPane().add(createButtonsPanel(), BorderLayout.SOUTH);
+ }
+
+ /**
+ * Creates the Find panel.
+ */
+ protected JPanel createFindPanel() {
+ JPanel panel = new JPanel(new GridBagLayout());
+
+ panel.setBorder(BorderFactory.createTitledBorder
+ (BorderFactory.createEtchedBorder(),
+ resources.getString("Panel.title")));
+
+ ExtendedGridBagConstraints gbc = new ExtendedGridBagConstraints();
+ gbc.insets = new Insets(2, 2, 2, 2);
+
+ gbc.anchor = ExtendedGridBagConstraints.EAST;
+ gbc.fill = ExtendedGridBagConstraints.NONE;
+ gbc.setWeight(0, 0);
+ gbc.setGridBounds(0, 0, 1, 1);
+ panel.add(new JLabel(resources.getString("FindLabel.text")), gbc);
+
+ gbc.fill = ExtendedGridBagConstraints.HORIZONTAL;
+ gbc.setWeight(1.0, 0);
+ gbc.setGridBounds(1, 0, 2, 1);
+ panel.add(search = new JTextField(20), gbc);
+
+ gbc.fill = ExtendedGridBagConstraints.NONE;
+ gbc.anchor = ExtendedGridBagConstraints.WEST;
+ gbc.setWeight(0, 0);
+ gbc.setGridBounds(1, 1, 1, 1);
+ caseSensitive = buttonFactory.createJCheckBox("CaseSensitiveCheckBox");
+ panel.add(caseSensitive, gbc);
+
+ return panel;
+ }
+
+ protected JPanel createShowResultPanel() {
+ JPanel panel = new JPanel(new GridBagLayout());
+
+ panel.setBorder(BorderFactory.createTitledBorder
+ (BorderFactory.createEtchedBorder(),
+ resources.getString("ShowResultPanel.title")));
+
+ ExtendedGridBagConstraints gbc = new ExtendedGridBagConstraints();
+ gbc.insets = new Insets(2, 2, 2, 2);
+
+ gbc.anchor = ExtendedGridBagConstraints.WEST;
+ gbc.fill = ExtendedGridBagConstraints.NONE;
+ gbc.setWeight(0, 0);
+
+ ButtonGroup grp = new ButtonGroup();
+
+ highlightButton = buttonFactory.createJRadioButton("Highlight");
+ highlightButton.setSelected(true);
+ grp.add(highlightButton);
+ gbc.setGridBounds(0, 0, 1, 1);
+ panel.add(highlightButton, gbc);
+
+ highlightCenterButton =
+ buttonFactory.createJRadioButton("HighlightAndCenter");
+ grp.add(highlightCenterButton);
+ gbc.setGridBounds(0, 1, 1, 1);
+ panel.add(highlightCenterButton, gbc);
+
+ highlightCenterZoomButton =
+ buttonFactory.createJRadioButton("HighlightCenterAndZoom");
+ grp.add(highlightCenterZoomButton);
+ gbc.setGridBounds(0, 2, 1, 1);
+ panel.add(highlightCenterZoomButton, gbc);
+
+ return panel;
+ }
+
+ /**
+ * Creates the buttons panel
+ */
+ protected JPanel createButtonsPanel() {
+ JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+ panel.add(findButton = buttonFactory.createJButton("FindButton"));
+ panel.add(clearButton = buttonFactory.createJButton("ClearButton"));
+ panel.add(closeButton = buttonFactory.createJButton("CloseButton"));
+ return panel;
+ }
+
+
+ /**
+ * Sets the graphics node into which text is searched.
+ * @param gvtRoot the GVT root node
+ */
+ public void setGraphicsNode(GraphicsNode gvtRoot) {
+ this.gvtRoot = gvtRoot;
+ if (gvtRoot != null) {
+ this.walker = new GVTTreeWalker(gvtRoot);
+ } else {
+ this.walker = null;
+ }
+ }
+
+ /**
+ * Returns the next GraphicsNode that matches the specified string or null
+ * if any.
+ *
+ * @param text the text to match
+ */
+ protected GraphicsNode getNext(String text) {
+ if (walker == null && gvtRoot != null) {
+ walker = new GVTTreeWalker(gvtRoot);
+ }
+ GraphicsNode gn = walker.getCurrentGraphicsNode();
+ int index = match(gn, text, currentIndex+text.length());
+ if (index >= 0) {
+ currentIndex = index;
+ } else {
+ currentIndex = 0;
+ gn = walker.nextGraphicsNode();
+ while (gn != null &&
+ ((currentIndex = match(gn, text, currentIndex)) < 0)) {
+ currentIndex = 0;
+ gn = walker.nextGraphicsNode();
+ }
+ }
+ return gn;
+ }
+
+ /**
+ * Returns the index inside the specified TextNode of the
+ * specified text, or -1 if not found.
+ *
+ * @param node the graphics node to check
+ * @param text the text use to match
+ * @param index the index from which to start */
+ protected int match(GraphicsNode node, String text, int index) {
+ if (!(node instanceof TextNode)
+ || !node.isVisible()
+ || text == null || text.length() == 0) {
+ return -1;
+ }
+ String s = ((TextNode)node).getText();
+ if (!caseSensitive.isSelected()) {
+ s = s.toLowerCase();
+ text = text.toLowerCase();
+ }
+ return s.indexOf(text, index);
+ }
+
+ /**
+ * Shows the current selected TextNode.
+ */
+ protected void showSelectedGraphicsNode() {
+ GraphicsNode gn = walker.getCurrentGraphicsNode();
+ if (!(gn instanceof TextNode)) {
+ return;
+ }
+ TextNode textNode = (TextNode)gn;
+ // mark the selection of the substring found
+ String text = textNode.getText();
+ String pattern = search.getText();
+ if (!caseSensitive.isSelected()) {
+ text = text.toLowerCase();
+ pattern = pattern.toLowerCase();
+ }
+ int end = text.indexOf(pattern, currentIndex);
+
+ AttributedCharacterIterator aci =
+ textNode.getAttributedCharacterIterator();
+ aci.first();
+ for (int i=0; i < end; ++i) {
+ aci.next();
+ }
+ Mark startMark = textNode.getMarkerForChar(aci.getIndex(), true);
+
+ for (int i = 0; i < pattern.length()-1; ++i) {
+ aci.next();
+ }
+ Mark endMark = textNode.getMarkerForChar(aci.getIndex(), false);
+ svgCanvas.select(startMark, endMark);
+
+ // zoom on the TextNode if needed
+ if (highlightButton.isSelected()) {
+ return;
+ }
+
+ // get the highlight shape in GVT root (global) coordinate sytem
+ Shape s = textNode.getHighlightShape();
+ AffineTransform at;
+ if (highlightCenterZoomButton.isSelected()) {
+ at = svgCanvas.getInitialTransform();
+ } else {
+ at = svgCanvas.getRenderingTransform();
+ }
+ // get the bounds of the highlight shape in the canvas coordinate system
+ Rectangle2D gnb = at.createTransformedShape(s).getBounds();
+
+ Dimension canvasSize = svgCanvas.getSize();
+ // translate the highlight region to (0, 0) in the canvas coordinate
+ // system
+ AffineTransform Tx = AffineTransform.getTranslateInstance
+ (-gnb.getX()-gnb.getWidth()/2,
+ -gnb.getY()-gnb.getHeight()/2);
+
+ if (highlightCenterZoomButton.isSelected()) {
+ // zoom on the highlight shape such as the shape takes x% of the
+ // canvas size
+ double sx = canvasSize.width/gnb.getWidth();
+ double sy = canvasSize.height/gnb.getHeight();
+ double scale = Math.min(sx, sy) / 8;
+ if (scale > 1) {
+ Tx.preConcatenate
+ (AffineTransform.getScaleInstance(scale, scale));
+ }
+ }
+ Tx.preConcatenate(AffineTransform.getTranslateInstance
+ (canvasSize.width/2, canvasSize.height/2));
+ // take into account the initial transform
+ AffineTransform newRT = new AffineTransform(at);
+ newRT.preConcatenate(Tx);
+ // change the rendering transform
+ svgCanvas.setRenderingTransform(newRT);
+ }
+
+ // ActionMap implementation
+
+ /**
+ * The map that contains the listeners
+ */
+ protected Map listeners = new HashMap(10);
+
+ /**
+ * Returns the action associated with the given string
+ * or null on error
+ * @param key the key mapped with the action to get
+ * @throws MissingListenerException if the action is not found
+ */
+ public Action getAction(String key) throws MissingListenerException {
+ return (Action)listeners.get(key);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Action implementation
+ //////////////////////////////////////////////////////////////////////////
+
+ /**
+ * The action associated to the 'find' button.
+ */
+ protected class FindButtonAction extends AbstractAction {
+ public void actionPerformed(ActionEvent e) {
+ String text = search.getText();
+ if (text == null || text.length() == 0) {
+ return;
+ }
+ GraphicsNode gn = getNext(text);
+ if (gn != null) {
+ showSelectedGraphicsNode();
+ } else {
+ // end of document reached
+ walker = null;
+ JOptionPane.showMessageDialog(FindDialog.this,
+ resources.getString("End.text"),
+ resources.getString("End.title"),
+ JOptionPane.INFORMATION_MESSAGE);
+ }
+ }
+ }
+
+ /**
+ * The action associated to the 'clear' button.
+ */
+ protected class ClearButtonAction extends AbstractAction {
+ public void actionPerformed(ActionEvent e) {
+ search.setText(null);
+ walker = null;
+ }
+ }
+
+ /**
+ * The action associated to the 'close' button.
+ */
+ protected class CloseButtonAction extends AbstractAction {
+ public void actionPerformed(ActionEvent e) {
+ dispose();
+ }
+ }
+}
+
+
Index: 3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/HistoryBrowser.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/HistoryBrowser.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/HistoryBrowser.java 8 Apr 2013 10:55:08 -0000 1.1
@@ -0,0 +1,624 @@
+/*
+
+ 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.batik.apps.svgbrowser;
+
+import java.util.ArrayList;
+import java.util.EventListener;
+import java.util.EventObject;
+
+import javax.swing.event.EventListenerList;
+
+/**
+ * History browser. Manages perform of execute, undo and redo actions.
+ */
+public class HistoryBrowser {
+
+ // The history browser states. Show whether the history browser is busy
+ // performing execute, undo or redo, or whether is idle.
+ /**
+ * The history browser is executing the command(s).
+ */
+ public static final int EXECUTING = 1;
+
+ /**
+ * The history browser is undoing the command(s).
+ */
+ public static final int UNDOING = 2;
+
+ /**
+ * The history browser is redoing the command(s).
+ */
+ public static final int REDOING = 3;
+
+ /**
+ * The history browser is in idle state - no command is being executed,
+ * undone or redone.
+ */
+ public static final int IDLE = 4;
+
+ /**
+ * Listeners list.
+ */
+ protected EventListenerList eventListeners =
+ new EventListenerList();
+
+ /**
+ * Command history.
+ */
+ protected ArrayList history;
+
+ /**
+ * Current command pointer in history array.
+ */
+ protected int currentCommandIndex = -1;
+
+ /**
+ * History size.
+ */
+ protected int historySize = 1000;
+
+ /**
+ * The current state of the history browser.
+ */
+ protected int state = IDLE;
+
+ /**
+ * Tells the history browser how to execute, undo and redo the commands.
+ * Wraps the execute, undo and redo methods
+ */
+ protected CommandController commandController;
+
+ /**
+ * Constructor.
+ */
+ public HistoryBrowser(CommandController commandController) {
+ this.history = new ArrayList();
+ this.commandController = commandController;
+ }
+
+ /**
+ * Constructor.
+ * @param historySize History size
+ */
+ public HistoryBrowser(int historySize) {
+ this.history = new ArrayList();
+ setHistorySize(historySize);
+ }
+
+ /**
+ * Setter for the history size.
+ *
+ * @param size
+ * New history size
+ */
+ protected void setHistorySize(int size) {
+ historySize = size;
+ }
+
+ /**
+ * Sets the commandController.
+ *
+ * @param newCommandController
+ * The newCommandController to set
+ */
+ public void setCommandController(CommandController newCommandController) {
+ this.commandController = newCommandController;
+ }
+
+ /**
+ * Adds the given command to history array and executes it.
+ *
+ * @param command
+ * The given command
+ */
+ public void addCommand(UndoableCommand command) {
+ // When the command is added to history array, the commands from the
+ // current position to the end of the list are removed from history
+ int n = history.size();
+ for (int i = n - 1; i > currentCommandIndex; i--) {
+ history.remove(i);
+ }
+ // Executes the command
+ if (commandController != null) {
+ commandController.execute(command);
+ } else {
+ state = EXECUTING;
+ command.execute();
+ state = IDLE;
+ }
+ // Adds it to the history array
+ history.add(command);
+
+ // Updates the pointer to the current command
+ currentCommandIndex = history.size() - 1;
+ if (currentCommandIndex >= historySize) {
+ history.remove(0);
+ currentCommandIndex--;
+ }
+ fireExecutePerformed(new HistoryBrowserEvent(new CommandNamesInfo(
+ command.getName(), getLastUndoableCommandName(),
+ getLastRedoableCommandName())));
+ }
+
+ /**
+ * Undoes the last executed or 'redone' command.
+ */
+ public void undo() {
+ // If history is empty, or the current command index is out of bounds
+ if (history.isEmpty() || currentCommandIndex < 0) {
+ return;
+ }
+ // Gets the command and performs undo
+ UndoableCommand command = (UndoableCommand) history
+ .get(currentCommandIndex);
+ if (commandController != null) {
+ commandController.undo(command);
+ } else {
+ state = UNDOING;
+ command.undo();
+ state = IDLE;
+ }
+ // Updates the current command index
+ currentCommandIndex--;
+ fireUndoPerformed(new HistoryBrowserEvent(new CommandNamesInfo(command
+ .getName(), getLastUndoableCommandName(),
+ getLastRedoableCommandName())));
+ }
+
+ /**
+ * Redoes the last 'undone' command.
+ */
+ public void redo() {
+ // If history is empty, or the current command index is out of bounds
+ if (history.isEmpty() || currentCommandIndex == history.size() - 1) {
+ return;
+ }
+ // Increases the current command index and redoes the command
+ UndoableCommand command = (UndoableCommand) history
+ .get(++currentCommandIndex);
+ if (commandController != null) {
+ commandController.redo(command);
+ } else {
+ state = REDOING;
+ command.redo();
+ state = IDLE;
+ }
+ fireRedoPerformed(new HistoryBrowserEvent(new CommandNamesInfo(command
+ .getName(), getLastUndoableCommandName(),
+ getLastRedoableCommandName())));
+ }
+
+ /**
+ * Performs undo action the given number of times.
+ *
+ * @param undoNumber
+ * The given number of undo actions to perform
+ */
+ public void compoundUndo(int undoNumber) {
+ for (int i = 0; i < undoNumber; i++) {
+ undo();
+ }
+ }
+
+ /**
+ * Performs redo action the given number of times.
+ *
+ * @param redoNumber
+ * The given number of redo actions to perform
+ */
+ public void compoundRedo(int redoNumber) {
+ for (int i = 0; i < redoNumber; i++) {
+ redo();
+ }
+ }
+
+ /**
+ * Gets the last undoable command name.
+ *
+ * @return String or "" if there's no any
+ */
+ public String getLastUndoableCommandName() {
+ if (history.isEmpty() || currentCommandIndex < 0) {
+ return "";
+ }
+ return ((UndoableCommand) history.get(currentCommandIndex)).getName();
+ }
+
+ /**
+ * Gets the last redoable command name.
+ *
+ * @return String or "" if there's no any
+ */
+ public String getLastRedoableCommandName() {
+ if (history.isEmpty() || currentCommandIndex == history.size() - 1) {
+ return "";
+ }
+ return ((UndoableCommand) history.get(currentCommandIndex + 1))
+ .getName();
+ }
+
+ /**
+ * Clears the history array.
+ */
+ public void resetHistory() {
+ history.clear();
+ currentCommandIndex = -1;
+ fireHistoryReset(new HistoryBrowserEvent(new Object()));
+ }
+
+ /**
+ * Gets the state of this history browser.
+ *
+ * @return the state
+ */
+ public int getState() {
+ if (commandController != null) {
+ return commandController.getState();
+ } else {
+ return state;
+ }
+ }
+
+ // Custom event support
+
+ /**
+ * Event to pass to listener.
+ */
+ public static class HistoryBrowserEvent extends EventObject {
+
+ /**
+ * @param source
+ */
+ public HistoryBrowserEvent(Object source) {
+ super(source);
+ }
+ }
+
+ /**
+ * The HistoryBrowserListener.
+ */
+ public static interface HistoryBrowserListener extends EventListener {
+
+ /**
+ * The command has been executed.
+ */
+ void executePerformed(HistoryBrowserEvent event);
+
+ /**
+ * The undo has been performed on the command.
+ */
+ void undoPerformed(HistoryBrowserEvent event);
+
+ /**
+ * The redo has been performed on the command.
+ */
+ void redoPerformed(HistoryBrowserEvent event);
+
+ /**
+ * History has been reset, and all commands have been removed from the
+ * history.
+ */
+ void historyReset(HistoryBrowserEvent event);
+
+ /**
+ * The the atom command that should be wrapped with the compound command
+ * has been executed.
+ */
+ void doCompoundEdit(HistoryBrowserEvent event);
+
+ /**
+ * The compound command has been made from the atom commands that were
+ * executed and should be wrapped.
+ */
+ void compoundEditPerformed(HistoryBrowserEvent event);
+ }
+
+ /**
+ * The adapter to provide the default behavior.
+ */
+ public static class HistoryBrowserAdapter implements HistoryBrowserListener {
+
+ public void executePerformed(HistoryBrowserEvent event) {
+ }
+
+ public void undoPerformed(HistoryBrowserEvent event) {
+ }
+
+ public void redoPerformed(HistoryBrowserEvent event) {
+ }
+
+ public void historyReset(HistoryBrowserEvent event) {
+ }
+
+ public void compoundEditPerformed(HistoryBrowserEvent event) {
+ }
+
+ public void doCompoundEdit(HistoryBrowserEvent event) {
+ }
+ }
+
+ /**
+ * Adds the listener to the listener list.
+ *
+ * @param listener
+ * The listener to add
+ */
+ public void addListener(HistoryBrowserListener listener) {
+ eventListeners.add(HistoryBrowserListener.class, listener);
+ }
+
+ /**
+ * Fires the executePerformed event.
+ *
+ * @param event
+ * The associated HistoryBrowserEvent event
+ */
+ public void fireExecutePerformed(HistoryBrowserEvent event) {
+ Object[] listeners = eventListeners.getListenerList();
+ int length = listeners.length;
+ for (int i = 0; i < length; i += 2) {
+ if (listeners[i] == HistoryBrowserListener.class) {
+ ((HistoryBrowserListener) listeners[i + 1])
+ .executePerformed(event);
+ }
+ }
+ }
+
+ /**
+ * Fires the undoPerformed event.
+ *
+ * @param event
+ * The associated HistoryBrowserEvent event
+ */
+ public void fireUndoPerformed(HistoryBrowserEvent event) {
+ Object[] listeners = eventListeners.getListenerList();
+ int length = listeners.length;
+ for (int i = 0; i < length; i += 2) {
+ if (listeners[i] == HistoryBrowserListener.class) {
+ ((HistoryBrowserListener) listeners[i + 1])
+ .undoPerformed(event);
+ }
+ }
+ }
+
+ /**
+ * Fires the redoPerformed event.
+ *
+ * @param event
+ * The associated HistoryBrowserEvent event
+ */
+ public void fireRedoPerformed(HistoryBrowserEvent event) {
+ Object[] listeners = eventListeners.getListenerList();
+ int length = listeners.length;
+ for (int i = 0; i < length; i += 2) {
+ if (listeners[i] == HistoryBrowserListener.class) {
+ ((HistoryBrowserListener) listeners[i + 1])
+ .redoPerformed(event);
+ }
+ }
+ }
+
+ /**
+ * Fires the historyReset event.
+ *
+ * @param event
+ * The associated HistoryBrowserEvent event
+ */
+ public void fireHistoryReset(HistoryBrowserEvent event) {
+ Object[] listeners = eventListeners.getListenerList();
+ int length = listeners.length;
+ for (int i = 0; i < length; i += 2) {
+ if (listeners[i] == HistoryBrowserListener.class) {
+ ((HistoryBrowserListener) listeners[i + 1])
+ .historyReset(event);
+ }
+ }
+ }
+
+ /**
+ * Fires the doCompoundEdit event.
+ *
+ * @param event
+ * The associated HistoryBrowserEvent event
+ */
+ public void fireDoCompoundEdit(HistoryBrowserEvent event) {
+ Object[] listeners = eventListeners.getListenerList();
+ int length = listeners.length;
+ for (int i = 0; i < length; i += 2) {
+ if (listeners[i] == HistoryBrowserListener.class) {
+ ((HistoryBrowserListener) listeners[i + 1])
+ .doCompoundEdit(event);
+ }
+ }
+ }
+
+ /**
+ * Fires the compoundEditPerformed event.
+ *
+ * @param event
+ * The associated HistoryBrowserEvent event
+ */
+ public void fireCompoundEditPerformed(HistoryBrowserEvent event) {
+ Object[] listeners = eventListeners.getListenerList();
+ int length = listeners.length;
+ for (int i = 0; i < length; i += 2) {
+ if (listeners[i] == HistoryBrowserListener.class) {
+ ((HistoryBrowserListener) listeners[i + 1])
+ .compoundEditPerformed(event);
+ }
+ }
+ }
+
+ /**
+ * Contains the info on the command name being executed, undone or redone and
+ * last undoable and redoable command names.
+ */
+ public static class CommandNamesInfo {
+
+ /**
+ * The name of the last undoable command in the history.
+ */
+ private String lastUndoableCommandName;
+
+ /**
+ * The name of the last redoable command in the history.
+ */
+ private String lastRedoableCommandName;
+
+ /**
+ * The command name being executed, undone or redone.
+ */
+ private String commandName;
+
+ /**
+ * Constructor.
+ *
+ * @param commandName
+ * The current command name being executed/undone/redone
+ * @param lastUndoableCommandName
+ * The last undoable command name
+ * @param lastRedoableCommandName
+ * The last redoable command name
+ */
+ public CommandNamesInfo(String commandName,
+ String lastUndoableCommandName,
+ String lastRedoableCommandName) {
+ this.lastUndoableCommandName = lastUndoableCommandName;
+ this.lastRedoableCommandName = lastRedoableCommandName;
+ this.commandName = commandName;
+ }
+
+ /**
+ * Gets the name of the last undoable command.
+ *
+ * @return the lastUndoableCommandName
+ */
+ public String getLastRedoableCommandName() {
+ return lastRedoableCommandName;
+ }
+
+ /**
+ * Gets the name of the last redoable command.
+ *
+ * @return the lastRedoableCommandName
+ */
+ public String getLastUndoableCommandName() {
+ return lastUndoableCommandName;
+ }
+
+ /**
+ * Gets the command name.
+ *
+ * @return the command name
+ */
+ public String getCommandName() {
+ return commandName;
+ }
+ }
+
+ /**
+ * Wrapps the command's execute, undo and redo methods.
+ */
+ public static interface CommandController {
+
+ /**
+ * Wrapps the execute method.
+ */
+ void execute(UndoableCommand command);
+
+ /**
+ * Wrapps the undo method.
+ */
+ void undo(UndoableCommand command);
+
+ /**
+ * Wrapps the redo method.
+ */
+ void redo(UndoableCommand command);
+
+ /**
+ * Gets the state of the command controller.
+ * @return HistoryBrowserState
+ */
+ int getState();
+ }
+
+ /**
+ * Lets the DOMViewerController wrap the commands.
+ */
+ public static class DocumentCommandController implements CommandController {
+
+ /**
+ * The DOMViewerController.
+ */
+ protected DOMViewerController controller;
+
+ /**
+ * The current state of the command controller.
+ */
+ protected int state = HistoryBrowser.IDLE;
+
+ /**
+ * The constructor.
+ *
+ * @param controller
+ * The DOMViewerController
+ */
+ public DocumentCommandController(DOMViewerController controller) {
+ this.controller = controller;
+ }
+
+ public void execute(final UndoableCommand command) {
+ Runnable r = new Runnable() {
+ public void run() {
+ state = HistoryBrowser.EXECUTING;
+ command.execute();
+ state = HistoryBrowser.IDLE;
+ }
+ };
+ controller.performUpdate(r);
+ }
+
+ public void undo(final UndoableCommand command) {
+ Runnable r = new Runnable() {
+ public void run() {
+ state = HistoryBrowser.UNDOING;
+ command.undo();
+ state = HistoryBrowser.IDLE;
+ }
+ };
+ controller.performUpdate(r);
+ }
+
+ public void redo(final UndoableCommand command) {
+ Runnable r = new Runnable() {
+ public void run() {
+ state = HistoryBrowser.REDOING;
+ command.redo();
+ state = HistoryBrowser.IDLE;
+ }
+ };
+ controller.performUpdate(r);
+ }
+
+ public int getState() {
+ return state;
+ }
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/HistoryBrowserInterface.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/HistoryBrowserInterface.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/HistoryBrowserInterface.java 8 Apr 2013 10:55:07 -0000 1.1
@@ -0,0 +1,1427 @@
+/*
+
+ 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.batik.apps.svgbrowser;
+
+import java.util.ArrayList;
+
+import org.apache.batik.apps.svgbrowser.HistoryBrowser.CommandController;
+import org.apache.batik.apps.svgbrowser.HistoryBrowser.HistoryBrowserEvent;
+import org.apache.batik.dom.util.DOMUtilities;
+import org.apache.batik.util.SVGConstants;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * The wrapper for the history browser. The commands for the historyBrowser
+ * are implemented here
+ *
+ * @version $Id: HistoryBrowserInterface.java,v 1.1 2013/04/08 10:55:07 marcin Exp $
+ */
+public class HistoryBrowserInterface {
+
+ // ATOM COMMANDS
+ private static final String ATTRIBUTE_ADDED_COMMAND = "Attribute added: ";
+
+ private static final String ATTRIBUTE_REMOVED_COMMAND = "Attribute removed: ";
+
+ private static final String ATTRIBUTE_MODIFIED_COMMAND = "Attribute modified: ";
+
+ private static final String NODE_INSERTED_COMMAND = "Node inserted: ";
+
+ private static final String NODE_REMOVED_COMMAND = "Node removed: ";
+
+ private static final String CHAR_DATA_MODIFIED_COMMAND = "Node value changed: ";
+
+ // OTHER COMMANDS
+ /**
+ * The changes being performed outside of the DOMViewer.
+ */
+ private static final String OUTER_EDIT_COMMAND = "Document changed outside DOM Viewer";
+
+ /**
+ * Compound tree node dropped command name.
+ */
+ private static final String COMPOUND_TREE_NODE_DROP = "Node moved";
+
+ /**
+ * Remove selected nodes command name.
+ */
+ private static final String REMOVE_SELECTED_NODES = "Nodes removed";
+
+ /**
+ * The history browser.
+ */
+ protected HistoryBrowser historyBrowser;
+
+ /**
+ * Used to group custom number of changes into a single command.
+ */
+ protected AbstractCompoundCommand currentCompoundCommand;
+
+ /**
+ * Constructor. Creates the history browser.
+ */
+ public HistoryBrowserInterface(CommandController commandController) {
+ historyBrowser = new HistoryBrowser(commandController);
+ }
+
+ /**
+ * Sets the history browser's command controller.
+ *
+ * @param newCommandController
+ * The commandController to set
+ */
+ public void setCommmandController(CommandController newCommandController) {
+ historyBrowser.setCommandController(newCommandController);
+ }
+
+ /**
+ * Creates the compound update command, that consists of custom number of
+ * commands.
+ *
+ * @param commandName
+ * Compound command name
+ * @return CompoundUpdateCommand
+ */
+ public CompoundUpdateCommand
+ createCompoundUpdateCommand(String commandName) {
+ CompoundUpdateCommand cmd = new CompoundUpdateCommand(commandName);
+ return cmd;
+ }
+
+ /**
+ * Creates the compound NodeChangedCommand. Used to create the 'dynamic'
+ * NodeChangedCommand name
+ *
+ * @return the CompoundUpdateCommand
+ */
+ public CompoundUpdateCommand createNodeChangedCommand(Node node) {
+ return new CompoundUpdateCommand(getNodeChangedCommandName(node));
+ }
+
+ /**
+ * Creates the compound NodesDroppedCommand. Used to create the 'dynamic'
+ * NodesDroppedCommand name
+ *
+ * @param nodes
+ * The list of the nodes that are being dropped
+ * @return the CompoundUpdateCommand
+ */
+ public CompoundUpdateCommand createNodesDroppedCommand(ArrayList nodes) {
+ return new CompoundUpdateCommand(COMPOUND_TREE_NODE_DROP);
+ }
+
+ /**
+ * Creates the compound RemoveSelectedTreeNodesCommand. Used to create the
+ * 'dynamic' RemoveSelectedTreeNodesCommand name
+ *
+ * @param nodes
+ * The list of the nodes that are selected and should be removed
+ * @return the RemoveSelectedTreeNodesCommand
+ */
+ public CompoundUpdateCommand
+ createRemoveSelectedTreeNodesCommand(ArrayList nodes) {
+ return new CompoundUpdateCommand(REMOVE_SELECTED_NODES);
+ }
+
+ /**
+ * Executes the given compound update command.
+ *
+ * @param command
+ * The given compound update command
+ */
+ public void performCompoundUpdateCommand(UndoableCommand command) {
+ historyBrowser.addCommand(command);
+ }
+
+ /**
+ * The compound command.
+ */
+ public static class CompoundUpdateCommand extends AbstractCompoundCommand {
+
+ /**
+ * Constructor.
+ *
+ * @param commandName
+ * The compound command name
+ */
+ public CompoundUpdateCommand(String commandName) {
+ setName(commandName);
+ }
+ }
+
+ /**
+ * Gets the history browser.
+ *
+ * @return the historyBrowser
+ */
+ public HistoryBrowser getHistoryBrowser() {
+ return historyBrowser;
+ }
+
+
+ // ATOM COMMANDS
+
+ /**
+ * Adds the NodeInsertedCommand to historyBrowser.
+ *
+ * @param newParent
+ * New parent node
+ * @param newSibling
+ * New (next) sibling node
+ * @param contextNode
+ * The node to be appended
+ */
+ public void nodeInserted(Node newParent, Node newSibling, Node contextNode) {
+ historyBrowser.addCommand(createNodeInsertedCommand(newParent,
+ newSibling, contextNode));
+ }
+
+ /**
+ * Creates the NodeInserted command.
+ *
+ * @param newParent
+ * New parent node
+ * @param newSibling
+ * New (next) sibling node
+ * @param contextNode
+ * The node to be appended
+ */
+ public NodeInsertedCommand createNodeInsertedCommand(Node newParent,
+ Node newSibling,
+ Node contextNode) {
+ return new NodeInsertedCommand
+ (NODE_INSERTED_COMMAND + getBracketedNodeName(contextNode),
+ newParent, newSibling, contextNode);
+ }
+
+ /**
+ * Inserts the given node as a child of another.
+ */
+ public static class NodeInsertedCommand extends AbstractUndoableCommand {
+
+ /**
+ * The node's next sibling.
+ */
+ protected Node newSibling;
+
+ /**
+ * The node's new parent.
+ */
+ protected Node newParent;
+
+ /**
+ * The node to be appended.
+ */
+ protected Node contextNode;
+
+ /**
+ * Constructor.
+ */
+ public NodeInsertedCommand(String commandName, Node parent,
+ Node sibling, Node contextNode) {
+ setName(commandName);
+ this.newParent = parent;
+ this.contextNode = contextNode;
+ this.newSibling = sibling;
+ }
+
+ public void execute() {
+ }
+
+ public void undo() {
+ newParent.removeChild(contextNode);
+ }
+
+ public void redo() {
+ if (newSibling != null) {
+ newParent.insertBefore(contextNode, newSibling);
+ } else {
+ newParent.appendChild(contextNode);
+ }
+ }
+
+ public boolean shouldExecute() {
+ if (newParent == null || contextNode == null) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Adds the NodeRemovedCommand to historyBrowser.
+ *
+ * @param oldParent
+ * The node's old parent
+ * @param oldSibling
+ * The node's old next sibling
+ * @param contextNode
+ * The node to be removed
+ */
+ public void nodeRemoved(Node oldParent, Node oldSibling, Node contextNode) {
+ historyBrowser.addCommand
+ (createNodeRemovedCommand(oldParent, oldSibling, contextNode));
+ }
+
+ /**
+ * Creates the NodeRemoved command.
+ *
+ * @param oldParent
+ * The node's old parent
+ * @param oldSibling
+ * The node's old next sibling
+ * @param contextNode
+ * The node to be removed
+ */
+ public NodeRemovedCommand createNodeRemovedCommand(Node oldParent,
+ Node oldSibling,
+ Node contextNode) {
+ return new NodeRemovedCommand
+ (NODE_REMOVED_COMMAND + getBracketedNodeName(contextNode),
+ oldParent, oldSibling, contextNode);
+ }
+
+ /**
+ * Removes the node from its parent node.
+ */
+ public static class NodeRemovedCommand extends AbstractUndoableCommand {
+
+ /**
+ * The node's old sibling.
+ */
+ protected Node oldSibling;
+
+ /**
+ * The node's new parent.
+ */
+ protected Node oldParent;
+
+ /**
+ * The node to be appended.
+ */
+ protected Node contextNode;
+
+ /**
+ * Constructor.
+ */
+ public NodeRemovedCommand(String commandName, Node oldParent,
+ Node oldSibling, Node contextNode) {
+ setName(commandName);
+ this.oldParent = oldParent;
+ this.contextNode = contextNode;
+ this.oldSibling = oldSibling;
+ }
+
+ public void execute() {
+ }
+
+ public void undo() {
+ if (oldSibling != null) {
+ oldParent.insertBefore(contextNode, oldSibling);
+ } else {
+ oldParent.appendChild(contextNode);
+ }
+ }
+
+ public void redo() {
+ oldParent.removeChild(contextNode);
+ }
+
+ public boolean shouldExecute() {
+ if (oldParent == null || contextNode == null) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Adds the AttributeAddedCommand to historyBrowser.
+ *
+ * @param contextElement
+ * The context element
+ * @param attributeName
+ * The attribute name
+ * @param newAttributeValue
+ * The attribute value
+ * @param namespaceURI
+ * The namespaceURI
+ */
+ public void attributeAdded(Element contextElement, String attributeName,
+ String newAttributeValue, String namespaceURI) {
+ historyBrowser.addCommand
+ (createAttributeAddedCommand(contextElement, attributeName,
+ newAttributeValue, namespaceURI));
+ }
+
+ /**
+ * Creates the AttributeAdded command.
+ *
+ * @param contextElement
+ * The context element
+ * @param attributeName
+ * The attribute name
+ * @param newAttributeValue
+ * The attribute value
+ * @param namespaceURI
+ * The namespaceURI
+ */
+ public AttributeAddedCommand
+ createAttributeAddedCommand(Element contextElement,
+ String attributeName,
+ String newAttributeValue,
+ String namespaceURI) {
+ return new AttributeAddedCommand
+ (ATTRIBUTE_ADDED_COMMAND + getBracketedNodeName(contextElement),
+ contextElement, attributeName, newAttributeValue, namespaceURI);
+ }
+
+ /**
+ * Adds the attribute to an element (MutationEvent.ADDITION)
+ */
+ public static class AttributeAddedCommand extends AbstractUndoableCommand {
+
+ /**
+ * The context element.
+ */
+ protected Element contextElement;
+
+ /**
+ * The attribute name.
+ */
+ protected String attributeName;
+
+ /**
+ * The attribute value.
+ */
+ protected String newValue;
+
+ /**
+ * The namespaceURI.
+ */
+ protected String namespaceURI;
+
+ /**
+ * Constructor.
+ *
+ * @param commandName
+ * The name of this command.
+ * @param contextElement
+ * The context element
+ * @param attributeName
+ * The attribute name
+ * @param newAttributeValue
+ * The attribute value
+ * @param namespaceURI
+ * The namespaceURI
+ */
+ public AttributeAddedCommand(String commandName,
+ Element contextElement,
+ String attributeName,
+ String newAttributeValue,
+ String namespaceURI) {
+ setName(commandName);
+ this.contextElement = contextElement;
+ this.attributeName = attributeName;
+ this.newValue = newAttributeValue;
+ this.namespaceURI = namespaceURI;
+ }
+
+ public void execute() {
+ }
+
+ public void undo() {
+ contextElement.removeAttributeNS(namespaceURI, attributeName);
+ }
+
+ public void redo() {
+ contextElement.setAttributeNS
+ (namespaceURI, attributeName, newValue);
+ }
+
+ public boolean shouldExecute() {
+ if (contextElement == null || attributeName.length() == 0) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Adds the AttributeRemovedCommand to historyBrowser.
+ *
+ * @param contextElement
+ * The context element
+ * @param attributeName
+ * The attribute name
+ * @param prevAttributeValue
+ * The previous attribute value
+ * @param namespaceURI
+ * The namespaceURI
+ */
+ public void attributeRemoved(Element contextElement,
+ String attributeName,
+ String prevAttributeValue,
+ String namespaceURI) {
+ historyBrowser.addCommand
+ (createAttributeRemovedCommand(contextElement, attributeName,
+ prevAttributeValue, namespaceURI));
+ }
+
+ /**
+ * Creates the AttributeRemoved command.
+ *
+ * @param contextElement
+ * The context element
+ * @param attributeName
+ * The attribute name
+ * @param prevAttributeValue
+ * The previous attribute value
+ * @param namespaceURI
+ * The namespaceURI
+ */
+ public AttributeRemovedCommand
+ createAttributeRemovedCommand(Element contextElement,
+ String attributeName,
+ String prevAttributeValue,
+ String namespaceURI) {
+ return new AttributeRemovedCommand
+ (ATTRIBUTE_REMOVED_COMMAND + getBracketedNodeName(contextElement),
+ contextElement, attributeName, prevAttributeValue, namespaceURI);
+ }
+
+ /**
+ * Removes the attribute of an element (MutationEvent.REMOVAL)
+ */
+ public static class AttributeRemovedCommand extends AbstractUndoableCommand {
+
+ /**
+ * The context element.
+ */
+ protected Element contextElement;
+
+ /**
+ * The attribute name.
+ */
+ protected String attributeName;
+
+ /**
+ * The previous attribute value.
+ */
+ protected String prevValue;
+
+ /**
+ * The namespaceURI.
+ */
+ protected String namespaceURI;
+
+ /**
+ * Constructor.
+ *
+ * @param commandName
+ * The name of this command.
+ * @param contextElement
+ * The context element
+ * @param attributeName
+ * The attribute name
+ * @param prevAttributeValue
+ * The previous attribute value
+ * @param namespaceURI
+ * The namespaceURI
+ */
+ public AttributeRemovedCommand(String commandName,
+ Element contextElement,
+ String attributeName,
+ String prevAttributeValue,
+ String namespaceURI) {
+ setName(commandName);
+ this.contextElement = contextElement;
+ this.attributeName = attributeName;
+ this.prevValue = prevAttributeValue;
+ this.namespaceURI = namespaceURI;
+ }
+
+ public void execute() {
+ }
+
+ public void undo() {
+ contextElement.setAttributeNS
+ (namespaceURI, attributeName, prevValue);
+ }
+
+ public void redo() {
+ contextElement.removeAttributeNS(namespaceURI, attributeName);
+ }
+
+ public boolean shouldExecute() {
+ if (contextElement == null || attributeName.length() == 0) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Adds the AttributeModifiedCommand to historyBrowser.
+ *
+ * @param contextElement
+ * The context element
+ * @param attributeName
+ * The attribute name
+ * @param prevAttributeValue
+ * The previous attribute value
+ * @param newAttributeValue
+ * The new attribute value
+ * @param namespaceURI
+ * The namespaceURI
+ */
+ public void attributeModified(Element contextElement,
+ String attributeName,
+ String prevAttributeValue,
+ String newAttributeValue,
+ String namespaceURI) {
+ historyBrowser.addCommand
+ (createAttributeModifiedCommand(contextElement, attributeName,
+ prevAttributeValue,
+ newAttributeValue, namespaceURI));
+ }
+
+ /**
+ * Creates the AttributeModified command.
+ *
+ * @param contextElement
+ * The context element
+ * @param attributeName
+ * The attribute name
+ * @param prevAttributeValue
+ * The previous attribute value
+ * @param newAttributeValue
+ * The new attribute value
+ * @param namespaceURI
+ * The namespaceURI
+ */
+ public AttributeModifiedCommand
+ createAttributeModifiedCommand(Element contextElement,
+ String attributeName,
+ String prevAttributeValue,
+ String newAttributeValue,
+ String namespaceURI) {
+ return new AttributeModifiedCommand
+ (ATTRIBUTE_MODIFIED_COMMAND + getBracketedNodeName(contextElement),
+ contextElement, attributeName, prevAttributeValue,
+ newAttributeValue, namespaceURI);
+ }
+
+ /**
+ * Modifies the attribute of an element (MutationEvent.MODIFICATION)
+ */
+ public static class AttributeModifiedCommand extends AbstractUndoableCommand {
+
+ /**
+ * The context element.
+ */
+ protected Element contextElement;
+
+ /**
+ * The attribute name.
+ */
+ protected String attributeName;
+
+ /**
+ * Previous attribute value.
+ */
+ protected String prevAttributeValue;
+
+ /**
+ * New attribute value.
+ */
+ protected String newAttributeValue;
+
+ /**
+ * The namespaceURI.
+ */
+ protected String namespaceURI;
+
+ /**
+ * Constructor.
+ *
+ * @param commandName
+ * The name of this command.
+ * @param contextElement
+ * The context element
+ * @param attributeName
+ * The attribute name
+ * @param prevAttributeValue
+ * The previous attribute value
+ * @param newAttributeValue
+ * The new attribute value
+ * @param namespaceURI
+ * The namespaceURI
+ */
+ public AttributeModifiedCommand(String commandName,
+ Element contextElement,
+ String attributeName,
+ String prevAttributeValue,
+ String newAttributeValue,
+ String namespaceURI) {
+ setName(commandName);
+ this.contextElement = contextElement;
+ this.attributeName = attributeName;
+ this.prevAttributeValue = prevAttributeValue;
+ this.newAttributeValue = newAttributeValue;
+ this.namespaceURI = namespaceURI;
+ }
+
+ public void execute() {
+ }
+
+ public void undo() {
+ contextElement.setAttributeNS
+ (namespaceURI, attributeName, prevAttributeValue);
+ }
+
+ public void redo() {
+ contextElement.setAttributeNS
+ (namespaceURI, attributeName, newAttributeValue);
+ }
+
+ public boolean shouldExecute() {
+ if (contextElement == null || attributeName.length() == 0) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Adds CharDataModifiedCommand to historyBrowser.
+ *
+ * @param contextNode
+ * The node whose nodeValue changed
+ * @param oldValue
+ * The old node value
+ * @param newValue
+ * The new node value
+ */
+ public void charDataModified(Node contextNode, String oldValue,
+ String newValue) {
+ historyBrowser.addCommand
+ (createCharDataModifiedCommand(contextNode, oldValue, newValue));
+ }
+
+ /**
+ * Creates the CharDataModified command.
+ *
+ * @param contextNode
+ * The node whose nodeValue changed
+ * @param oldValue
+ * The old node value
+ * @param newValue
+ * The new node value
+ */
+ public CharDataModifiedCommand
+ createCharDataModifiedCommand(Node contextNode,
+ String oldValue,
+ String newValue) {
+ return new CharDataModifiedCommand
+ (CHAR_DATA_MODIFIED_COMMAND + getBracketedNodeName(contextNode),
+ contextNode, oldValue, newValue);
+ }
+
+ /**
+ * Sets the node value.
+ */
+ public static class CharDataModifiedCommand extends AbstractUndoableCommand {
+
+ /**
+ * The node whose value changed.
+ */
+ protected Node contextNode;
+
+ /**
+ * Old node value.
+ */
+ protected String oldValue;
+
+ /**
+ * New node value.
+ */
+ protected String newValue;
+
+ /**
+ * Constructor.
+ *
+ * @param commandName
+ * The command name
+ * @param contextNode
+ * Context node
+ * @param oldValue
+ * Old node value
+ * @param newValue
+ * New node value
+ */
+ public CharDataModifiedCommand(String commandName, Node contextNode,
+ String oldValue, String newValue) {
+ setName(commandName);
+ this.contextNode = contextNode;
+ this.oldValue = oldValue;
+ this.newValue = newValue;
+ }
+
+ public void execute() {
+ }
+
+ public void undo() {
+ contextNode.setNodeValue(oldValue);
+ }
+
+ public void redo() {
+ contextNode.setNodeValue(newValue);
+ }
+
+ public boolean shouldExecute() {
+ if (contextNode == null) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ // OTHER COMMANDS
+
+ /**
+ * Adds and executes the AppendChildCommand to historyBrowser.
+ *
+ * @param parent
+ * The given parent
+ * @param child
+ * The node to be appended
+ */
+ public void appendChild(Node parent, Node child) {
+ historyBrowser.addCommand(createAppendChildCommand(parent, child));
+ }
+
+
+ /**
+ * Creates and return the AppendChild command.
+ *
+ * @param parent
+ * The given parent
+ * @param child
+ * The node to be appended
+ * @return the AppendChild command
+ */
+ public AppendChildCommand createAppendChildCommand(Node parent,
+ Node child) {
+ return new AppendChildCommand
+ (getAppendChildCommandName(parent, child), parent, child);
+ }
+
+ /**
+ * The AppendChild command. Appends the given node to the given parent node
+ * as a last child.
+ */
+ public static class AppendChildCommand extends AbstractUndoableCommand {
+
+ /**
+ * The node's previous parent.
+ */
+ protected Node oldParentNode;
+
+ /**
+ * The node's previous next sibling.
+ */
+ protected Node oldNextSibling;
+
+ /**
+ * The node's new parent.
+ */
+ protected Node parentNode;
+
+ /**
+ * The node to be appended.
+ */
+ protected Node childNode;
+
+ /**
+ * Constructor.
+ */
+ public AppendChildCommand(String commandName, Node parentNode,
+ Node childNode) {
+ setName(commandName);
+ this.oldParentNode = childNode.getParentNode();
+ this.oldNextSibling = childNode.getNextSibling();
+ this.parentNode = parentNode;
+ this.childNode = childNode;
+ }
+
+ public void execute() {
+ parentNode.appendChild(childNode);
+ }
+
+ public void undo() {
+ if (oldParentNode != null) {
+ oldParentNode.insertBefore(childNode, oldNextSibling);
+ } else {
+ parentNode.removeChild(childNode);
+ }
+ }
+
+ public void redo() {
+ execute();
+ }
+
+ public boolean shouldExecute() {
+ if (parentNode == null || childNode == null) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Adds and executes the InsertNodeBeforeCommand to historyBrowser.
+ *
+ * @param parent
+ * The given parent
+ * @param sibling
+ * Points where to be inserted
+ * @param child
+ * The node to insert
+ */
+ public void insertChildBefore(Node parent, Node sibling, Node child) {
+ if (sibling == null) {
+ historyBrowser.addCommand(createAppendChildCommand(parent, child));
+ } else {
+ historyBrowser.addCommand
+ (createInsertNodeBeforeCommand(parent, sibling, child));
+ }
+ }
+
+ /**
+ * Creates InsertChildBefore or AppendChild command, depending on the value
+ * of siblingNode.
+ *
+ * @param parent
+ * The parent node
+ * @param sibling
+ * The sibling node
+ * @param child
+ * The child node
+ * @return AppendChild command if sibling node is null, InsertChildBefore
+ * otherwise
+ */
+ public UndoableCommand createInsertChildCommand(Node parent,
+ Node sibling,
+ Node child) {
+ if (sibling == null) {
+ return createAppendChildCommand(parent, child);
+ } else {
+ return createInsertNodeBeforeCommand(parent, sibling, child);
+ }
+ }
+ /**
+ * Creates and returns the InsertNodeBeforeCommand.
+ *
+ * @param parent
+ * The given parent
+ * @param sibling
+ * Points where to be inserted
+ * @param child
+ * The node to insert
+ * @return the InsertNodeBeforeCommand
+ */
+ public InsertNodeBeforeCommand createInsertNodeBeforeCommand(Node parent,
+ Node sibling,
+ Node child) {
+ return new InsertNodeBeforeCommand
+ (getInsertBeforeCommandName(parent, child, sibling),
+ parent, sibling, child);
+ }
+
+ /**
+ * Inserts the given node as a child to the given parent node before the
+ * specified sibling node, or as the last child of the given parent, if the
+ * sibling node is null.
+ */
+ public static class InsertNodeBeforeCommand extends AbstractUndoableCommand {
+
+ /**
+ * The node's previous parent.
+ */
+ protected Node oldParent;
+
+ /**
+ * The node's previous next sibling.
+ */
+ protected Node oldNextSibling;
+
+ /**
+ * The node's new next sibling.
+ */
+ protected Node newNextSibling;
+
+ /**
+ * The node's new parent.
+ */
+ protected Node parent;
+
+ /**
+ * The node to be appended.
+ */
+ protected Node child;
+
+ /**
+ * Constructor.
+ */
+ public InsertNodeBeforeCommand(String commandName, Node parent,
+ Node sibling, Node child) {
+ setName(commandName);
+ this.oldParent = child.getParentNode();
+ this.oldNextSibling = child.getNextSibling();
+ this.parent = parent;
+ this.child = child;
+ this.newNextSibling = sibling;
+ }
+
+ public void execute() {
+ if (newNextSibling != null) {
+ parent.insertBefore(child, newNextSibling);
+ } else {
+ parent.appendChild(child);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.batik.util.gui.AbstractUndoableCommand#undo()
+ */
+ public void undo() {
+ if (oldParent != null) {
+ oldParent.insertBefore(child, oldNextSibling);
+ } else {
+ parent.removeChild(child);
+ }
+ }
+
+ public void redo() {
+ execute();
+ }
+
+ public boolean shouldExecute() {
+ if (parent == null || child == null) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+
+ /**
+ * Adds and executes the ReplaceChild command to historyBrowser.
+ *
+ * @param parent
+ * The parent node
+ * @param newChild
+ * Points where to be inserted
+ * @param oldChild
+ * The node to be appended
+ */
+ public void replaceChild(Node parent, Node newChild, Node oldChild) {
+// if (sibling == null) {
+// historyBrowser.addCommand(new AppendChildCommand(
+// APPEND_CHILD_COMMAND, parent, child));
+// } else {
+// historyBrowser.addCommand(new InsertNodeBeforeCommand(
+// REPLACE_CHILD_COMMAND, parent, sibling, child));
+// }
+ }
+
+ /**
+ * insertBefore
+ */
+ public static class ReplaceChildCommand extends AbstractUndoableCommand {
+
+ /**
+ * The node's previous parent.
+ */
+ protected Node oldParent;
+
+ /**
+ * The node's previous next sibling.
+ */
+ protected Node oldNextSibling;
+
+ /**
+ * The node's new next sibling.
+ */
+ protected Node newNextSibling;
+
+ /**
+ * The node's new parent.
+ */
+ protected Node parent;
+
+ /**
+ * The node to be appended.
+ */
+ protected Node child;
+
+ /**
+ * Constructor.
+ */
+ public ReplaceChildCommand(String commandName, Node parent,
+ Node sibling, Node child) {
+ setName(commandName);
+ this.oldParent = child.getParentNode();
+ this.oldNextSibling = child.getNextSibling();
+ this.parent = parent;
+ this.child = child;
+ this.newNextSibling = sibling;
+ }
+
+ public void execute() {
+ if (newNextSibling != null) {
+ parent.insertBefore(child, newNextSibling);
+ } else {
+ parent.appendChild(child);
+ }
+ }
+
+ public void undo() {
+ if (oldParent != null) {
+ oldParent.insertBefore(child, oldNextSibling);
+ } else {
+ parent.removeChild(child);
+ }
+ }
+
+ public void redo() {
+ execute();
+ }
+
+ public boolean shouldExecute() {
+ if (parent == null || child == null) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Adds and executes the RemoveChild command to the History Browser.
+ *
+ * @param parent
+ * The given parent
+ * @param child
+ * The given child
+ */
+ public void removeChild(Node parent, Node child) {
+ historyBrowser.addCommand(createRemoveChildCommand(parent, child));
+ }
+
+ /**
+ * Creates and returns the RemoveChild command.
+ *
+ * @param parent
+ * The parent node
+ * @param child
+ * The child node
+ * @return The RemoveChild command
+ */
+ public RemoveChildCommand createRemoveChildCommand(Node parent,
+ Node child) {
+ return new RemoveChildCommand
+ (getRemoveChildCommandName(parent, child), parent, child);
+ }
+
+ /**
+ * The RemoveChild command. Removes the given child node from its given
+ * parent node.
+ */
+ public static class RemoveChildCommand extends AbstractUndoableCommand {
+
+ /**
+ * Node's previous parent.
+ */
+ protected Node parentNode;
+
+ /**
+ * The node to be removed.
+ */
+ protected Node childNode;
+
+ /**
+ * Node's index in parent's children array.
+ */
+ protected int indexInChildrenArray;
+
+ /**
+ * Constructor.
+ */
+ public RemoveChildCommand(String commandName, Node parentNode,
+ Node childNode) {
+ setName(commandName);
+ this.parentNode = parentNode;
+ this.childNode = childNode;
+ }
+
+ public void execute() {
+ indexInChildrenArray =
+ DOMUtilities.getChildIndex(childNode, parentNode);
+ parentNode.removeChild(childNode);
+ }
+
+ public void undo() {
+ Node refChild =
+ parentNode.getChildNodes().item(indexInChildrenArray);
+ parentNode.insertBefore(childNode, refChild);
+ }
+
+ public void redo() {
+ parentNode.removeChild(childNode);
+ }
+
+ public boolean shouldExecute() {
+ if (parentNode == null || childNode == null) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Adds and executes the ChangeNodeValueCommand to historyBrowser.
+ *
+ * @param contextNode
+ * The node whose nodeValue changed
+ * @param newValue
+ * The new node value
+ */
+ public void setNodeValue(Node contextNode, String newValue) {
+ historyBrowser.addCommand
+ (createChangeNodeValueCommand(contextNode, newValue));
+ }
+
+ /**
+ * Creates and returns the ChangeNodeValue command.
+ *
+ * @param contextNode
+ * The node whose nodeValue changed
+ * @param newValue
+ * The new node value
+ * @return the ChangeNodeValue command
+ */
+ public ChangeNodeValueCommand
+ createChangeNodeValueCommand(Node contextNode, String newValue) {
+ return new ChangeNodeValueCommand
+ (getChangeNodeValueCommandName(contextNode, newValue),
+ contextNode, newValue);
+ }
+
+ /**
+ * The Change Node Value command. Sets the given node value to the given
+ * node.
+ */
+ public static class ChangeNodeValueCommand extends AbstractUndoableCommand {
+
+ /**
+ * The node whose value changed.
+ */
+ protected Node contextNode;
+
+ /**
+ * New node value.
+ */
+ protected String newValue;
+
+ /**
+ * Constructor.
+ */
+ public ChangeNodeValueCommand(String commandName, Node contextNode,
+ String newValue) {
+ setName(commandName);
+ this.contextNode = contextNode;
+ this.newValue = newValue;
+ }
+
+ public void execute() {
+ String oldNodeValue = contextNode.getNodeValue();
+ contextNode.setNodeValue(newValue);
+ newValue = oldNodeValue;
+ }
+
+ public void undo() {
+ execute();
+ }
+
+ public void redo() {
+ execute();
+ }
+
+ public boolean shouldExecute() {
+ if (contextNode == null) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Gets the current compound command.
+ *
+ * @return the currentCompoundCommand
+ */
+ public AbstractCompoundCommand getCurrentCompoundCommand() {
+ if (currentCompoundCommand == null) {
+ currentCompoundCommand =
+ createCompoundUpdateCommand(OUTER_EDIT_COMMAND);
+ }
+ return currentCompoundCommand;
+ }
+
+ /**
+ * Adds the given command to current compound command.
+ *
+ * @param cmd
+ * The command to add
+ */
+ public void addToCurrentCompoundCommand(AbstractUndoableCommand cmd) {
+ getCurrentCompoundCommand().addCommand(cmd);
+ // Fire the 'doCompoundEdit' event
+ historyBrowser.fireDoCompoundEdit
+ (new HistoryBrowserEvent(getCurrentCompoundCommand()));
+ }
+
+ /**
+ * Adds and executes the current compound command to history browser.
+ */
+ public void performCurrentCompoundCommand() {
+ if (getCurrentCompoundCommand().getCommandNumber() > 0) {
+ historyBrowser.addCommand(getCurrentCompoundCommand());
+ // Fire the 'compoundEditPerformed' event
+ historyBrowser.fireCompoundEditPerformed
+ (new HistoryBrowserEvent(currentCompoundCommand));
+ // Reset the current compound command
+ currentCompoundCommand = null;
+ }
+ }
+
+ // Command names
+ /**
+ * Gets the node name and the nodes id (nodeName + "nodeId").
+ *
+ * @param node
+ * The given node
+ * @return e.g. node name with quoted node id or node name if id is empty
+ * String
+ */
+ private String getNodeAsString(Node node) {
+ String id = "";
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ Element e = (Element) node;
+ id = e.getAttributeNS(null, SVGConstants.SVG_ID_ATTRIBUTE);
+ }
+ if (id.length() != 0) {
+ return node.getNodeName() + " \"" + id + "\"";
+ }
+ return node.getNodeName();
+ }
+
+ /**
+ * Gets the node info in brackets.
+ *
+ * @param node
+ * The given node
+ * @return e.g (rect "23")
+ */
+ private String getBracketedNodeName(Node node) {
+ return "(" + getNodeAsString(node) + ")";
+ }
+
+ /**
+ * Generates the "Append Child" command name.
+ *
+ * @param parentNode
+ * The parent node
+ * @param childNode
+ * The child node
+ * @return The command name
+ */
+ private String getAppendChildCommandName(Node parentNode, Node childNode) {
+ return "Append " + getNodeAsString(childNode) + " to "
+ + getNodeAsString(parentNode);
+ }
+
+ /**
+ * Generates the "Insert Child Before" command name.
+ *
+ * @param parentNode
+ * The parentNode
+ * @param childNode
+ * The node being inserted
+ * @param siblingNode
+ * The new sibling node
+ * @return The command name
+ */
+ private String getInsertBeforeCommandName(Node parentNode, Node childNode,
+ Node siblingNode) {
+ return "Insert " + getNodeAsString(childNode) + " to "
+ + getNodeAsString(parentNode) + " before "
+ + getNodeAsString(siblingNode);
+ }
+
+ /**
+ * Generates the "Remove Child" command name.
+ *
+ * @param parent
+ * The parent node
+ * @param child
+ * The child node
+ * @return The command name
+ */
+ private String getRemoveChildCommandName(Node parent, Node child) {
+ return "Remove " + getNodeAsString(child) + " from "
+ + getNodeAsString(parent);
+ }
+
+ /**
+ * Generates the "Change Node Value" command name.
+ *
+ * @param contextNode
+ * The node whose value is to be changed
+ * @param newValue
+ * The new node value
+ * @return The command name
+ */
+ private String getChangeNodeValueCommandName(Node contextNode,
+ String newValue) {
+ return "Change " + getNodeAsString(contextNode) + " value to "
+ + newValue;
+ }
+
+ /**
+ * Generates the "Node Changed" command name.
+ * @return The command name
+ */
+ private String getNodeChangedCommandName(Node node) {
+ return "Node " + getNodeAsString(node) + " changed";
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/JAuthenticator.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/JAuthenticator.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/JAuthenticator.java 8 Apr 2013 10:55:08 -0000 1.1
@@ -0,0 +1,243 @@
+/*
+
+ 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.batik.apps.svgbrowser;
+
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;
+
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JTextField;
+import javax.swing.SwingConstants;
+
+/**
+ * This class is resposible for providing authentication information
+ * when needed by network protocols. It does this by poping up a small
+ * window that asks for User ID and password for the system.
+ *
+ * @author Thomas DeWeese
+ * @version $Id: JAuthenticator.java,v 1.1 2013/04/08 10:55:08 marcin Exp $
+ */
+public class JAuthenticator extends Authenticator {
+
+ /**
+ * Internationalization message string
+ */
+ public static final String TITLE
+ = "JAuthenticator.title";
+ public static final String LABEL_SITE
+ = "JAuthenticator.label.site";
+ public static final String LABEL_REQ
+ = "JAuthenticator.label.req";
+ public static final String LABEL_USERID
+ = "JAuthenticator.label.userID";
+ public static final String LABEL_PASSWORD
+ = "JAuthenticator.label.password";
+
+ public static final String LABEL_CANCEL
+ = "JAuthenticator.label.cancel";
+ public static final String LABEL_OK
+ = "JAuthenticator.label.ok";
+
+ protected JDialog window;
+ protected JButton cancelButton;
+ protected JButton okButton;
+
+ protected JLabel label1;
+ protected JLabel label2;
+ protected JTextField JUserID;
+ protected JPasswordField JPassword;
+
+ final Object lock = new Object();
+
+ private boolean result;
+ private volatile boolean wasNotified;
+ private String userID;
+ private char [] password;
+
+ public JAuthenticator() {
+ initWindow();
+ }
+
+ protected void initWindow() {
+ String title = Resources.getString(TITLE);
+ window = new JDialog((Frame)null, title, true);
+
+ Container mainPanel = window.getContentPane();
+ mainPanel.setLayout(new BorderLayout());
+ mainPanel.add(buildAuthPanel(), BorderLayout.CENTER);
+ mainPanel.add(buildButtonPanel(), BorderLayout.SOUTH);
+ window.pack();
+
+ window.addWindowListener( new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ cancelListener.actionPerformed
+ (new ActionEvent(e.getWindow(),
+ ActionEvent.ACTION_PERFORMED,
+ "Close"));
+ }
+ });
+ }
+
+ protected JComponent buildAuthPanel() {
+ GridBagLayout gridBag = new GridBagLayout();
+ GridBagConstraints c = new GridBagConstraints();
+ JPanel proxyPanel = new JPanel(gridBag);
+ c.fill = GridBagConstraints.BOTH;
+ c.weightx = 1.0;
+
+ c.gridwidth = 1;
+ JLabel labelS = new JLabel(Resources.getString(LABEL_SITE));
+ labelS.setHorizontalAlignment(SwingConstants.LEFT);
+ gridBag.setConstraints(labelS, c);
+ proxyPanel.add(labelS);
+
+ c.gridwidth = GridBagConstraints.REMAINDER;
+ label1 = new JLabel("");
+ label1.setHorizontalAlignment(SwingConstants.LEFT);
+ gridBag.setConstraints(label1, c);
+ proxyPanel.add(label1);
+
+ c.gridwidth = 1;
+ JLabel labelR = new JLabel(Resources.getString(LABEL_REQ));
+ labelR.setHorizontalAlignment(SwingConstants.LEFT);
+ gridBag.setConstraints(labelR, c);
+ proxyPanel.add(labelR);
+
+ c.gridwidth = GridBagConstraints.REMAINDER;
+ label2 = new JLabel("");
+ label2.setHorizontalAlignment(SwingConstants.LEFT);
+ gridBag.setConstraints(label2, c);
+ proxyPanel.add(label2);
+
+ c.gridwidth = 1;
+ JLabel labelUserID = new JLabel(Resources.getString(LABEL_USERID));
+ labelUserID.setHorizontalAlignment(SwingConstants.LEFT);
+ gridBag.setConstraints(labelUserID, c);
+ proxyPanel.add(labelUserID);
+
+ c.gridwidth = GridBagConstraints.REMAINDER;
+ JUserID = new JTextField(20);
+ gridBag.setConstraints(JUserID, c);
+ proxyPanel.add(JUserID);
+
+ c.gridwidth = 1;
+ JLabel labelPassword = new JLabel(Resources.getString(LABEL_PASSWORD));
+ labelPassword.setHorizontalAlignment(SwingConstants.LEFT);
+ gridBag.setConstraints(labelPassword, c);
+ proxyPanel.add(labelPassword);
+
+ c.gridwidth = GridBagConstraints.REMAINDER;
+ JPassword = new JPasswordField(20);
+ JPassword.setEchoChar('*');
+ JPassword.addActionListener(okListener);
+ gridBag.setConstraints(JPassword, c);
+ proxyPanel.add(JPassword);
+
+ return proxyPanel;
+ }
+
+
+
+ protected JComponent buildButtonPanel() {
+ JPanel buttonPanel = new JPanel();
+ cancelButton = new JButton(Resources.getString(LABEL_CANCEL));
+ cancelButton.addActionListener(cancelListener);
+ buttonPanel.add(cancelButton);
+
+ okButton = new JButton(Resources.getString(LABEL_OK));
+ okButton.addActionListener( okListener);
+ buttonPanel.add(okButton);
+
+ return buttonPanel;
+ }
+
+ /**
+ * This is called by the protocol stack when authentication is
+ * required. We then show the dialog in the Swing event thread,
+ * and block waiting for the user to select either cancel or ok,
+ * at which point we get notified.
+ */
+ public PasswordAuthentication getPasswordAuthentication() {
+ synchronized (lock) {
+ EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ label1.setText(getRequestingSite().getHostName());
+ label2.setText(getRequestingPrompt());
+ window.setVisible(true);
+ }
+ });
+ wasNotified = false;
+ while (!wasNotified) {
+ try {
+ lock.wait();
+ } catch(InterruptedException ie) { }
+ }
+ if (!result)
+ return null;
+
+ return new PasswordAuthentication(userID, password);
+ }
+ }
+
+ ActionListener okListener = new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ synchronized (lock) {
+ window.setVisible(false);
+
+ userID = JUserID.getText();
+ password = JPassword.getPassword();
+ JPassword.setText("");
+ result = true;
+ wasNotified = true;
+ lock.notifyAll();
+ }
+ }
+ };
+
+ ActionListener cancelListener = new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ synchronized (lock) {
+ window.setVisible(false);
+
+ userID = null;
+ JUserID.setText("");
+ password = null;
+ JPassword.setText("");
+ result = false;
+ wasNotified = true;
+ lock.notifyAll();
+ }
+ }
+ };
+}
Index: 3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/JPEGOptionPanel.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/JPEGOptionPanel.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/JPEGOptionPanel.java 8 Apr 2013 10:55:07 -0000 1.1
@@ -0,0 +1,108 @@
+/*
+
+ 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.batik.apps.svgbrowser;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.util.Hashtable;
+
+import javax.swing.BorderFactory;
+import javax.swing.JLabel;
+import javax.swing.JSlider;
+
+import org.apache.batik.util.gui.ExtendedGridBagConstraints;
+
+/**
+ * This class represents a panel to control jpeg encoding quality.
+ *
+ * @author Thierry Kormann
+ * @version $Id: JPEGOptionPanel.java,v 1.1 2013/04/08 10:55:07 marcin Exp $
+ */
+public class JPEGOptionPanel extends OptionPanel {
+ /**
+ * The jpeg encoding quality.
+ */
+ protected JSlider quality;
+
+ /**
+ * Creates a new panel.
+ */
+ public JPEGOptionPanel() {
+ super(new GridBagLayout());
+
+ ExtendedGridBagConstraints constraints =
+ new ExtendedGridBagConstraints();
+
+
+ constraints.insets = new Insets(5, 5, 5, 5);
+
+ constraints.weightx = 0;
+ constraints.weighty = 0;
+ constraints.fill = GridBagConstraints.NONE;
+ constraints.setGridBounds(0, 0, 1, 1);
+ add(new JLabel(resources.getString("JPEGOptionPanel.label")),
+ constraints);
+
+ quality = new JSlider();
+ quality.setMinimum(0);
+ quality.setMaximum(100);
+ quality.setMajorTickSpacing(10);
+ quality.setMinorTickSpacing(5);
+ quality.setPaintTicks(true);
+ quality.setPaintLabels(true);
+ quality.setBorder(BorderFactory.createEmptyBorder(0,0,10,0));
+ Hashtable labels = new Hashtable();
+ for (int i=0; i < 100; i+=10) {
+ labels.put(new Integer(i), new JLabel("0."+i/10));
+ }
+ labels.put(new Integer(100), new JLabel("1"));
+ quality.setLabelTable(labels);
+
+ Dimension dim = quality.getPreferredSize();
+ quality.setPreferredSize(new Dimension(350, dim.height));
+
+ constraints.weightx = 1.0;
+ constraints.fill = GridBagConstraints.HORIZONTAL;
+ constraints.setGridBounds(1, 0, 1, 1);
+ add(quality, constraints);
+ }
+
+ /**
+ * Returns the jpeg quality.
+ */
+ public float getQuality() {
+ return quality.getValue()/100f;
+ }
+
+ /**
+ * Shows a dialog to choose the jpeg encoding quality and return
+ * the quality as a float.
+ */
+ public static float showDialog(Component parent) {
+ String title = resources.getString("JPEGOptionPanel.dialog.title");
+ JPEGOptionPanel panel = new JPEGOptionPanel();
+ Dialog dialog = new Dialog(parent, title, panel);
+ dialog.pack();
+ dialog.setVisible(true);
+ return panel.getQuality();
+ }
+}
Index: 3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/JSVGViewerFrame.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/JSVGViewerFrame.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/JSVGViewerFrame.java 8 Apr 2013 10:55:08 -0000 1.1
@@ -0,0 +1,3137 @@
+/*
+
+ 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.batik.apps.svgbrowser;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Event;
+import java.awt.EventQueue;
+import java.awt.FileDialog;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionAdapter;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+import java.awt.image.BufferedImage;
+import java.awt.print.PrinterException;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.Vector;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.BorderFactory;
+import javax.swing.ButtonGroup;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.JScrollPane;
+import javax.swing.JToolBar;
+import javax.swing.JWindow;
+import javax.swing.KeyStroke;
+import javax.swing.filechooser.FileFilter;
+import javax.swing.text.Document;
+
+import org.apache.batik.bridge.DefaultExternalResourceSecurity;
+import org.apache.batik.bridge.DefaultScriptSecurity;
+import org.apache.batik.bridge.EmbededExternalResourceSecurity;
+import org.apache.batik.bridge.EmbededScriptSecurity;
+import org.apache.batik.bridge.ExternalResourceSecurity;
+import org.apache.batik.bridge.NoLoadExternalResourceSecurity;
+import org.apache.batik.bridge.NoLoadScriptSecurity;
+import org.apache.batik.bridge.RelaxedExternalResourceSecurity;
+import org.apache.batik.bridge.RelaxedScriptSecurity;
+import org.apache.batik.bridge.ScriptSecurity;
+import org.apache.batik.bridge.UpdateManager;
+import org.apache.batik.bridge.UpdateManagerEvent;
+import org.apache.batik.bridge.UpdateManagerListener;
+import org.apache.batik.dom.StyleSheetProcessingInstruction;
+import org.apache.batik.dom.svg.SVGOMDocument;
+import org.apache.batik.dom.util.HashTable;
+import org.apache.batik.dom.util.DOMUtilities;
+import org.apache.batik.ext.swing.JAffineTransformChooser;
+import org.apache.batik.swing.JSVGCanvas;
+import org.apache.batik.swing.gvt.GVTTreeRendererEvent;
+import org.apache.batik.swing.gvt.GVTTreeRendererListener;
+import org.apache.batik.swing.gvt.Overlay;
+import org.apache.batik.swing.svg.GVTTreeBuilderEvent;
+import org.apache.batik.swing.svg.GVTTreeBuilderListener;
+import org.apache.batik.swing.svg.LinkActivationEvent;
+import org.apache.batik.swing.svg.LinkActivationListener;
+import org.apache.batik.swing.svg.SVGDocumentLoaderEvent;
+import org.apache.batik.swing.svg.SVGDocumentLoaderListener;
+import org.apache.batik.swing.svg.SVGFileFilter;
+import org.apache.batik.swing.svg.SVGLoadEventDispatcherEvent;
+import org.apache.batik.swing.svg.SVGLoadEventDispatcherListener;
+import org.apache.batik.swing.svg.SVGUserAgent;
+import org.apache.batik.transcoder.TranscoderInput;
+import org.apache.batik.transcoder.TranscoderOutput;
+import org.apache.batik.transcoder.image.ImageTranscoder;
+import org.apache.batik.transcoder.image.JPEGTranscoder;
+import org.apache.batik.transcoder.image.PNGTranscoder;
+import org.apache.batik.transcoder.image.TIFFTranscoder;
+import org.apache.batik.transcoder.print.PrintTranscoder;
+import org.apache.batik.transcoder.svg2svg.SVGTranscoder;
+import org.apache.batik.util.ParsedURL;
+import org.apache.batik.util.Platform;
+import org.apache.batik.util.Service;
+import org.apache.batik.util.SVGConstants;
+import org.apache.batik.util.XMLConstants;
+import org.apache.batik.util.gui.JErrorPane;
+import org.apache.batik.util.gui.LocationBar;
+import org.apache.batik.util.gui.MemoryMonitor;
+import org.apache.batik.util.gui.URIChooser;
+import org.apache.batik.util.gui.resource.ActionMap;
+import org.apache.batik.util.gui.resource.JComponentModifier;
+import org.apache.batik.util.gui.resource.MenuFactory;
+import org.apache.batik.util.gui.resource.MissingListenerException;
+import org.apache.batik.util.gui.resource.ToolBarFactory;
+import org.apache.batik.util.gui.xmleditor.XMLDocument;
+import org.apache.batik.util.gui.xmleditor.XMLTextEditor;
+import org.apache.batik.util.resources.ResourceManager;
+import org.apache.batik.xml.XMLUtilities;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.css.ViewCSS;
+import org.w3c.dom.svg.SVGDocument;
+
+/**
+ * This class represents a SVG viewer swing frame.
+ *
+ * @author Stephane Hillion
+ * @version $Id: JSVGViewerFrame.java,v 1.1 2013/04/08 10:55:08 marcin Exp $
+ */
+public class JSVGViewerFrame
+ extends JFrame
+ implements ActionMap,
+ SVGDocumentLoaderListener,
+ GVTTreeBuilderListener,
+ SVGLoadEventDispatcherListener,
+ GVTTreeRendererListener,
+ LinkActivationListener,
+ UpdateManagerListener {
+
+ private static String EOL;
+ static {
+ try {
+ EOL = System.getProperty("line.separator", "\n");
+ } catch (SecurityException e) {
+ EOL = "\n";
+ }
+ }
+
+ /**
+ * Kind of ugly, but we need to know if we are running before
+ * or after 1.4...
+ */
+ protected static boolean priorJDK1_4 = true;
+
+ /**
+ * If the following class can be found (it appeared in JDK 1.4),
+ * then we know we are post JDK 1.4.
+ */
+ protected static final String JDK_1_4_PRESENCE_TEST_CLASS
+ = "java.util.logging.LoggingPermission";
+
+ static {
+ try {
+ Class.forName(JDK_1_4_PRESENCE_TEST_CLASS);
+ priorJDK1_4 = false;
+ } catch (ClassNotFoundException e) {
+ }
+ }
+
+ /**
+ * The gui resources file name
+ */
+ public static final String RESOURCES =
+ "org.apache.batik.apps.svgbrowser.resources.GUI";
+
+ // The actions names.
+ public static final String ABOUT_ACTION = "AboutAction";
+ public static final String OPEN_ACTION = "OpenAction";
+ public static final String OPEN_LOCATION_ACTION = "OpenLocationAction";
+ public static final String NEW_WINDOW_ACTION = "NewWindowAction";
+ public static final String RELOAD_ACTION = "ReloadAction";
+ public static final String SAVE_AS_ACTION = "SaveAsAction";
+ public static final String BACK_ACTION = "BackAction";
+ public static final String FORWARD_ACTION = "ForwardAction";
+ public static final String FULL_SCREEN_ACTION = "FullScreenAction";
+ public static final String PRINT_ACTION = "PrintAction";
+ public static final String EXPORT_AS_JPG_ACTION = "ExportAsJPGAction";
+ public static final String EXPORT_AS_PNG_ACTION = "ExportAsPNGAction";
+ public static final String EXPORT_AS_TIFF_ACTION = "ExportAsTIFFAction";
+ public static final String PREFERENCES_ACTION = "PreferencesAction";
+ public static final String CLOSE_ACTION = "CloseAction";
+ public static final String VIEW_SOURCE_ACTION = "ViewSourceAction";
+ public static final String EXIT_ACTION = "ExitAction";
+ public static final String RESET_TRANSFORM_ACTION = "ResetTransformAction";
+ public static final String ZOOM_IN_ACTION = "ZoomInAction";
+ public static final String ZOOM_OUT_ACTION = "ZoomOutAction";
+ public static final String PREVIOUS_TRANSFORM_ACTION = "PreviousTransformAction";
+ public static final String NEXT_TRANSFORM_ACTION = "NextTransformAction";
+ public static final String USE_STYLESHEET_ACTION = "UseStylesheetAction";
+ public static final String PLAY_ACTION = "PlayAction";
+ public static final String PAUSE_ACTION = "PauseAction";
+ public static final String STOP_ACTION = "StopAction";
+ public static final String MONITOR_ACTION = "MonitorAction";
+ public static final String DOM_VIEWER_ACTION = "DOMViewerAction";
+ public static final String SET_TRANSFORM_ACTION = "SetTransformAction";
+ public static final String FIND_DIALOG_ACTION = "FindDialogAction";
+ public static final String THUMBNAIL_DIALOG_ACTION = "ThumbnailDialogAction";
+ public static final String FLUSH_ACTION = "FlushAction";
+ public static final String TOGGLE_DEBUGGER_ACTION = "ToggleDebuggerAction";
+
+ /**
+ * The cursor indicating that an operation is pending.
+ */
+ public static final Cursor WAIT_CURSOR =
+ new Cursor(Cursor.WAIT_CURSOR);
+
+ /**
+ * The default cursor.
+ */
+ public static final Cursor DEFAULT_CURSOR =
+ new Cursor(Cursor.DEFAULT_CURSOR);
+
+ /**
+ * Name for the os-name property
+ */
+ public static final String PROPERTY_OS_NAME
+ = Resources.getString("JSVGViewerFrame.property.os.name");
+
+ /**
+ * Name for the os.name default
+ */
+ public static final String PROPERTY_OS_NAME_DEFAULT
+ = Resources.getString("JSVGViewerFrame.property.os.name.default");
+
+ /**
+ * Name for the os.name property prefix we are looking
+ * for in OpenAction to work around JFileChooser bug
+ */
+ public static final String PROPERTY_OS_WINDOWS_PREFIX
+ = Resources.getString("JSVGViewerFrame.property.os.windows.prefix");
+
+ /**
+ * Resource string name for the Open dialog.
+ */
+ protected static final String OPEN_TITLE = "Open.title";
+
+ /**
+ * The input handlers
+ */
+ protected static Vector handlers;
+
+ /**
+ * The default input handler
+ */
+ protected static SquiggleInputHandler defaultHandler = new SVGInputHandler();
+
+ /**
+ * The resource bundle
+ */
+ protected static ResourceBundle bundle;
+
+ /**
+ * The resource manager
+ */
+ protected static ResourceManager resources;
+ static {
+ bundle = ResourceBundle.getBundle(RESOURCES, Locale.getDefault());
+ resources = new ResourceManager(bundle);
+ }
+
+ /**
+ * The current application.
+ */
+ protected Application application;
+
+ /**
+ * The JSVGCanvas.
+ */
+ protected Canvas svgCanvas;
+
+ /**
+ * An extension of JSVGCanvas that exposes the Rhino interpreter.
+ */
+ protected class Canvas extends JSVGCanvas {
+
+ /**
+ * Creates a new Canvas.
+ */
+ public Canvas(SVGUserAgent ua, boolean eventsEnabled,
+ boolean selectableText) {
+ super(ua, eventsEnabled, selectableText);
+ }
+
+ /**
+ * Returns the Rhino interpreter for this canvas.
+ */
+ public Object getRhinoInterpreter() {
+ if (bridgeContext == null) {
+ return null;
+ }
+ return bridgeContext.getInterpreter("text/ecmascript");
+ }
+
+ /**
+ * JSVGViewerFrame DOMViewerController implementation.
+ */
+ protected class JSVGViewerDOMViewerController
+ // extends CanvasDOMViewerController {
+ implements DOMViewerController {
+
+ public boolean canEdit() {
+ return getUpdateManager() != null;
+ }
+
+ public ElementOverlayManager createSelectionManager() {
+ if (canEdit()) {
+ return new ElementOverlayManager(Canvas.this);
+ }
+ return null;
+ }
+
+ public org.w3c.dom.Document getDocument() {
+ return Canvas.this.svgDocument;
+ }
+
+ public void performUpdate(Runnable r) {
+ if (canEdit()) {
+ getUpdateManager().getUpdateRunnableQueue().invokeLater(r);
+ } else {
+ r.run();
+ }
+ }
+
+ public void removeSelectionOverlay(Overlay selectionOverlay) {
+ getOverlays().remove(selectionOverlay);
+ }
+
+ public void selectNode(Node node) {
+ DOMViewerAction dViewerAction =
+ (DOMViewerAction) getAction(DOM_VIEWER_ACTION);
+ dViewerAction.openDOMViewer();
+ domViewer.selectNode(node);
+ }
+ }
+ }
+
+ /**
+ * The panel where the svgCanvas is displayed
+ */
+ protected JPanel svgCanvasPanel;
+
+ /**
+ * A window used for full screen display
+ */
+ protected JWindow window;
+
+ /**
+ * The memory monitor frame.
+ */
+ protected static JFrame memoryMonitorFrame;
+
+ /**
+ * The current path.
+ */
+ protected File currentPath = new File("");
+
+ /**
+ * The current export path.
+ */
+ protected File currentSavePath = new File("");
+
+ /**
+ * The back action
+ */
+ protected BackAction backAction = new BackAction();
+
+ /**
+ * The forward action
+ */
+ protected ForwardAction forwardAction = new ForwardAction();
+
+ /**
+ * The play action
+ */
+ protected PlayAction playAction = new PlayAction();
+
+ /**
+ * The pause action
+ */
+ protected PauseAction pauseAction = new PauseAction();
+
+ /**
+ * The stop action
+ */
+ protected StopAction stopAction = new StopAction();
+
+ /**
+ * The previous transform action
+ */
+ protected PreviousTransformAction previousTransformAction =
+ new PreviousTransformAction();
+
+ /**
+ * The next transform action
+ */
+ protected NextTransformAction nextTransformAction =
+ new NextTransformAction();
+
+ /**
+ * The use (author) stylesheet action
+ */
+ protected UseStylesheetAction useStylesheetAction =
+ new UseStylesheetAction();
+
+ /**
+ * The debug flag.
+ */
+ protected boolean debug;
+
+ /**
+ * The auto adjust flag.
+ */
+ protected boolean autoAdjust = true;
+
+ /**
+ * Whether the update manager was stopped.
+ */
+ protected boolean managerStopped;
+
+ /**
+ * The SVG user agent.
+ */
+ protected SVGUserAgent userAgent = new UserAgent();
+
+ /**
+ * The current document.
+ */
+ protected SVGDocument svgDocument;
+
+ /**
+ * The URI chooser.
+ */
+ protected URIChooser uriChooser;
+
+ /**
+ * The DOM viewer.
+ */
+ protected DOMViewer domViewer;
+
+ /**
+ * The Find dialog.
+ */
+ protected FindDialog findDialog;
+
+ /**
+ * The Find dialog.
+ */
+ protected ThumbnailDialog thumbnailDialog;
+
+ /**
+ * The transform dialog
+ */
+ protected JAffineTransformChooser.Dialog transformDialog;
+
+ /**
+ * The location bar.
+ */
+ protected LocationBar locationBar;
+
+ /**
+ * The status bar.
+ */
+ protected StatusBar statusBar;
+
+ /**
+ * The initial frame title.
+ */
+ protected String title;
+
+ /**
+ * The local history.
+ */
+ protected LocalHistory localHistory;
+
+ /**
+ * The transform history.
+ */
+ protected TransformHistory transformHistory = new TransformHistory();
+
+ /**
+ * The alternate style-sheet title.
+ */
+ protected String alternateStyleSheet;
+
+ /**
+ * The debugger object.
+ */
+ protected Debugger debugger;
+
+ /**
+ * Creates a new SVG viewer frame.
+ */
+ public JSVGViewerFrame(Application app) {
+ application = app;
+
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ application.closeJSVGViewerFrame(JSVGViewerFrame.this);
+ }
+ });
+
+ //
+ // Set the frame's maximum size so that content
+ // bigger than the screen does not cause the creation
+ // of unnecessary large images.
+ //
+ svgCanvas = new Canvas(userAgent, true, true) {
+ Dimension screenSize;
+
+ {
+ screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ setMaximumSize(screenSize);
+ }
+
+ public Dimension getPreferredSize(){
+ Dimension s = super.getPreferredSize();
+ if (s.width > screenSize.width) s.width =screenSize.width;
+ if (s.height > screenSize.height) s.height = screenSize.height;
+ return s;
+ }
+
+
+ /**
+ * This method is called when the component knows the desired
+ * size of the window (based on width/height of outermost SVG
+ * element). We override it to immediately pack this frame.
+ */
+ public void setMySize(Dimension d) {
+ setPreferredSize(d);
+ invalidate();
+ if (JSVGViewerFrame.this.autoAdjust) {
+ Platform.unmaximize(JSVGViewerFrame.this);
+ JSVGViewerFrame.this.pack();
+ }
+ }
+
+ public void setDisableInteractions(boolean b) {
+ super.setDisableInteractions(b);
+
+ // Disable/Enable all our different ways to adjust the
+ // rendering transform (menus, toolbar, thumbnail, keyboard).
+
+ ((Action)listeners.get(SET_TRANSFORM_ACTION)) .setEnabled(!b);
+
+ if (thumbnailDialog != null)
+ thumbnailDialog.setInteractionEnabled(!b);
+ }
+ };
+
+ javax.swing.ActionMap map = svgCanvas.getActionMap();
+ map.put(FULL_SCREEN_ACTION, new FullScreenAction());
+ javax.swing.InputMap imap = svgCanvas.getInputMap(JComponent.WHEN_FOCUSED);
+ KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0);
+ imap.put(key, FULL_SCREEN_ACTION);
+
+ svgCanvas.setDoubleBufferedRendering(true);
+
+ listeners.put(ABOUT_ACTION, new AboutAction());
+ listeners.put(OPEN_ACTION, new OpenAction());
+ listeners.put(OPEN_LOCATION_ACTION, new OpenLocationAction());
+ listeners.put(NEW_WINDOW_ACTION, new NewWindowAction());
+ listeners.put(RELOAD_ACTION, new ReloadAction());
+ listeners.put(SAVE_AS_ACTION, new SaveAsAction());
+ listeners.put(BACK_ACTION, backAction);
+ listeners.put(FORWARD_ACTION, forwardAction);
+ listeners.put(PRINT_ACTION, new PrintAction());
+ listeners.put(EXPORT_AS_JPG_ACTION, new ExportAsJPGAction());
+ listeners.put(EXPORT_AS_PNG_ACTION, new ExportAsPNGAction());
+ listeners.put(EXPORT_AS_TIFF_ACTION, new ExportAsTIFFAction());
+ listeners.put(PREFERENCES_ACTION, new PreferencesAction());
+ listeners.put(CLOSE_ACTION, new CloseAction());
+ listeners.put(EXIT_ACTION, application.createExitAction(this));
+ listeners.put(VIEW_SOURCE_ACTION, new ViewSourceAction());
+
+ javax.swing.ActionMap cMap = svgCanvas.getActionMap();
+ listeners.put(RESET_TRANSFORM_ACTION,
+ cMap.get(JSVGCanvas.RESET_TRANSFORM_ACTION));
+ listeners.put(ZOOM_IN_ACTION,
+ cMap.get(JSVGCanvas.ZOOM_IN_ACTION));
+ listeners.put(ZOOM_OUT_ACTION,
+ cMap.get(JSVGCanvas.ZOOM_OUT_ACTION));
+
+ listeners.put(PREVIOUS_TRANSFORM_ACTION, previousTransformAction);
+ key = KeyStroke.getKeyStroke(KeyEvent.VK_K, KeyEvent.CTRL_MASK);
+ imap.put(key, previousTransformAction);
+
+ listeners.put(NEXT_TRANSFORM_ACTION, nextTransformAction);
+ key = KeyStroke.getKeyStroke(KeyEvent.VK_L, KeyEvent.CTRL_MASK);
+ imap.put(key, nextTransformAction);
+
+ listeners.put(USE_STYLESHEET_ACTION, useStylesheetAction);
+ listeners.put(PLAY_ACTION, playAction);
+ listeners.put(PAUSE_ACTION, pauseAction);
+ listeners.put(STOP_ACTION, stopAction);
+ listeners.put(MONITOR_ACTION, new MonitorAction());
+ listeners.put(DOM_VIEWER_ACTION, new DOMViewerAction());
+ listeners.put(SET_TRANSFORM_ACTION, new SetTransformAction());
+ listeners.put(FIND_DIALOG_ACTION, new FindDialogAction());
+ listeners.put(THUMBNAIL_DIALOG_ACTION, new ThumbnailDialogAction());
+ listeners.put(FLUSH_ACTION, new FlushAction());
+ listeners.put(TOGGLE_DEBUGGER_ACTION, new ToggleDebuggerAction());
+
+ JPanel p = null;
+ try {
+ // Create the menu
+ MenuFactory mf = new MenuFactory(bundle, this);
+ JMenuBar mb =
+ mf.createJMenuBar("MenuBar", application.getUISpecialization());
+ setJMenuBar(mb);
+
+ localHistory = new LocalHistory(mb, this);
+
+ String[] uri = application.getVisitedURIs();
+ for (int i=0; iNodePickerPanel
that it is being hidden.
+ */
+ boolean panelHiding() {
+ return !isDirty || promptForChanges();
+ }
+
+ /**
+ * Gets the current working mode.
+ *
+ * @return the mode
+ */
+ private int getMode() {
+ return mode;
+ }
+
+ /**
+ * Enters the view mode.
+ */
+ public void enterViewMode() {
+ if (mode != VIEW_MODE) {
+ mode = VIEW_MODE;
+ // Disable appropriate buttons
+ getApplyButton().setEnabled(false);
+ getResetButton().setEnabled(false);
+ // Enable the remove and add buttons
+ getRemoveButton().setEnabled(true);
+ getAddButton().setEnabled(true);
+ // Update the isWellFormed label
+ String isWellFormedLabelVal =
+ resources.getString("IsWellFormedLabel.wellFormed");
+ isWellFormedLabel.setText(isWellFormedLabelVal);
+ }
+ }
+
+ /**
+ * Enters the edit mode.
+ */
+ public void enterEditMode() {
+ if (mode != EDIT_MODE) {
+ mode = EDIT_MODE;
+ clonedElement = (Element) previewElement.cloneNode(true);
+
+ // Enable appropriate buttons
+ getApplyButton().setEnabled(true);
+ getResetButton().setEnabled(true);
+ }
+ }
+
+ /**
+ * Enters the add new element mode.
+ *
+ * @param newElement
+ * The element to be added
+ * @param parent
+ * The parent node of the element to be added
+ */
+ public void enterAddNewElementMode(Element newElement, Node parent) {
+ if (mode != ADD_NEW_ELEMENT) {
+ mode = ADD_NEW_ELEMENT;
+ previewElement = newElement;
+ clonedElement = (Element) newElement.cloneNode(true);
+ parentElement = parent;
+ // Update the appropriate areas
+ updateNodeXmlArea(newElement);
+ // Enable appropriate buttons
+ getApplyButton().setEnabled(true);
+ getResetButton().setEnabled(true);
+// // Request focus
+// getSvgInputPanel().getNodeXmlArea().requestFocusInWindow();
+ }
+ }
+
+ /**
+ * Updates the panel when DOM Mutation event occures.
+ */
+ public void updateOnDocumentChange(String mutationEventType, Node targetNode) {
+ if (mode == VIEW_MODE) {
+ if (this.isShowing() &&
+ shouldUpdate(mutationEventType,
+ targetNode,
+ getPreviewElement())) {
+ setPreviewElement(getPreviewElement());
+ }
+ }
+ }
+
+ /**
+ * If the panel should update its components after dom mutation event.
+ * Checks whether any node that is the child node of the node currently
+ * being previewed has changed. If true, updates the xml text area of this
+ * NodePicker. In case of DOMAttrModiefied mutation event, the additional
+ * condition is added - to check whether the attributes of an element that
+ * is being previewed are changed. If true, the xml text area is refreshed.
+ *
+ * @return True if should update
+ */
+ private boolean shouldUpdate(String mutationEventType, Node affectedNode,
+ Node currentNode) {
+ if (mutationEventType.equals("DOMNodeInserted")) {
+ if (DOMUtilities.isAncestorOf(currentNode, affectedNode)) {
+ return true;
+ }
+ } else if (mutationEventType.equals("DOMNodeRemoved")) {
+ if (DOMUtilities.isAncestorOf(currentNode, affectedNode)) {
+ return true;
+ }
+ } else if (mutationEventType.equals("DOMAttrModified")) {
+ if (DOMUtilities.isAncestorOf(currentNode, affectedNode)
+ || currentNode == affectedNode) {
+ return true;
+ }
+ } else if (mutationEventType.equals("DOMCharDataModified")) {
+ if (DOMUtilities.isAncestorOf(currentNode, affectedNode)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Parses the given xml and return parsed document's root element.
+ * Used to check whether the given xml is well formed.
+ *
+ * @param xmlString
+ * Xml as a String
+ * @return Element
+ */
+ private Element parseXml(String xmlString) {
+ Document doc = null;
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ try {
+ javax.xml.parsers.DocumentBuilder parser = factory
+ .newDocumentBuilder();
+ parser.setErrorHandler(new ErrorHandler() {
+ public void error(SAXParseException exception)
+ throws SAXException {
+ }
+
+ public void fatalError(SAXParseException exception)
+ throws SAXException {
+ }
+
+ public void warning(SAXParseException exception)
+ throws SAXException {
+ }
+ });
+ doc = parser.parse(new InputSource(new StringReader(xmlString)));
+ } catch (ParserConfigurationException e1) {
+ } catch (SAXException e1) {
+ } catch (IOException e1) {
+ }
+ if (doc != null) {
+ return doc.getDocumentElement();
+ }
+ return null;
+ }
+
+ /**
+ * Sets the node picker components to be editable / uneditable.
+ *
+ * @param editable
+ * Whether to enable or disable edit
+ */
+ public void setEditable(boolean editable) {
+ getSvgInputPanel().getNodeXmlArea().setEditable(editable);
+ getResetButton().setEnabled(editable);
+ getApplyButton().setEnabled(editable);
+ getAddButton().setEnabled(editable);
+ getRemoveButton().setEnabled(editable);
+ attributesTable.setEnabled(editable);
+ }
+
+ /**
+ * Checks whether the given component is a part component of the this node
+ * picker.
+ *
+ * @param component
+ * The given component
+ * @return True if the given component is a part of the this NodePicker
+ */
+ private boolean isANodePickerComponent(Component component) {
+ return SwingUtilities.getAncestorOfClass(NodePickerPanel.class,
+ component) != null;
+ }
+
+ /**
+ * Shows a dialog to save changes.
+ */
+ public boolean promptForChanges() {
+ // If the xml is well formed
+ if (getApplyButton().isEnabled() && isElementModified()) {
+ String confirmString = resources.getString("ConfirmDialog.message");
+ int option = JOptionPane.showConfirmDialog(getSvgInputPanel(),
+ confirmString);
+ if (option == JOptionPane.YES_OPTION) {
+ getApplyButton().doClick();
+ } else if (option == JOptionPane.CANCEL_OPTION) {
+ return false;
+ } else {
+ getResetButton().doClick();
+ }
+ } else {
+ getResetButton().doClick();
+ }
+ isDirty = false;
+ return true;
+ }
+
+ /**
+ * Whether the element being edit is changed.
+ *
+ * @return True if the element being edit is changed
+ */
+ private boolean isElementModified() {
+ if (getMode() == EDIT_MODE) {
+ return !DOMUtilities.getXML(previewElement).equals
+ (getSvgInputPanel().getNodeXmlArea().getText());
+ } else if (getMode() == ADD_NEW_ELEMENT) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Manages the edits on focus events.
+ */
+ protected class NodePickerEditListener extends FocusAdapter {
+
+ public void focusGained(FocusEvent e) {
+ if (getMode() == VIEW_MODE) {
+ enterEditMode();
+ }
+ setEditable(controller.isEditable()
+ && controller.canEdit(previewElement));
+ isDirty = isElementModified();
+ }
+
+ // XXX Java 1.3 does not have getOppositeComponent()
+ /*public void focusLost(FocusEvent e) {
+ // Prompts the user to save changes that he made for an element,
+ // when the NodePicker loses focus
+ if (!isANodePickerComponent(e.getOppositeComponent())
+ && !e.isTemporary() && isDirty) {
+ promptForChanges();
+ }
+ }*/
+ }
+
+ /**
+ * Listens for the changes in the xml text area and updates this node picker
+ * panel if needed.
+ */
+ protected class XMLAreaListener implements DocumentListener {
+ public void changedUpdate(DocumentEvent e) {
+ isDirty = isElementModified();
+ }
+
+ public void insertUpdate(DocumentEvent e) {
+ updateNodePicker(e);
+ isDirty = isElementModified();
+ }
+
+ public void removeUpdate(DocumentEvent e) {
+ updateNodePicker(e);
+ isDirty = isElementModified();
+ }
+
+ /**
+ * Updates the node picker panel after document changes.
+ *
+ * @param e
+ * The document event
+ */
+ private void updateNodePicker(DocumentEvent e) {
+ if (getMode() == EDIT_MODE) {
+ updateViewAfterSvgInput
+ (parseXml(svgInputPanel.getNodeXmlArea().getText()),
+ clonedElement);
+ } else if (getMode() == ADD_NEW_ELEMENT) {
+ updateViewAfterSvgInput
+ (parseXml(svgInputPanel.getNodeXmlArea().getText()),
+ previewElement);
+ }
+ }
+ }
+
+ /**
+ * Listens for the changes in the table and updates this node picker panel
+ * if needed.
+ */
+ protected class AttributesTableModelListener implements TableModelListener {
+ public void tableChanged(TableModelEvent e) {
+ if (e.getType() == TableModelEvent.UPDATE && shouldProcessUpdate) {
+ updateNodePicker(e);
+ }
+ }
+
+ /**
+ * Updates the node picker panel after document changes.
+ *
+ * @param e
+ * The document event
+ */
+ private void updateNodePicker(TableModelEvent e) {
+ if (getMode() == EDIT_MODE) {
+ updateElementAttributes
+ (clonedElement, (AttributesTableModel) (e.getSource()));
+ updateNodeXmlArea(clonedElement);
+ } else if (getMode() == ADD_NEW_ELEMENT) {
+ updateElementAttributes
+ (previewElement, (AttributesTableModel) (e.getSource()));
+ updateNodeXmlArea(previewElement);
+ }
+ }
+ }
+
+ /**
+ * The action associated with the 'Apply' button.
+ */
+ protected class ApplyButtonAction extends AbstractAction {
+ public void actionPerformed(ActionEvent e) {
+ isDirty = false;
+ String xmlAreaText = getResults();
+ if (getMode() == EDIT_MODE) {
+ fireUpdateElement
+ (new NodePickerEvent
+ (NodePickerPanel.this,
+ xmlAreaText,
+ previewElement,
+ NodePickerEvent.EDIT_ELEMENT));
+ } else if (getMode() == ADD_NEW_ELEMENT) {
+ fireAddNewElement
+ (new NodePickerEvent
+ (NodePickerPanel.this,
+ xmlAreaText,
+ parentElement,
+ NodePickerEvent.ADD_NEW_ELEMENT));
+ }
+ enterViewMode();
+ }
+ }
+
+ /**
+ * The action associated with the 'Reset' button.
+ */
+ protected class ResetButtonAction extends AbstractAction {
+ public void actionPerformed(ActionEvent e) {
+ isDirty = false;
+ setPreviewElement(getPreviewElement());
+ }
+ }
+
+ /**
+ * The action associated with the 'Add' button.
+ */
+ protected class AddButtonAction extends AbstractAction {
+ public void actionPerformed(ActionEvent e) {
+ if (getMode() == VIEW_MODE) {
+ enterEditMode();
+ }
+ DefaultTableModel model =
+ (DefaultTableModel) attributesTable.getModel();
+ shouldProcessUpdate = false;
+ model.addRow((Vector) null);
+ shouldProcessUpdate = true;
+ }
+ }
+
+ /**
+ * The action associated with the 'Remove' button.
+ */
+ protected class RemoveButtonAction extends AbstractAction {
+ public void actionPerformed(ActionEvent e) {
+ if (getMode() == VIEW_MODE) {
+ enterEditMode();
+ }
+ // Find the contextElement
+ Element contextElement = clonedElement;
+ if (getMode() == ADD_NEW_ELEMENT) {
+ contextElement = previewElement;
+ }
+ DefaultTableModel model =
+ (DefaultTableModel) attributesTable.getModel();
+ int[] selectedRows = attributesTable.getSelectedRows();
+ for (int i = 0; i < selectedRows.length; i++) {
+ String attrName = (String) model.getValueAt(selectedRows[i], 0);
+ if (attrName != null) {
+ String prefix = DOMUtilities.getPrefix(attrName);
+ String localName = DOMUtilities.getLocalName(attrName);
+ String namespaceURI = getNamespaceURI(prefix);
+ contextElement.removeAttributeNS(namespaceURI, localName);
+ }
+ }
+ shouldProcessUpdate = false;
+ updateAttributesTable(contextElement);
+ shouldProcessUpdate = true;
+ updateNodeXmlArea(contextElement);
+ }
+ }
+
+ /**
+ * Returns the action associated with the given string or null on error
+ *
+ * @param key
+ * the key mapped with the action to get
+ * @throws MissingListenerException
+ * if the action is not found
+ */
+ public Action getAction(String key) throws MissingListenerException {
+ return (Action) listeners.get(key);
+ }
+
+ /**
+ * The attributesTable model.
+ */
+ public static class AttributesTableModel extends DefaultTableModel {
+ public AttributesTableModel(int rowCount, int columnCount) {
+ super(rowCount, columnCount);
+ }
+
+ public String getColumnName(int column) {
+ if (column == 0) {
+ return resources.getString("AttributesTable.column1");
+ } else {
+ return resources.getString("AttributesTable.column2");
+ }
+ }
+
+ /**
+ * Gets the value of the attribute with the given attribute name.
+ *
+ * @param attrName
+ * The given attribute name
+ */
+ public Object getValueForName(Object attrName) {
+ for (int i = 0; i < getRowCount(); i++) {
+ if (getValueAt(i, 0) != null
+ && getValueAt(i, 0).equals(attrName)) {
+ return getValueAt(i, 1);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Gets the name of the attribute with the table row.
+ */
+ public Object getAttrNameAt(int i) {
+ return getValueAt(i, 0);
+ }
+
+ /**
+ * Gets the value of the attribute with the table row.
+ */
+ public Object getAttrValueAt(int i) {
+ return getValueAt(i, 1);
+ }
+
+ /**
+ * Gets the first row where the given attribute name appears.
+ * @param attrName The given attribute name
+ */
+ public int getRow(Object attrName) {
+ for (int i = 0; i < getRowCount(); i++) {
+ if (getValueAt(i, 0) != null
+ && getValueAt(i, 0).equals(attrName)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+ }
+
+ // Custom events support
+ /**
+ * Fires the updateElement event.
+ *
+ * @param event
+ * The associated NodePickerEvent event
+ */
+ public void fireUpdateElement(NodePickerEvent event) {
+ Object[] listeners = eventListeners.getListenerList();
+
+ int length = listeners.length;
+ for (int i = 0; i < length; i += 2) {
+ if (listeners[i] == NodePickerListener.class) {
+ ((NodePickerListener) listeners[i + 1])
+ .updateElement(event);
+ }
+ }
+ }
+
+ /**
+ * Fires the AddNewElement event.
+ *
+ * @param event
+ * The associated NodePickerEvent event
+ */
+ public void fireAddNewElement(NodePickerEvent event) {
+ Object[] listeners = eventListeners.getListenerList();
+ int length = listeners.length;
+ for (int i = 0; i < length; i += 2) {
+ if (listeners[i] == NodePickerListener.class) {
+ ((NodePickerListener) listeners[i + 1])
+ .addNewElement(event);
+ }
+ }
+ }
+
+ /**
+ * Adds the listener to the listener list.
+ *
+ * @param listener
+ * The listener to add
+ */
+ public void addListener(NodePickerListener listener) {
+ eventListeners.add(NodePickerListener.class, listener);
+ }
+
+ /**
+ * Event to pass to listener.
+ */
+ public static class NodePickerEvent extends EventObject {
+
+ // The event types
+ public static final int EDIT_ELEMENT = 1;
+
+ public static final int ADD_NEW_ELEMENT = 2;
+
+ /**
+ * The type of this event.
+ */
+ private int type;
+
+ /**
+ * The string that is to be parsed.
+ */
+ private String result;
+
+ /**
+ * The context node associated with this event.
+ */
+ private Node contextNode;
+
+ /**
+ * Creates the NodePickerEvent.
+ *
+ * @param source
+ * The NodePicker that initiated the event
+ * @param result
+ * the NodePicker result
+ * @param contextNode
+ * the associated context node
+ */
+ public NodePickerEvent(Object source, String result, Node contextNode,
+ int type) {
+ super(source);
+ this.result = result;
+ this.contextNode = contextNode;
+ }
+
+ /**
+ * Gets the NodePickerPanel result.
+ *
+ * @return the result
+ */
+ public String getResult() {
+ return result;
+ }
+
+ /**
+ * Gets the context node.
+ * 'EDIT_ELEMENT' event type - the context node is the original element
+ * being previewed.
+ * 'ADD_NEW_ELEMENT' event type - the context node is the parent node of
+ * the element being added
+ *
+ * @return the context node
+ */
+ public Node getContextNode() {
+ return contextNode;
+ }
+
+ /**
+ * Gets the type of this event.
+ *
+ * @return the type
+ */
+ public int getType() {
+ return type;
+ }
+ }
+
+ /**
+ * Node picker listener.
+ */
+ public static interface NodePickerListener extends EventListener {
+ /**
+ * Updates the element from the data contained in the NodePickerEvent.
+ */
+ void updateElement(NodePickerEvent event);
+
+ /**
+ * Adds the element from the data contained in the NodePickerEvent.
+ */
+ void addNewElement(NodePickerEvent event);
+ }
+
+ /**
+ * The adapter for the NodePicker listener.
+ */
+ public static class NodePickerAdapter implements NodePickerListener {
+
+ public void addNewElement(NodePickerEvent event) {
+ }
+
+ public void updateElement(NodePickerEvent event) {
+ }
+ }
+
+ /**
+ * The panel to view and edit the elements xml representation.
+ */
+ protected class SVGInputPanel extends JPanel {
+
+ /**
+ * The text area.
+ */
+ protected XMLTextEditor nodeXmlArea;
+
+ /**
+ * Constructor.
+ */
+ public SVGInputPanel() {
+ super(new BorderLayout());
+ add(new JScrollPane(getNodeXmlArea()));
+ }
+
+ /**
+ * Gets the nodeXmlArea.
+ *
+ * @return the nodeXmlArea
+ */
+ protected XMLTextEditor getNodeXmlArea() {
+ if (nodeXmlArea == null) {
+ // Create syntax-highlighted text area
+ nodeXmlArea = new XMLTextEditor();
+ nodeXmlArea.setEditable(true);
+ }
+ return nodeXmlArea;
+ }
+ }
+
+ /**
+ * Dialog for choosing element name.
+ */
+ public static class NameEditorDialog extends JDialog implements ActionMap {
+
+ /**
+ * The return value if 'OK' is chosen.
+ */
+ public static final int OK_OPTION = 0;
+
+ /**
+ * The return value if 'Cancel' is chosen.
+ */
+ public static final int CANCEL_OPTION = 1;
+
+ /**
+ * The resource file name.
+ */
+ protected static final String RESOURCES =
+ "org.apache.batik.apps.svgbrowser.resources.NameEditorDialogMessages";
+
+ /**
+ * The resource bundle.
+ */
+ protected static ResourceBundle bundle;
+
+ /**
+ * The resource manager.
+ */
+ protected static ResourceManager resources;
+ static {
+ bundle = ResourceBundle.getBundle(RESOURCES, Locale.getDefault());
+ resources = new ResourceManager(bundle);
+ }
+
+ /**
+ * The Dialog results.
+ */
+ protected int returnCode;
+
+ /**
+ * The Dialog main panel.
+ */
+ protected JPanel mainPanel;
+
+ /**
+ * The Button factory.
+ */
+ protected ButtonFactory buttonFactory;
+
+ /**
+ * The node name label.
+ */
+ protected JLabel nodeNameLabel;
+
+ /**
+ * The node name field.
+ */
+ protected JTextField nodeNameField;
+
+ /**
+ * The OK button.
+ */
+ protected JButton okButton;
+
+ /**
+ * The Cancel button.
+ */
+ protected JButton cancelButton;
+
+ /**
+ * The map that contains the listeners
+ */
+ protected Map listeners = new HashMap(10);
+
+ /**
+ * Constructor.
+ *
+ * @param frame
+ * Parent frame
+ */
+ public NameEditorDialog(Frame frame) {
+ super(frame, true);
+ this.setResizable(false);
+ this.setModal(true);
+ initialize();
+ }
+
+ /**
+ * Initializes the dialog.
+ */
+ protected void initialize() {
+ this.setSize(resources.getInteger("Dialog.width"),
+ resources.getInteger("Dialog.height"));
+ this.setTitle(resources.getString("Dialog.title"));
+ addButtonActions();
+ this.setContentPane(getMainPanel());
+ }
+
+ /**
+ * Gets buttonFactory.
+ */
+ protected ButtonFactory getButtonFactory() {
+ if (buttonFactory == null) {
+ buttonFactory = new ButtonFactory(bundle, this);
+ }
+ return buttonFactory;
+ }
+
+ /**
+ * Adds button actions.
+ */
+ protected void addButtonActions() {
+ listeners.put("OKButtonAction", new OKButtonAction());
+ listeners.put("CancelButtonAction", new CancelButtonAction());
+ }
+
+ /**
+ * Shows the dialog.
+ *
+ * @return OK_OPTION or CANCEL_OPTION.
+ */
+ public int showDialog() {
+ setVisible(true);
+ return returnCode;
+ }
+
+ /**
+ * Gets the Ok button.
+ *
+ * @return the okButton
+ */
+ protected JButton getOkButton() {
+ if (okButton == null) {
+ okButton = getButtonFactory().createJButton("OKButton");
+ this.getRootPane().setDefaultButton(okButton);
+ }
+ return okButton;
+ }
+
+ /**
+ * Gets the Cancel button.
+ *
+ * @return the cancelButton
+ */
+ protected JButton getCancelButton() {
+ if (cancelButton == null) {
+ cancelButton = getButtonFactory().createJButton("CancelButton");
+ }
+ return cancelButton;
+ }
+
+ /**
+ * Gets dialog's main panel.
+ *
+ * @return the mainPanel
+ */
+ protected JPanel getMainPanel() {
+ if (mainPanel == null) {
+ mainPanel = new JPanel(new GridBagLayout());
+
+ GridBagConstraints gridBag = new GridBagConstraints();
+ gridBag.gridx = 1;
+ gridBag.gridy = 1;
+ gridBag.fill = GridBagConstraints.NONE;
+ gridBag.insets = new Insets(5, 5, 5, 5);
+ mainPanel.add(getNodeNameLabel(), gridBag);
+
+ gridBag.gridx = 2;
+ gridBag.weightx = 1.0;
+ gridBag.weighty = 1.0;
+ gridBag.fill = GridBagConstraints.HORIZONTAL;
+ gridBag.anchor = GridBagConstraints.CENTER;
+ mainPanel.add(getNodeNameField(), gridBag);
+
+ gridBag.gridx = 1;
+ gridBag.gridy = 2;
+ gridBag.weightx = 0;
+ gridBag.weighty = 0;
+ gridBag.anchor = GridBagConstraints.EAST;
+ gridBag.fill = GridBagConstraints.HORIZONTAL;
+ mainPanel.add(getOkButton(), gridBag);
+
+ gridBag.gridx = 2;
+ gridBag.gridy = 2;
+ gridBag.anchor = GridBagConstraints.EAST;
+ mainPanel.add(getCancelButton(), gridBag);
+ }
+ return mainPanel;
+ }
+
+ /**
+ * Gets the node name label.
+ *
+ * @return the nodeNameLabel
+ */
+ public JLabel getNodeNameLabel() {
+ if (nodeNameLabel == null) {
+ nodeNameLabel = new JLabel();
+ nodeNameLabel.setText(resources.getString("Dialog.label"));
+ }
+ return nodeNameLabel;
+ }
+
+ /**
+ * Gets the text field for node name.
+ *
+ * @return the nodeNameField
+ */
+ protected JTextField getNodeNameField() {
+ if (nodeNameField == null) {
+ nodeNameField = new JTextField();
+ }
+ return nodeNameField;
+ }
+
+ /**
+ * Gets the dialog results.
+ *
+ * @return the element name
+ */
+ public String getResults() {
+ return nodeNameField.getText();
+ }
+
+ /**
+ * The action associated with the 'OK' button of Attribute Adder Dialog
+ */
+ protected class OKButtonAction extends AbstractAction {
+ public void actionPerformed(ActionEvent e) {
+ returnCode = OK_OPTION;
+ dispose();
+ }
+ }
+
+ /**
+ * The action associated with the 'Cancel' button of Attribute Adder
+ * Dialog
+ */
+ protected class CancelButtonAction extends AbstractAction {
+ public void actionPerformed(ActionEvent e) {
+ returnCode = CANCEL_OPTION;
+ dispose();
+ }
+ }
+
+ /**
+ * Returns the action associated with the given string or null on error
+ *
+ * @param key
+ * the key mapped with the action to get
+ * @throws MissingListenerException
+ * if the action is not found
+ */
+ public Action getAction(String key) throws MissingListenerException {
+ return (Action) listeners.get(key);
+ }
+ }
+}
+
Index: 3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/NodeTemplates.java
===================================================================
RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/NodeTemplates.java,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ 3rdParty_sources/batik/org/apache/batik/apps/svgbrowser/NodeTemplates.java 8 Apr 2013 10:55:07 -0000 1.1
@@ -0,0 +1,1368 @@
+/*
+
+ 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.batik.apps.svgbrowser;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.batik.util.SVGConstants;
+import org.w3c.dom.Node;
+
+/**
+ * Provides basic xml representation and description for most commonly used
+ * nodes.
+ *
+ * @version $Id: NodeTemplates.java,v 1.1 2013/04/08 10:55:07 marcin Exp $
+ */
+public class NodeTemplates {
+
+ // Node template descriptions provide basic information on node properties,
+ // such as: xml represenation (suffix "Value"), element name
+ // (suffix "Name"), element type (suffix "Type"), element category
+ // (suffix "Category"), element description (suffix "Description").
+ // Base node name on which these suffixes are appended is read from the
+ // class members ending with "MemberName".
+
+ // Example:
+ // public static String rectMemberName = "rectElement";
+ // Other class members that describe this node should be declared as:
+ // rectElementValue = "...", rectElementType = "...", rectElementName =
+ // "...", rectElementCategory = "..." and rectElementDescription = "..."
+
+ // Suffixes
+ public static final String VALUE = "Value";
+
+ public static final String NAME = "Name";
+
+ public static final String TYPE = "Type";
+
+ public static final String DESCRIPTION = "Description";
+
+ public static final String CATEGORY = "Category";
+
+ // Categories
+ public static final String BASIC_SHAPES = "Basic Shapes";
+
+ public static final String LINKING = "Linking";
+
+ public static final String TEXT = "Text";
+
+ public static final String ANIMATION = "Animation";
+
+ public static final String CLIP_MASK_COMPOSITE = "Clipping, Masking and Compositing";
+
+ public static final String COLOR = "Color";
+
+ public static final String INTERACTIVITY = "Interactivity";
+
+ public static final String FONTS = "Fonts";
+
+ public static final String DOCUMENT_STRUCTURE = "Document Structure";
+
+ public static final String FILTER_EFFECTS = "Filter Effects";
+
+ public static final String EXTENSIBILITY = "Extensibility";
+
+ public static final String GRADIENTS_AND_PATTERNS = "Gradients and Patterns";
+
+ public static final String PAINTING = "Painting: Filling, Stroking and Marker Symbols";
+
+ public static final String METADATA = "Metadata";
+
+ public static final String PATHS = "Paths";
+
+ public static final String SCRIPTING = "Scripting";
+
+ public static final String STYLING = "Styling";
+
+ // Maps
+ /**
+ * Map with node template wrappers.
+ */
+ private Map nodeTemplatesMap = new HashMap();
+
+ /**
+ * List with all node categories.
+ */
+ private ArrayList categoriesList = new ArrayList();
+
+
+ // Rect element
+ public static String rectMemberName = "rectElement";
+
+ public static String rectElementValue = "Properties
table to the output stream in a format suitable
+ * for loading into a Properties
table using the
+ * load
method.
+ * The stream is written using the ISO 8859-1 character encoding.
+ */
+ public synchronized void store(OutputStream os, String header)
+ throws IOException {
+ BufferedWriter w;
+ w = new BufferedWriter(new OutputStreamWriter(os, PREFERENCE_ENCODING));
+
+ Map m = new HashMap();
+ enumerate(m);
+
+ w.write("+ * svgpp is a pretty-printer for SVG source files. + * + * @author Stephane Hillion + * @version $Id: Main.java,v 1.1 2013/04/08 10:55:58 marcin Exp $ + */ +public class Main { + + /** + * The application main method. + * @param args The command-line arguments. + */ + public static void main(String[] args) { + new Main(args).run(); + } + + /** + * The default resource bundle base name. + */ + public static final String BUNDLE_CLASSNAME = + "org.apache.batik.apps.svgpp.resources.Messages"; + + /** + * The localizable support. + */ + protected static LocalizableSupport localizableSupport = + new LocalizableSupport(BUNDLE_CLASSNAME, Main.class.getClassLoader()); + + /** + * The arguments. + */ + protected String[] arguments; + + /** + * The current index. + */ + protected int index; + + /** + * The option handlers. + */ + protected Map handlers = new HashMap(); + { + handlers.put("-doctype", new DoctypeHandler()); + handlers.put("-doc-width", new DocWidthHandler()); + handlers.put("-newline", new NewlineHandler()); + handlers.put("-public-id", new PublicIdHandler()); + handlers.put("-no-format", new NoFormatHandler()); + handlers.put("-system-id", new SystemIdHandler()); + handlers.put("-tab-width", new TabWidthHandler()); + handlers.put("-xml-decl", new XMLDeclHandler()); + } + + /** + * The transcoder. + */ + protected Transcoder transcoder = new SVGTranscoder(); + + /** + * Initializes the application. + * @param args The command-line arguments. + */ + public Main(String[] args) { + arguments = args; + } + + /** + * Runs the pretty printer. + */ + public void run() { + if (arguments.length == 0) { + printUsage(); + return; + } + try { + for (;;) { + OptionHandler oh = (OptionHandler)handlers.get(arguments[index]); + if (oh == null) { + break; + } + oh.handleOption(); + } + TranscoderInput in; + in = new TranscoderInput(new java.io.FileReader(arguments[index++])); + TranscoderOutput out; + if (index < arguments.length) { + out = new TranscoderOutput(new java.io.FileWriter(arguments[index])); + } else { + out = new TranscoderOutput(new java.io.OutputStreamWriter(System.out)); + } + transcoder.transcode(in, out); + } catch (Exception e) { + e.printStackTrace(); + printUsage(); + } + } + + /** + * Prints the command usage. + */ + protected void printUsage() { + printHeader(); + System.out.println(localizableSupport.formatMessage("syntax", null)); + System.out.println(); + System.out.println(localizableSupport.formatMessage("options", null)); + Iterator it = handlers.keySet().iterator(); + while (it.hasNext()) { + String s = (String)it.next(); + System.out.println(((OptionHandler)handlers.get(s)).getDescription()); + } + } + + /** + * Prints the command header. + */ + protected void printHeader() { + System.out.println(localizableSupport.formatMessage("header", null)); + } + + /** + * This interface represents an option handler. + */ + protected interface OptionHandler { + /** + * Handles the current option. + */ + void handleOption(); + + /** + * Returns the option description. + */ + String getDescription(); + } + + /** + * To handle the '-doctype' option. + */ + protected class DoctypeHandler implements OptionHandler { + protected final Map values = new HashMap(6); + { + values.put("remove", SVGTranscoder.VALUE_DOCTYPE_REMOVE); + values.put("change", SVGTranscoder.VALUE_DOCTYPE_CHANGE); + } + public void handleOption() { + index++; + if (index >= arguments.length) { + throw new IllegalArgumentException(); + } + Object val = values.get(arguments[index++]); + if (val == null) { + throw new IllegalArgumentException(); + } + transcoder.addTranscodingHint(SVGTranscoder.KEY_DOCTYPE, val); + } + + public String getDescription() { + return localizableSupport.formatMessage("doctype.description", null); + } + } + + /** + * To handle the '-newline' option. + */ + protected class NewlineHandler implements OptionHandler { + protected final Map values = new HashMap(6); + { + values.put("cr", SVGTranscoder.VALUE_NEWLINE_CR); + values.put("cr-lf", SVGTranscoder.VALUE_NEWLINE_CR_LF); + values.put("lf", SVGTranscoder.VALUE_NEWLINE_LF); + } + public void handleOption() { + index++; + if (index >= arguments.length) { + throw new IllegalArgumentException(); + } + Object val = values.get(arguments[index++]); + if (val == null) { + throw new IllegalArgumentException(); + } + transcoder.addTranscodingHint(SVGTranscoder.KEY_NEWLINE, val); + } + + public String getDescription() { + return localizableSupport.formatMessage("newline.description", null); + } + } + + /** + * To handle the '-no-format' option. + */ + protected class NoFormatHandler implements OptionHandler { + public void handleOption() { + index++; + transcoder.addTranscodingHint(SVGTranscoder.KEY_FORMAT, Boolean.FALSE); + } + + public String getDescription() { + return localizableSupport.formatMessage("no-format.description", null); + } + } + + /** + * To handle the '-public-id' option. + */ + protected class PublicIdHandler implements OptionHandler { + public void handleOption() { + index++; + if (index >= arguments.length) { + throw new IllegalArgumentException(); + } + String s = arguments[index++]; + transcoder.addTranscodingHint(SVGTranscoder.KEY_PUBLIC_ID, s); + } + + public String getDescription() { + return localizableSupport.formatMessage("public-id.description", null); + } + } + + /** + * To handle the '-system-id' option. + */ + protected class SystemIdHandler implements OptionHandler { + public void handleOption() { + index++; + if (index >= arguments.length) { + throw new IllegalArgumentException(); + } + String s = arguments[index++]; + transcoder.addTranscodingHint(SVGTranscoder.KEY_SYSTEM_ID, s); + } + + public String getDescription() { + return localizableSupport.formatMessage("system-id.description", null); + } + } + + /** + * To handle the '-xml-decl' option. + */ + protected class XMLDeclHandler implements OptionHandler { + public void handleOption() { + index++; + if (index >= arguments.length) { + throw new IllegalArgumentException(); + } + String s = arguments[index++]; + transcoder.addTranscodingHint(SVGTranscoder.KEY_XML_DECLARATION, s); + } + + public String getDescription() { + return localizableSupport.formatMessage("xml-decl.description", null); + } + } + + /** + * To handle the '-tab-width' option. + */ + protected class TabWidthHandler implements OptionHandler { + public void handleOption() { + index++; + if (index >= arguments.length) { + throw new IllegalArgumentException(); + } + transcoder.addTranscodingHint(SVGTranscoder.KEY_TABULATION_WIDTH, + new Integer(arguments[index++])); + } + + public String getDescription() { + return localizableSupport.formatMessage("tab-width.description", null); + } + } + + /** + * To handle the '-doc-width' option. + */ + protected class DocWidthHandler implements OptionHandler { + public void handleOption() { + index++; + if (index >= arguments.length) { + throw new IllegalArgumentException(); + } + transcoder.addTranscodingHint(SVGTranscoder.KEY_DOCUMENT_WIDTH, + new Integer(arguments[index++])); + } + + public String getDescription() { + return localizableSupport.formatMessage("doc-width.description", null); + } + } +} Index: 3rdParty_sources/batik/org/apache/batik/apps/ttf2svg/Main.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/apps/ttf2svg/Main.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/batik/org/apache/batik/apps/ttf2svg/Main.java 8 Apr 2013 10:55:59 -0000 1.1 @@ -0,0 +1,37 @@ +/* + + 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.batik.apps.ttf2svg; + +import org.apache.batik.svggen.font.SVGFont; + +/** + * This test runs the True Type Font to SVG Font converter, the + * tool that allows some characters from a font to be converted + * to the SVG Font format. + * + * @author Vincent Hardy + * @version $Id: Main.java,v 1.1 2013/04/08 10:55:59 marcin Exp $ + */ +public class Main { + public static void main(String[] args){ + SVGFont.main(args); + } +} + Index: 3rdParty_sources/batik/org/apache/batik/bridge/AbstractGraphicsNodeBridge.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/batik/org/apache/batik/bridge/AbstractGraphicsNodeBridge.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ 3rdParty_sources/batik/org/apache/batik/bridge/AbstractGraphicsNodeBridge.java 8 Apr 2013 10:55:05 -0000 1.1 @@ -0,0 +1,585 @@ +/* + + 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.batik.bridge; + +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.lang.ref.SoftReference; + +import org.apache.batik.css.engine.CSSEngineEvent; +import org.apache.batik.css.engine.SVGCSSEngine; +import org.apache.batik.dom.events.AbstractEvent; +import org.apache.batik.dom.svg.AbstractSVGTransformList; +import org.apache.batik.dom.svg.AnimatedLiveAttributeValue; +import org.apache.batik.dom.svg.LiveAttributeException; +import org.apache.batik.dom.svg.SVGContext; +import org.apache.batik.dom.svg.SVGMotionAnimatableElement; +import org.apache.batik.dom.svg.SVGOMElement; +import org.apache.batik.dom.svg.SVGOMAnimatedTransformList; +import org.apache.batik.ext.awt.geom.SegmentList; +import org.apache.batik.gvt.CanvasGraphicsNode; +import org.apache.batik.gvt.CompositeGraphicsNode; +import org.apache.batik.gvt.GraphicsNode; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.events.DocumentEvent; +import org.w3c.dom.events.EventTarget; +import org.w3c.dom.events.MutationEvent; +import org.w3c.dom.svg.SVGFitToViewBox; +import org.w3c.dom.svg.SVGTransformable; + +/** + * The base bridge class for SVG graphics node. By default, the namespace URI is + * the SVG namespace. Override the getNamespaceURI if you want to add + * custom GraphicsNode with a custom namespace. + * + *
This class handles various attributes that are defined on most + * of the SVG graphic elements as described in the SVG + * specification.
+ * + *+ * {0} - URL of document containing script. + * {1} - Element tag + * {2} - line number of element. + *+ */ + public static final String INLINE_SCRIPT_DESCRIPTION + = "BaseScriptingEnvironment.constant.inline.script.description"; + + /** + * Constant used to describe inline scripts. + *
+ * {0} - URL of document containing script. + * {1} - Event attribute name + * {2} - line number of element. + *+ */ + public static final String EVENT_SCRIPT_DESCRIPTION + = "BaseScriptingEnvironment.constant.event.script.description"; + + /** + * Tells whether the given SVG document is dynamic. + */ + public static boolean isDynamicDocument(BridgeContext ctx, Document doc) { + Element elt = doc.getDocumentElement(); + if ((elt != null) && + SVGConstants.SVG_NAMESPACE_URI.equals(elt.getNamespaceURI())) { + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONABORT_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONERROR_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONRESIZE_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONUNLOAD_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONSCROLL_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONZOOM_ATTRIBUTE).length() > 0) { + return true; + } + return isDynamicElement(ctx, doc.getDocumentElement()); + } + return false; + } + + public static boolean isDynamicElement(BridgeContext ctx, Element elt) { + List bridgeExtensions = ctx.getBridgeExtensions(elt.getOwnerDocument()); + return isDynamicElement(elt, ctx, bridgeExtensions); + } + + /** + * Tells whether the given SVG element is dynamic. + */ + public static boolean isDynamicElement + (Element elt, BridgeContext ctx, List bridgeExtensions) { + Iterator i = bridgeExtensions.iterator(); + while (i.hasNext()) { + BridgeExtension bridgeExtension = (BridgeExtension) i.next(); + if (bridgeExtension.isDynamicElement(elt)) { + return true; + } + } + if (SVGConstants.SVG_NAMESPACE_URI.equals(elt.getNamespaceURI())) { + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONKEYUP_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONKEYDOWN_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONKEYPRESS_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONLOAD_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONERROR_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONACTIVATE_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONCLICK_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONFOCUSIN_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONFOCUSOUT_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONMOUSEDOWN_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONMOUSEMOVE_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONMOUSEOUT_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONMOUSEOVER_ATTRIBUTE).length() > 0) { + return true; + } + if (elt.getAttributeNS + (null, SVGConstants.SVG_ONMOUSEUP_ATTRIBUTE).length() > 0) { + return true; + } + } + + for (Node n = elt.getFirstChild(); + n != null; + n = n.getNextSibling()) { + if (n.getNodeType() == Node.ELEMENT_NODE) { + if (isDynamicElement(ctx, (Element)n)) { + return true; + } + } + } + return false; + } + + + protected static final String EVENT_NAME = "event"; + protected static final String ALTERNATE_EVENT_NAME = "evt"; + + /** + * The 'application/ecmascript' MIME type. + */ + protected static final String APPLICATION_ECMASCRIPT = + "application/ecmascript"; + + /** + * The bridge context. + */ + protected BridgeContext bridgeContext; + + /** + * The user-agent. + */ + protected UserAgent userAgent; + + /** + * The document to manage. + */ + protected Document document; + + /** + * The URL of the document ot manage + */ + protected ParsedURL docPURL; + + protected Set languages = new HashSet(); + + /** + * The default Interpreter for the document + */ + protected Interpreter interpreter; + + /** + * Creates a new BaseScriptingEnvironment. + * @param ctx the bridge context + */ + public BaseScriptingEnvironment(BridgeContext ctx) { + bridgeContext = ctx; + document = ctx.getDocument(); + docPURL = new ParsedURL(((SVGDocument)document).getURL()); + userAgent = bridgeContext.getUserAgent(); + } + + /** + * Creates a new Window object. + */ + public org.apache.batik.script.Window createWindow + (Interpreter interp, String lang) { + return new Window(interp, lang); + } + + /** + * Creates a new Window object. + */ + public org.apache.batik.script.Window createWindow() { + return createWindow(null, null); + } + + /** + * Returns the default Interpreter for this document. + */ + public Interpreter getInterpreter() { + if (interpreter != null) + return interpreter; + + SVGSVGElement root = (SVGSVGElement)document.getDocumentElement(); + String lang = root.getContentScriptType(); + return getInterpreter(lang); + } + + public Interpreter getInterpreter(String lang) { + interpreter = bridgeContext.getInterpreter(lang); + if (interpreter == null) { + if (languages.contains(lang)) { + // Already issued warning so just return null; + return null; + } + + // So we know we have processed this interpreter. + languages.add(lang); + return null; + } + + if (!languages.contains(lang)) { + languages.add(lang); + initializeEnvironment(interpreter, lang); + } + return interpreter; + } + + /** + * Initializes the environment of the given interpreter. + */ + public void initializeEnvironment(Interpreter interp, String lang) { + interp.bindObject("window", createWindow(interp, lang)); + } + + /** + * Loads the scripts contained in the