Added: xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedNumber.java URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedNumber.java?rev=1647590&view=auto ============================================================================== --- xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedNumber.java (added) +++ xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedNumber.java Tue Dec 23 15:10:45 2014 @@ -0,0 +1,215 @@ +/* + + 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.dom; + +import org.apache.batik.anim.values.AnimatableNumberValue; +import org.apache.batik.anim.values.AnimatableValue; + +import org.w3c.dom.Attr; +import org.w3c.dom.DOMException; +import org.w3c.dom.svg.SVGAnimatedNumber; + +/** + * This class implements the {@link SVGAnimatedNumber} interface. + * + * @author <a href="mailto:steph...@hillion.org">Stephane Hillion</a> + * @version $Id$ + */ +public class SVGOMAnimatedNumber + extends AbstractSVGAnimatedValue + implements SVGAnimatedNumber { + + /** + * The default value. + */ + protected float defaultValue; + + /** + * Whether the parsed number can be a percentage. + */ + protected boolean allowPercentage; + + /** + * Whether the base value is valid. + */ + protected boolean valid; + + /** + * The current base value. + */ + protected float baseVal; + + /** + * The current animated value. + */ + protected float animVal; + + /** + * Whether the value is changing. + */ + protected boolean changing; + + /** + * Creates a new SVGOMAnimatedNumber. + * @param elt The associated element. + * @param ns The attribute's namespace URI. + * @param ln The attribute's local name. + * @param val The default value, if the attribute is not specified. + */ + public SVGOMAnimatedNumber(AbstractElement elt, + String ns, + String ln, + float val) { + this(elt, ns, ln, val, false); + } + + /** + * Creates a new SVGOMAnimatedNumber possibly parsing it as a percentage. + * @param elt The associated element. + * @param ns The attribute's namespace URI. + * @param ln The attribute's local name. + * @param val The default value, if the attribute is not specified. + * @param allowPercentage Allows number specified as a percentage. + */ + public SVGOMAnimatedNumber(AbstractElement elt, + String ns, + String ln, + float val, + boolean allowPercentage) { + super(elt, ns, ln); + defaultValue = val; + this.allowPercentage = allowPercentage; + } + + /** + * <b>DOM</b>: Implements {@link SVGAnimatedNumber#getBaseVal()}. + */ + public float getBaseVal() { + if (!valid) { + update(); + } + return baseVal; + } + + /** + * Updates the base value from the attribute. + */ + protected void update() { + Attr attr = element.getAttributeNodeNS(namespaceURI, localName); + if (attr == null) { + baseVal = defaultValue; + } else { + String v = attr.getValue(); + int len = v.length(); + if (allowPercentage && len > 1 && v.charAt(len - 1) == '%') { + baseVal = .01f * Float.parseFloat(v.substring(0, len - 1)); + } else { + baseVal = Float.parseFloat(v); + } + } + valid = true; + } + + /** + * <b>DOM</b>: Implements {@link SVGAnimatedNumber#setBaseVal(float)}. + */ + public void setBaseVal(float baseVal) throws DOMException { + try { + this.baseVal = baseVal; + valid = true; + changing = true; + element.setAttributeNS(namespaceURI, localName, + String.valueOf(baseVal)); + } finally { + changing = false; + } + } + + /** + * <b>DOM</b>: Implements {@link SVGAnimatedNumber#getAnimVal()}. + */ + public float getAnimVal() { + if (hasAnimVal) { + return animVal; + } + if (!valid) { + update(); + } + return baseVal; + } + + /** + * Returns the base value of the attribute as an {@link AnimatableValue}. + */ + public AnimatableValue getUnderlyingValue(AnimationTarget target) { + return new AnimatableNumberValue(target, getBaseVal()); + } + + /** + * Updates the animated value with the given {@link AnimatableValue}. + */ + protected void updateAnimatedValue(AnimatableValue val) { + if (val == null) { + hasAnimVal = false; + } else { + hasAnimVal = true; + this.animVal = ((AnimatableNumberValue) val).getValue(); + } + fireAnimatedAttributeListeners(); + } + + /** + * Called when an Attr node has been added. + */ + public void attrAdded(Attr node, String newv) { + if (!changing) { + valid = false; + } + fireBaseAttributeListeners(); + if (!hasAnimVal) { + fireAnimatedAttributeListeners(); + } + } + + /** + * Called when an Attr node has been modified. + */ + public void attrModified(Attr node, String oldv, String newv) { + if (!changing) { + valid = false; + } + fireBaseAttributeListeners(); + if (!hasAnimVal) { + fireAnimatedAttributeListeners(); + } + } + + /** + * Called when an Attr node has been removed. + */ + public void attrRemoved(Attr node, String oldv) { + if (!changing) { + valid = false; + } + fireBaseAttributeListeners(); + if (!hasAnimVal) { + fireAnimatedAttributeListeners(); + } + } +}
Added: xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedNumberList.java URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedNumberList.java?rev=1647590&view=auto ============================================================================== --- xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedNumberList.java (added) +++ xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedNumberList.java Tue Dec 23 15:10:45 2014 @@ -0,0 +1,514 @@ +/* + + 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.dom; + +import java.util.ArrayList; +import java.util.Iterator; + +import org.apache.batik.anim.values.AnimatableNumberListValue; +import org.apache.batik.anim.values.AnimatableValue; +import org.apache.batik.dom.svg.AbstractSVGList; +import org.apache.batik.dom.svg.AbstractSVGNumberList; +import org.apache.batik.dom.svg.ListBuilder; +import org.apache.batik.dom.svg.LiveAttributeException; +import org.apache.batik.dom.svg.SVGItem; +import org.apache.batik.dom.svg.SVGNumberItem; + +import org.apache.batik.parser.ParseException; + +import org.w3c.dom.Attr; +import org.w3c.dom.DOMException; +import org.w3c.dom.Element; +import org.w3c.dom.svg.SVGAnimatedNumberList; +import org.w3c.dom.svg.SVGException; +import org.w3c.dom.svg.SVGNumber; +import org.w3c.dom.svg.SVGNumberList; + +/** + * This class is the implementation of the {@link SVGAnimatedNumberList} + * interface. + * + * @author <a href="mailto:to...@kiyut.com">Tonny Kohar</a> + * @version $Id$ + */ +public class SVGOMAnimatedNumberList + extends AbstractSVGAnimatedValue + implements SVGAnimatedNumberList { + + /** + * The base value. + */ + protected BaseSVGNumberList baseVal; + + /** + * The animated value. + */ + protected AnimSVGNumberList animVal; + + /** + * Whether the list is changing. + */ + protected boolean changing; + + /** + * Default value for the number list. + */ + protected String defaultValue; + + /** + * Whether empty length lists are allowed. + */ + protected boolean emptyAllowed; + + /** + * Creates a new SVGOMAnimatedNumberList. + * @param elt The associated element. + * @param ns The attribute's namespace URI. + * @param ln The attribute's local name. + * @param defaultValue The default value if the attribute is not specified. + * @param emptyAllowed Whether an empty number list is allowed. + */ + public SVGOMAnimatedNumberList(AbstractElement elt, + String ns, + String ln, + String defaultValue, + boolean emptyAllowed) { + super(elt, ns, ln); + this.defaultValue = defaultValue; + this.emptyAllowed = emptyAllowed; + } + + /** + * <b>DOM</b>: Implements {@link SVGAnimatedNumberList#getBaseVal()}. + */ + public SVGNumberList getBaseVal() { + if (baseVal == null) { + baseVal = new BaseSVGNumberList(); + } + return baseVal; + } + + /** + * <b>DOM</b>: Implements {@link SVGAnimatedNumberList#getAnimVal()}. + */ + public SVGNumberList getAnimVal() { + if (animVal == null) { + animVal = new AnimSVGNumberList(); + } + return animVal; + } + + /** + * Throws an exception if the number list value is malformed. + */ + public void check() { + if (!hasAnimVal) { + if (baseVal == null) { + baseVal = new BaseSVGNumberList(); + } + baseVal.revalidate(); + if (baseVal.missing) { + throw new LiveAttributeException + (element, localName, + LiveAttributeException.ERR_ATTRIBUTE_MISSING, null); + } + if (baseVal.malformed) { + throw new LiveAttributeException + (element, localName, + LiveAttributeException.ERR_ATTRIBUTE_MALFORMED, + baseVal.getValueAsString()); + } + } + } + + /** + * Returns the base value of the attribute as an {@link AnimatableValue}. + */ + public AnimatableValue getUnderlyingValue(AnimationTarget target) { + SVGNumberList nl = getBaseVal(); + int n = nl.getNumberOfItems(); + float[] numbers = new float[n]; + for (int i = 0; i < n; i++) { + numbers[i] = nl.getItem(n).getValue(); + } + return new AnimatableNumberListValue(target, numbers); + } + + /** + * Updates the animated value with the given {@link AnimatableValue}. + */ + protected void updateAnimatedValue(AnimatableValue val) { + if (val == null) { + hasAnimVal = false; + } else { + hasAnimVal = true; + AnimatableNumberListValue animNumList = + (AnimatableNumberListValue) val; + if (animVal == null) { + animVal = new AnimSVGNumberList(); + } + animVal.setAnimatedValue(animNumList.getNumbers()); + } + fireAnimatedAttributeListeners(); + } + + /** + * Called when an Attr node has been added. + */ + public void attrAdded(Attr node, String newv) { + if (!changing && baseVal != null) { + baseVal.invalidate(); + } + fireBaseAttributeListeners(); + if (!hasAnimVal) { + fireAnimatedAttributeListeners(); + } + } + + /** + * Called when an Attr node has been modified. + */ + public void attrModified(Attr node, String oldv, String newv) { + if (!changing && baseVal != null) { + baseVal.invalidate(); + } + fireBaseAttributeListeners(); + if (!hasAnimVal) { + fireAnimatedAttributeListeners(); + } + } + + /** + * Called when an Attr node has been removed. + */ + public void attrRemoved(Attr node, String oldv) { + if (!changing && baseVal != null) { + baseVal.invalidate(); + } + fireBaseAttributeListeners(); + if (!hasAnimVal) { + fireAnimatedAttributeListeners(); + } + } + + /** + * {@link SVGNumberList} implementation for the base number list value. + */ + public class BaseSVGNumberList extends AbstractSVGNumberList { + + /** + * Whether the value is missing. + */ + protected boolean missing; + + /** + * Whether the value is malformed. + */ + protected boolean malformed; + + /** + * Create a DOMException. + */ + protected DOMException createDOMException(short type, String key, + Object[] args) { + return element.createDOMException(type, key, args); + } + + /** + * Create a SVGException. + */ + protected SVGException createSVGException(short type, String key, + Object[] args) { + + return ((SVGOMElement)element).createSVGException(type, key, args); + } + + /** + * Returns the element owning the attribute with which this length + * list is associated. + */ + protected Element getElement() { + return element; + } + + /** + * Returns the value of the DOM attribute containing the number list. + */ + protected String getValueAsString() { + Attr attr = element.getAttributeNodeNS(namespaceURI, localName); + if (attr == null) { + return defaultValue; + } + return attr.getValue(); + } + + /** + * Sets the DOM attribute value containing the number list. + */ + protected void setAttributeValue(String value) { + try { + changing = true; + element.setAttributeNS(namespaceURI, localName, value); + } finally { + changing = false; + } + } + + /** + * Resets the value of the associated attribute. + */ + protected void resetAttribute() { + super.resetAttribute(); + missing = false; + malformed = false; + } + + /** + * Appends the string representation of the given {@link SVGItem} to + * the DOM attribute. This is called in response to an append to + * the list. + */ + protected void resetAttribute(SVGItem item) { + super.resetAttribute(item); + missing = false; + malformed = false; + } + + /** + * Initializes the list, if needed. + */ + protected void revalidate() { + if (valid) { + return; + } + + valid = true; + missing = false; + malformed = false; + + String s = getValueAsString(); + boolean isEmpty = s != null && s.length() == 0; + if (s == null || isEmpty && !emptyAllowed) { + missing = true; + return; + } + if (isEmpty) { + itemList = new ArrayList(1); + } else { + try { + ListBuilder builder = new ListBuilder(this); + + doParse(s, builder); + + if (builder.getList() != null) { + clear(itemList); + } + itemList = builder.getList(); + } catch (ParseException e) { + itemList = new ArrayList(1); + valid = true; + malformed = true; + } + } + } + } + + /** + * {@link SVGNumberList} implementation for the animated number list value. + */ + protected class AnimSVGNumberList extends AbstractSVGNumberList { + + /** + * Creates a new AnimSVGNumberList. + */ + public AnimSVGNumberList() { + itemList = new ArrayList(1); + } + + /** + * Create a DOMException. + */ + protected DOMException createDOMException(short type, String key, + Object[] args) { + return element.createDOMException(type, key, args); + } + + /** + * Create a SVGException. + */ + protected SVGException createSVGException(short type, String key, + Object[] args) { + + return ((SVGOMElement)element).createSVGException(type, key, args); + } + + /** + * Returns the element owning this SVGNumberList. + */ + protected Element getElement() { + return element; + } + + /** + * <b>DOM</b>: Implements {@link SVGNumberList#getNumberOfItems()}. + */ + public int getNumberOfItems() { + if (hasAnimVal) { + return super.getNumberOfItems(); + } + return getBaseVal().getNumberOfItems(); + } + + /** + * <b>DOM</b>: Implements {@link SVGNumberList#getItem(int)}. + */ + public SVGNumber getItem(int index) throws DOMException { + if (hasAnimVal) { + return super.getItem(index); + } + return getBaseVal().getItem(index); + } + + /** + * Returns the value of the DOM attribute containing the point list. + */ + protected String getValueAsString() { + if (itemList.size() == 0) { + return ""; + } + StringBuffer sb = new StringBuffer( itemList.size() * 8 ); + Iterator i = itemList.iterator(); + if (i.hasNext()) { + sb.append(((SVGItem) i.next()).getValueAsString()); + } + while (i.hasNext()) { + sb.append(getItemSeparator()); + sb.append(((SVGItem) i.next()).getValueAsString()); + } + return sb.toString(); + } + + /** + * Sets the DOM attribute value containing the point list. + */ + protected void setAttributeValue(String value) { + } + + /** + * <b>DOM</b>: Implements {@link SVGNumberList#clear()}. + */ + public void clear() throws DOMException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.number.list", null); + } + + /** + * <b>DOM</b>: Implements {@link SVGNumberList#initialize(SVGNumber)}. + */ + public SVGNumber initialize(SVGNumber newItem) + throws DOMException, SVGException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.number.list", null); + } + + /** + * <b>DOM</b>: Implements {@link + * SVGNumberList#insertItemBefore(SVGNumber, int)}. + */ + public SVGNumber insertItemBefore(SVGNumber newItem, int index) + throws DOMException, SVGException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.number.list", null); + } + + /** + * <b>DOM</b>: Implements {@link + * SVGNumberList#replaceItem(SVGNumber, int)}. + */ + public SVGNumber replaceItem(SVGNumber newItem, int index) + throws DOMException, SVGException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.number.list", null); + } + + /** + * <b>DOM</b>: Implements {@link SVGNumberList#removeItem(int)}. + */ + public SVGNumber removeItem(int index) throws DOMException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.number.list", null); + } + + /** + * <b>DOM</b>: Implements {@link SVGNumberList#appendItem(SVGNumber)}. + */ + public SVGNumber appendItem(SVGNumber newItem) throws DOMException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.number.list", null); + } + + /** + * Sets the animated value. + */ + protected void setAnimatedValue(float[] values) { + int size = itemList.size(); + int i = 0; + while (i < size && i < values.length) { + SVGNumberItem n = (SVGNumberItem) itemList.get(i); + n.setValue(values[i]); + i++; + } + while (i < values.length) { + appendItemImpl(new SVGNumberItem(values[i])); + i++; + } + while (size > values.length) { + removeItemImpl(--size); + } + } + + /** + * Resets the value of the associated attribute. Does nothing, since + * there is no attribute for an animated value. + */ + protected void resetAttribute() { + } + + /** + * Resets the value of the associated attribute. Does nothing, since + * there is no attribute for an animated value. + */ + protected void resetAttribute(SVGItem item) { + } + + /** + * Initializes the list, if needed. Does nothing, since there is no + * attribute to read the list from. + */ + protected void revalidate() { + valid = true; + } + } +} Added: xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedPathData.java URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedPathData.java?rev=1647590&view=auto ============================================================================== --- xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedPathData.java (added) +++ xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedPathData.java Tue Dec 23 15:10:45 2014 @@ -0,0 +1,815 @@ +/* + + 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.dom; + +import java.util.ArrayList; +import java.util.Iterator; + +import org.apache.batik.anim.values.AnimatablePathDataValue; +import org.apache.batik.anim.values.AnimatableValue; +import org.apache.batik.dom.svg.AbstractSVGList; +import org.apache.batik.dom.svg.AbstractSVGNormPathSegList; +import org.apache.batik.dom.svg.AbstractSVGPathSegList; +import org.apache.batik.dom.svg.ListBuilder; +import org.apache.batik.dom.svg.LiveAttributeException; +import org.apache.batik.dom.svg.SVGAnimatedPathDataSupport; +import org.apache.batik.dom.svg.SVGItem; +import org.apache.batik.dom.svg.AbstractSVGPathSegList.SVGPathSegArcItem; +import org.apache.batik.dom.svg.AbstractSVGPathSegList.SVGPathSegCurvetoCubicItem; +import org.apache.batik.dom.svg.AbstractSVGPathSegList.SVGPathSegCurvetoCubicSmoothItem; +import org.apache.batik.dom.svg.AbstractSVGPathSegList.SVGPathSegCurvetoQuadraticItem; +import org.apache.batik.dom.svg.AbstractSVGPathSegList.SVGPathSegCurvetoQuadraticSmoothItem; +import org.apache.batik.dom.svg.AbstractSVGPathSegList.SVGPathSegLinetoHorizontalItem; +import org.apache.batik.dom.svg.AbstractSVGPathSegList.SVGPathSegLinetoVerticalItem; +import org.apache.batik.dom.svg.AbstractSVGPathSegList.SVGPathSegMovetoLinetoItem; +import org.apache.batik.dom.svg.SVGPathSegItem; + +import org.apache.batik.parser.ParseException; +import org.apache.batik.parser.PathArrayProducer; + +import org.w3c.dom.Attr; +import org.w3c.dom.DOMException; +import org.w3c.dom.svg.SVGAnimatedPathData; +import org.w3c.dom.svg.SVGException; +import org.w3c.dom.svg.SVGPathSeg; +import org.w3c.dom.svg.SVGPathSegList; + +/** + * This class is the implementation of the {@link SVGAnimatedPathData} + * interface. + * + * @author <a href="mailto:nicolas.sochel...@bitflash.com">Nicolas Socheleau</a> + * @author <a href="mailto:andr...@world-affair.com">Andres Toussaint</a> + * @version $Id$ + */ +public class SVGOMAnimatedPathData + extends AbstractSVGAnimatedValue + implements SVGAnimatedPathData { + + /** + * Whether the list is changing. + */ + protected boolean changing; + + /** + * The base path data value. + */ + protected BaseSVGPathSegList pathSegs; + + /** + * The normalized base path data value. + */ + protected NormalizedBaseSVGPathSegList normalizedPathSegs; + + /** + * The animated path data value. + */ + protected AnimSVGPathSegList animPathSegs; + +// /** +// * The normalized animated base path data value. +// */ +// protected NormalizedAnimSVGPathSegList normalizedPathSegs; + + /** + * Default value for the 'd' attribute. + */ + protected String defaultValue; + + /** + * Creates a new SVGOMAnimatedPathData. + * @param elt The associated element. + * @param ns The attribute's namespace URI. + * @param ln The attribute's local name. + * @param defaultValue The default value if the attribute is not specified. + */ + public SVGOMAnimatedPathData(AbstractElement elt, + String ns, + String ln, + String defaultValue) { + super(elt, ns, ln); + this.defaultValue = defaultValue; + } + + /** + * <b>DOM</b>: Implements {@link + * SVGAnimatedPathData#getAnimatedNormalizedPathSegList()}. + */ + public SVGPathSegList getAnimatedNormalizedPathSegList() { + throw new UnsupportedOperationException + ("SVGAnimatedPathData.getAnimatedNormalizedPathSegList is not implemented"); // XXX + } + + /** + * <b>DOM</b>: Implements {@link + * SVGAnimatedPathData#getAnimatedPathSegList()}. + */ + public SVGPathSegList getAnimatedPathSegList() { + if (animPathSegs == null) { + animPathSegs = new AnimSVGPathSegList(); + } + return animPathSegs; + } + + /** + * <b>DOM</b>: Implements {@link + * SVGAnimatedPathData#getNormalizedPathSegList()}. + * <p> + * Returns the SVGPathSegList mapping the normalized static 'd' attribute + * of the element. + * </p> + * <p> + * A normalized path is composed only of absolute moveto, lineto and + * cubicto path segments (M, L and C). Using this subset, the path + * description can be represented with fewer segment types. Be aware that + * the normalized 'd' attribute will be a larger String that the original. + * </p> + * <p> + * Relative values are transformed into absolute, quadratic curves are + * promoted to cubic curves, and arcs are converted into one or more + * cubic curves (one per quadrant). + * </p> + * <p> + * Modifications to the normalized SVGPathSegList will result + * in substituting the original path with a set of normalized path + * segments. + * </p> + * @return a path segment list containing the normalized version of the path. + */ + public SVGPathSegList getNormalizedPathSegList() { + if (normalizedPathSegs == null) { + normalizedPathSegs = new NormalizedBaseSVGPathSegList(); + } + return normalizedPathSegs; + } + + /** + * <b>DOM</b>: Implements {@link + * SVGAnimatedPathData#getPathSegList()}. + */ + public SVGPathSegList getPathSegList() { + if (pathSegs == null) { + pathSegs = new BaseSVGPathSegList(); + } + return pathSegs; + } + + /** + * Throws an exception if the path data is malformed. + */ + public void check() { + if (!hasAnimVal) { + if (pathSegs == null) { + pathSegs = new BaseSVGPathSegList(); + } + pathSegs.revalidate(); + if (pathSegs.missing) { + throw new LiveAttributeException + (element, localName, + LiveAttributeException.ERR_ATTRIBUTE_MISSING, null); + } + if (pathSegs.malformed) { + throw new LiveAttributeException + (element, localName, + LiveAttributeException.ERR_ATTRIBUTE_MALFORMED, + pathSegs.getValueAsString()); + } + } + } + + /** + * Returns the base value of the attribute as an {@link AnimatableValue}. + */ + public AnimatableValue getUnderlyingValue(AnimationTarget target) { + SVGPathSegList psl = getPathSegList(); + PathArrayProducer pp = new PathArrayProducer(); + SVGAnimatedPathDataSupport.handlePathSegList(psl, pp); + return new AnimatablePathDataValue(target, pp.getPathCommands(), + pp.getPathParameters()); + } + + /** + * Updates the animated value with the given {@link AnimatableValue}. + */ + protected void updateAnimatedValue(AnimatableValue val) { + if (val == null) { + hasAnimVal = false; + } else { + hasAnimVal = true; + AnimatablePathDataValue animPath = (AnimatablePathDataValue) val; + if (animPathSegs == null) { + animPathSegs = new AnimSVGPathSegList(); + } + animPathSegs.setAnimatedValue(animPath.getCommands(), + animPath.getParameters()); + } + fireAnimatedAttributeListeners(); + } + + /** + * Called when an Attr node has been added. + */ + public void attrAdded(Attr node, String newv) { + if (!changing) { + if (pathSegs != null) { + pathSegs.invalidate(); + } + if (normalizedPathSegs != null) { + normalizedPathSegs.invalidate(); + } + } + fireBaseAttributeListeners(); + if (!hasAnimVal) { + fireAnimatedAttributeListeners(); + } + } + + /** + * Called when an Attr node has been modified. + */ + public void attrModified(Attr node, String oldv, String newv) { + if (!changing) { + if (pathSegs != null) { + pathSegs.invalidate(); + } + if (normalizedPathSegs != null) { + normalizedPathSegs.invalidate(); + } + } + fireBaseAttributeListeners(); + if (!hasAnimVal) { + fireAnimatedAttributeListeners(); + } + } + + /** + * Called when an Attr node has been removed. + */ + public void attrRemoved(Attr node, String oldv) { + if (!changing) { + if (pathSegs != null) { + pathSegs.invalidate(); + } + if (normalizedPathSegs != null) { + normalizedPathSegs.invalidate(); + } + } + fireBaseAttributeListeners(); + if (!hasAnimVal) { + fireAnimatedAttributeListeners(); + } + } + + /** + * {@link SVGPathSegList} implementation for the base path data value. + */ + public class BaseSVGPathSegList extends AbstractSVGPathSegList { + + /** + * Whether the attribute is missing. + */ + protected boolean missing; + + /** + * Whether the attribute is malformed. + */ + protected boolean malformed; + + /** + * Create a DOMException. + */ + protected DOMException createDOMException(short type, String key, + Object[] args) { + return element.createDOMException(type, key, args); + } + + /** + * Create a SVGException. + */ + protected SVGException createSVGException(short type, String key, + Object[] args) { + return ((SVGOMElement)element).createSVGException(type, key, args); + } + + /** + * Returns the value of the DOM attribute containing the path data. + */ + protected String getValueAsString() { + Attr attr = element.getAttributeNodeNS(namespaceURI, localName); + if (attr == null) { + return defaultValue; + } + return attr.getValue(); + } + + /** + * Sets the DOM attribute value containing the path data. + */ + protected void setAttributeValue(String value) { + try { + changing = true; + element.setAttributeNS(namespaceURI, localName, value); + } finally { + changing = false; + } + } + + /** + * Resets the value of the associated attribute. + */ + protected void resetAttribute() { + super.resetAttribute(); + missing = false; + malformed = false; + } + + /** + * Appends the string representation of the given {@link SVGItem} to + * the DOM attribute. This is called in response to an append to + * the list. + */ + protected void resetAttribute(SVGItem item) { + super.resetAttribute(item); + missing = false; + malformed = false; + } + + /** + * Initializes the list, if needed. + */ + protected void revalidate() { + if (valid) { + return; + } + + valid = true; + missing = false; + malformed = false; + + String s = getValueAsString(); + if (s == null) { + missing = true; + return; + } + try { + ListBuilder builder = new ListBuilder(this); + + doParse(s, builder); + + if (builder.getList() != null) { + clear(itemList); + } + itemList = builder.getList(); + } catch (ParseException e) { + itemList = new ArrayList(1); + malformed = true; + } + } + } + + /** + * {@link SVGPathSegList} implementation for the normalized version of the + * base path data value. + */ + public class NormalizedBaseSVGPathSegList + extends AbstractSVGNormPathSegList { + + /** + * Whether the attribute is missing. + */ + protected boolean missing; + + /** + * Whether the attribute is malformed. + */ + protected boolean malformed; + + /** + * Create a DOMException. + */ + protected DOMException createDOMException(short type, String key, + Object[] args) { + return element.createDOMException(type, key, args); + } + + /** + * Create a SVGException. + */ + protected SVGException createSVGException(short type, String key, + Object[] args) { + return ((SVGOMElement)element).createSVGException(type, key, args); + } + + /** + * Returns the value of the DOM attribute containing the path data. + */ + protected String getValueAsString() throws SVGException { + Attr attr = element.getAttributeNodeNS(namespaceURI, localName); + if (attr == null) { + return defaultValue; + } + return attr.getValue(); + } + + /** + * Sets the DOM attribute value containing the path data. + */ + protected void setAttributeValue(String value) { + try { + changing = true; + element.setAttributeNS(namespaceURI, localName, value); + } finally { + changing = false; + } + } + + /** + * Initializes the list, if needed. + */ + protected void revalidate() { + if (valid) { + return; + } + + valid = true; + missing = false; + malformed = false; + + String s = getValueAsString(); + if (s == null) { + missing = true; + return; + } + try { + ListBuilder builder = new ListBuilder(this); + + doParse(s, builder); + + if (builder.getList() != null) { + clear(itemList); + } + itemList = builder.getList(); + } catch (ParseException e) { + itemList = new ArrayList(1); + malformed = true; + } + } + } + + /** + * {@link SVGPathSegList} implementation for the animated path data value. + */ + public class AnimSVGPathSegList extends AbstractSVGPathSegList { + + /** + * Creates a new AnimSVGPathSegList. + */ + public AnimSVGPathSegList() { + itemList = new ArrayList(1); + } + + /** + * Create a DOMException. + */ + protected DOMException createDOMException(short type, String key, + Object[] args) { + return element.createDOMException(type, key, args); + } + + /** + * Create a SVGException. + */ + protected SVGException createSVGException(short type, String key, + Object[] args) { + return ((SVGOMElement)element).createSVGException(type, key, args); + } + + /** + * <b>DOM</b>: Implements {@link SVGPathSegList#getNumberOfItems()}. + */ + public int getNumberOfItems() { + if (hasAnimVal) { + return super.getNumberOfItems(); + } + return getPathSegList().getNumberOfItems(); + } + + /** + * <b>DOM</b>: Implements {@link SVGPathSegList#getItem(int)}. + */ + public SVGPathSeg getItem(int index) throws DOMException { + if (hasAnimVal) { + return super.getItem(index); + } + return getPathSegList().getItem(index); + } + + /** + * Returns the value of the DOM attribute containing the point list. + */ + protected String getValueAsString() { + if (itemList.size() == 0) { + return ""; + } + StringBuffer sb = new StringBuffer( itemList.size() * 8 ); + Iterator i = itemList.iterator(); + if (i.hasNext()) { + sb.append(((SVGItem) i.next()).getValueAsString()); + } + while (i.hasNext()) { + sb.append(getItemSeparator()); + sb.append(((SVGItem) i.next()).getValueAsString()); + } + return sb.toString(); + } + + /** + * Sets the DOM attribute value containing the point list. + */ + protected void setAttributeValue(String value) { + } + + /** + * <b>DOM</b>: Implements {@link SVGPathSegList#clear()}. + */ + public void clear() throws DOMException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.pathseg.list", null); + } + + /** + * <b>DOM</b>: Implements {@link SVGPathSegList#initialize(SVGPathSeg)}. + */ + public SVGPathSeg initialize(SVGPathSeg newItem) + throws DOMException, SVGException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.pathseg.list", null); + } + + /** + * <b>DOM</b>: Implements {@link + * SVGPathSegList#insertItemBefore(SVGPathSeg, int)}. + */ + public SVGPathSeg insertItemBefore(SVGPathSeg newItem, int index) + throws DOMException, SVGException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.pathseg.list", null); + } + + /** + * <b>DOM</b>: Implements {@link + * SVGPathSegList#replaceItem(SVGPathSeg, int)}. + */ + public SVGPathSeg replaceItem(SVGPathSeg newItem, int index) + throws DOMException, SVGException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.pathseg.list", null); + } + + /** + * <b>DOM</b>: Implements {@link SVGPathSegList#removeItem(int)}. + */ + public SVGPathSeg removeItem(int index) throws DOMException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.pathseg.list", null); + } + + /** + * <b>DOM</b>: Implements {@link SVGPathSegList#appendItem(SVGPathSeg)}. + */ + public SVGPathSeg appendItem(SVGPathSeg newItem) throws DOMException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.pathseg.list", null); + } + + /** + * Pass by reference integer for use by newItem. + */ + private int[] parameterIndex = new int[1]; + + /** + * Creates a new SVGPathSegItem from the given path command and array + * of parameter values. + */ + protected SVGPathSegItem newItem(short command, float[] parameters, + int[] j) { + switch (command) { + case SVGPathSeg.PATHSEG_ARC_ABS: + case SVGPathSeg.PATHSEG_ARC_REL: + return new SVGPathSegArcItem + (command, PATHSEG_LETTERS[command], + parameters[j[0]++], + parameters[j[0]++], + parameters[j[0]++], + parameters[j[0]++] != 0, + parameters[j[0]++] != 0, + parameters[j[0]++], + parameters[j[0]++]); + case SVGPathSeg.PATHSEG_CLOSEPATH: + return new SVGPathSegItem + (command, PATHSEG_LETTERS[command]); + case SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS: + case SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL: + return new SVGPathSegCurvetoCubicItem + (command, PATHSEG_LETTERS[command], + parameters[j[0]++], + parameters[j[0]++], + parameters[j[0]++], + parameters[j[0]++], + parameters[j[0]++], + parameters[j[0]++]); + case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: + case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL: + return new SVGPathSegCurvetoCubicSmoothItem + (command, PATHSEG_LETTERS[command], + parameters[j[0]++], + parameters[j[0]++], + parameters[j[0]++], + parameters[j[0]++]); + case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS: + case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL: + return new SVGPathSegCurvetoQuadraticItem + (command, PATHSEG_LETTERS[command], + parameters[j[0]++], + parameters[j[0]++], + parameters[j[0]++], + parameters[j[0]++]); + case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: + case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: + return new SVGPathSegCurvetoQuadraticSmoothItem + (command, PATHSEG_LETTERS[command], + parameters[j[0]++], + parameters[j[0]++]); + case SVGPathSeg.PATHSEG_LINETO_ABS: + case SVGPathSeg.PATHSEG_LINETO_REL: + case SVGPathSeg.PATHSEG_MOVETO_ABS: + case SVGPathSeg.PATHSEG_MOVETO_REL: + return new SVGPathSegMovetoLinetoItem + (command, PATHSEG_LETTERS[command], + parameters[j[0]++], + parameters[j[0]++]); + case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL: + case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS: + return new SVGPathSegLinetoHorizontalItem + (command, PATHSEG_LETTERS[command], + parameters[j[0]++]); + case SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL: + case SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS: + return new SVGPathSegLinetoVerticalItem + (command, PATHSEG_LETTERS[command], + parameters[j[0]++]); + } + return null; + } + + /** + * Sets the animated value. + */ + protected void setAnimatedValue(short[] commands, float[] parameters) { + int size = itemList.size(); + int i = 0; + int[] j = parameterIndex; + j[0] = 0; + while (i < size && i < commands.length) { + SVGPathSeg s = (SVGPathSeg) itemList.get(i); + if (s.getPathSegType() != commands[i]) { + s = newItem(commands[i], parameters, j); + } else { + switch (commands[i]) { + case SVGPathSeg.PATHSEG_ARC_ABS: + case SVGPathSeg.PATHSEG_ARC_REL: { + SVGPathSegArcItem ps = (SVGPathSegArcItem) s; + ps.setR1(parameters[j[0]++]); + ps.setR2(parameters[j[0]++]); + ps.setAngle(parameters[j[0]++]); + ps.setLargeArcFlag(parameters[j[0]++] != 0); + ps.setSweepFlag(parameters[j[0]++] != 0); + ps.setX(parameters[j[0]++]); + ps.setY(parameters[j[0]++]); + break; + } + case SVGPathSeg.PATHSEG_CLOSEPATH: + // Nothing to update. + break; + case SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS: + case SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL: { + SVGPathSegCurvetoCubicItem ps = + (SVGPathSegCurvetoCubicItem) s; + ps.setX1(parameters[j[0]++]); + ps.setY1(parameters[j[0]++]); + ps.setX2(parameters[j[0]++]); + ps.setY2(parameters[j[0]++]); + ps.setX(parameters[j[0]++]); + ps.setY(parameters[j[0]++]); + break; + } + case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: + case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL: { + SVGPathSegCurvetoCubicSmoothItem ps = + (SVGPathSegCurvetoCubicSmoothItem) s; + ps.setX2(parameters[j[0]++]); + ps.setY2(parameters[j[0]++]); + ps.setX(parameters[j[0]++]); + ps.setY(parameters[j[0]++]); + break; + } + case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS: + case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL: { + SVGPathSegCurvetoQuadraticItem ps = + (SVGPathSegCurvetoQuadraticItem) s; + ps.setX1(parameters[j[0]++]); + ps.setY1(parameters[j[0]++]); + ps.setX(parameters[j[0]++]); + ps.setY(parameters[j[0]++]); + break; + } + case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: + case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: { + SVGPathSegCurvetoQuadraticSmoothItem ps = + (SVGPathSegCurvetoQuadraticSmoothItem) s; + ps.setX(parameters[j[0]++]); + ps.setY(parameters[j[0]++]); + break; + } + case SVGPathSeg.PATHSEG_LINETO_ABS: + case SVGPathSeg.PATHSEG_LINETO_REL: + case SVGPathSeg.PATHSEG_MOVETO_ABS: + case SVGPathSeg.PATHSEG_MOVETO_REL: { + SVGPathSegMovetoLinetoItem ps = + (SVGPathSegMovetoLinetoItem) s; + ps.setX(parameters[j[0]++]); + ps.setY(parameters[j[0]++]); + break; + } + case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL: + case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS: { + SVGPathSegLinetoHorizontalItem ps = + (SVGPathSegLinetoHorizontalItem) s; + ps.setX(parameters[j[0]++]); + break; + } + case SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL: + case SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS: { + SVGPathSegLinetoVerticalItem ps = + (SVGPathSegLinetoVerticalItem) s; + ps.setY(parameters[j[0]++]); + break; + } + } + } + i++; + } + while (i < commands.length) { + appendItemImpl(newItem(commands[i], parameters, j)); + i++; + } + while (size > commands.length) { + removeItemImpl(--size); + } + } + + /** + * Resets the value of the associated attribute. Does nothing, since + * there is no attribute for an animated value. + */ + protected void resetAttribute() { + } + + /** + * Resets the value of the associated attribute. Does nothing, since + * there is no attribute for an animated value. + */ + protected void resetAttribute(SVGItem item) { + } + + /** + * Initializes the list, if needed. Does nothing, since there is no + * attribute to read the list from. + */ + protected void revalidate() { + valid = true; + } + } +} Added: xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedPoints.java URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedPoints.java?rev=1647590&view=auto ============================================================================== --- xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedPoints.java (added) +++ xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedPoints.java Tue Dec 23 15:10:45 2014 @@ -0,0 +1,486 @@ +/* + + 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.dom; + +import java.util.ArrayList; +import java.util.Iterator; + +import org.apache.batik.anim.values.AnimatablePointListValue; +import org.apache.batik.anim.values.AnimatableValue; +import org.apache.batik.dom.svg.AbstractSVGList; +import org.apache.batik.dom.svg.AbstractSVGPointList; +import org.apache.batik.dom.svg.ListBuilder; +import org.apache.batik.dom.svg.LiveAttributeException; +import org.apache.batik.dom.svg.SVGItem; +import org.apache.batik.dom.svg.SVGPointItem; + +import org.apache.batik.parser.ParseException; + +import org.w3c.dom.Attr; +import org.w3c.dom.DOMException; +import org.w3c.dom.svg.SVGAnimatedPoints; +import org.w3c.dom.svg.SVGException; +import org.w3c.dom.svg.SVGPoint; +import org.w3c.dom.svg.SVGPointList; + +/** + * This class is the implementation of the SVGAnimatedPoints interface. + * + * @author <a href="mailto:nicolas.sochel...@bitflash.com">Nicolas Socheleau</a> + * @version $Id$ + */ +public class SVGOMAnimatedPoints + extends AbstractSVGAnimatedValue + implements SVGAnimatedPoints { + + /** + * The base value. + */ + protected BaseSVGPointList baseVal; + + /** + * The animated value. + */ + protected AnimSVGPointList animVal; + + /** + * Whether the list is changing. + */ + protected boolean changing; + + /** + * Default value for the point list. + */ + protected String defaultValue; + + /** + * Creates a new SVGOMAnimatedPoints. + * @param elt The associated element. + * @param ns The attribute's namespace URI. + * @param ln The attribute's local name. + * @param defaultValue The default value if the attribute is not specified. + */ + public SVGOMAnimatedPoints(AbstractElement elt, + String ns, + String ln, + String defaultValue) { + super(elt, ns, ln); + this.defaultValue = defaultValue; + } + + /** + * <b>DOM</b>: Implements {@link SVGAnimatedPoints#getPoints()}. + */ + public SVGPointList getPoints() { + if (baseVal == null) { + baseVal = new BaseSVGPointList(); + } + return baseVal; + } + + /** + * <b>DOM</b>: Implements {@link SVGAnimatedPoints#getAnimatedPoints()}. + */ + public SVGPointList getAnimatedPoints() { + if (animVal == null) { + animVal = new AnimSVGPointList(); + } + return animVal; + } + + /** + * Throws an exception if the points list value is malformed. + */ + public void check() { + if (!hasAnimVal) { + if (baseVal == null) { + baseVal = new BaseSVGPointList(); + } + baseVal.revalidate(); + if (baseVal.missing) { + throw new LiveAttributeException + (element, localName, + LiveAttributeException.ERR_ATTRIBUTE_MISSING, null); + } + if (baseVal.malformed) { + throw new LiveAttributeException + (element, localName, + LiveAttributeException.ERR_ATTRIBUTE_MALFORMED, + baseVal.getValueAsString()); + } + } + } + + /** + * Returns the base value of the attribute as an {@link AnimatableValue}. + */ + public AnimatableValue getUnderlyingValue(AnimationTarget target) { + SVGPointList pl = getPoints(); + int n = pl.getNumberOfItems(); + float[] points = new float[n * 2]; + for (int i = 0; i < n; i++) { + SVGPoint p = pl.getItem(i); + points[i * 2] = p.getX(); + points[i * 2 + 1] = p.getY(); + } + return new AnimatablePointListValue(target, points); + } + + /** + * Updates the animated value with the given {@link AnimatableValue}. + */ + protected void updateAnimatedValue(AnimatableValue val) { + if (val == null) { + hasAnimVal = false; + } else { + hasAnimVal = true; + AnimatablePointListValue animPointList = + (AnimatablePointListValue) val; + if (animVal == null) { + animVal = new AnimSVGPointList(); + } + animVal.setAnimatedValue(animPointList.getNumbers()); + } + fireAnimatedAttributeListeners(); + } + + /** + * Called when an Attr node has been added. + */ + public void attrAdded(Attr node, String newv) { + if (!changing && baseVal != null) { + baseVal.invalidate(); + } + fireBaseAttributeListeners(); + if (!hasAnimVal) { + fireAnimatedAttributeListeners(); + } + } + + /** + * Called when an Attr node has been modified. + */ + public void attrModified(Attr node, String oldv, String newv) { + if (!changing && baseVal != null) { + baseVal.invalidate(); + } + fireBaseAttributeListeners(); + if (!hasAnimVal) { + fireAnimatedAttributeListeners(); + } + } + + /** + * Called when an Attr node has been removed. + */ + public void attrRemoved(Attr node, String oldv) { + if (!changing && baseVal != null) { + baseVal.invalidate(); + } + fireBaseAttributeListeners(); + if (!hasAnimVal) { + fireAnimatedAttributeListeners(); + } + } + + /** + * {@link SVGPointList} implementation for the base point list value. + */ + protected class BaseSVGPointList extends AbstractSVGPointList { + + /** + * Whether the attribute is missing. + */ + protected boolean missing; + + /** + * Whether the attribute is malformed. + */ + protected boolean malformed; + + /** + * Create a DOMException. + */ + protected DOMException createDOMException(short type, String key, + Object[] args) { + return element.createDOMException(type, key, args); + } + + /** + * Create a SVGException. + */ + protected SVGException createSVGException(short type, String key, + Object[] args) { + + return ((SVGOMElement)element).createSVGException(type, key, args); + } + + /** + * Returns the value of the DOM attribute containing the point list. + */ + protected String getValueAsString() { + Attr attr = element.getAttributeNodeNS(namespaceURI, localName); + if (attr == null) { + return defaultValue; + } + return attr.getValue(); + } + + /** + * Sets the DOM attribute value containing the point list. + */ + protected void setAttributeValue(String value) { + try { + changing = true; + element.setAttributeNS(namespaceURI, localName, value); + } finally { + changing = false; + } + } + + /** + * Resets the value of the associated attribute. + */ + protected void resetAttribute() { + super.resetAttribute(); + missing = false; + malformed = false; + } + + /** + * Appends the string representation of the given {@link SVGItem} to + * the DOM attribute. This is called in response to an append to + * the list. + */ + protected void resetAttribute(SVGItem item) { + super.resetAttribute(item); + missing = false; + malformed = false; + } + + /** + * Initializes the list, if needed. + */ + protected void revalidate() { + if (valid) { + return; + } + + valid = true; + missing = false; + malformed = false; + + String s = getValueAsString(); + if (s == null) { + missing = true; + return; + } + try { + ListBuilder builder = new ListBuilder(this); + + doParse(s, builder); + + if (builder.getList() != null) { + clear(itemList); + } + itemList = builder.getList(); + } catch (ParseException e) { + itemList = new ArrayList(1); + malformed = true; + } + } + } + + /** + * {@link SVGPointList} implementation for the animated point list value. + */ + protected class AnimSVGPointList extends AbstractSVGPointList { + + /** + * Creates a new AnimSVGPointList. + */ + public AnimSVGPointList() { + itemList = new ArrayList(1); + } + + /** + * Create a DOMException. + */ + protected DOMException createDOMException(short type, String key, + Object[] args) { + return element.createDOMException(type, key, args); + } + + /** + * Create a SVGException. + */ + protected SVGException createSVGException(short type, String key, + Object[] args) { + + return ((SVGOMElement)element).createSVGException(type, key, args); + } + + /** + * <b>DOM</b>: Implements {@link SVGPointList#getNumberOfItems()}. + */ + public int getNumberOfItems() { + if (hasAnimVal) { + return super.getNumberOfItems(); + } + return getPoints().getNumberOfItems(); + } + + /** + * <b>DOM</b>: Implements {@link SVGPointList#getItem(int)}. + */ + public SVGPoint getItem(int index) throws DOMException { + if (hasAnimVal) { + return super.getItem(index); + } + return getPoints().getItem(index); + } + + /** + * Returns the value of the DOM attribute containing the point list. + */ + protected String getValueAsString() { + if (itemList.size() == 0) { + return ""; + } + StringBuffer sb = new StringBuffer( itemList.size() * 8 ); + Iterator i = itemList.iterator(); + if (i.hasNext()) { + sb.append(((SVGItem) i.next()).getValueAsString()); + } + while (i.hasNext()) { + sb.append(getItemSeparator()); + sb.append(((SVGItem) i.next()).getValueAsString()); + } + return sb.toString(); + } + + /** + * Sets the DOM attribute value containing the point list. + */ + protected void setAttributeValue(String value) { + } + + /** + * <b>DOM</b>: Implements {@link SVGPointList#clear()}. + */ + public void clear() throws DOMException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.point.list", null); + } + + /** + * <b>DOM</b>: Implements {@link SVGPointList#initialize(SVGPoint)}. + */ + public SVGPoint initialize(SVGPoint newItem) + throws DOMException, SVGException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.point.list", null); + } + + /** + * <b>DOM</b>: Implements {@link + * SVGPointList#insertItemBefore(SVGPoint, int)}. + */ + public SVGPoint insertItemBefore(SVGPoint newItem, int index) + throws DOMException, SVGException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.point.list", null); + } + + /** + * <b>DOM</b>: Implements {@link + * SVGPointList#replaceItem(SVGPoint, int)}. + */ + public SVGPoint replaceItem(SVGPoint newItem, int index) + throws DOMException, SVGException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.point.list", null); + } + + /** + * <b>DOM</b>: Implements {@link SVGPointList#removeItem(int)}. + */ + public SVGPoint removeItem(int index) throws DOMException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.point.list", null); + } + + /** + * <b>DOM</b>: Implements {@link SVGPointList#appendItem(SVGPoint)}. + */ + public SVGPoint appendItem(SVGPoint newItem) throws DOMException { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.point.list", null); + } + + /** + * Sets the animated value. + */ + protected void setAnimatedValue(float[] pts) { + int size = itemList.size(); + int i = 0; + while (i < size && i < pts.length / 2) { + SVGPointItem p = (SVGPointItem) itemList.get(i); + p.setX(pts[i * 2]); + p.setY(pts[i * 2 + 1]); + i++; + } + while (i < pts.length / 2) { + appendItemImpl(new SVGPointItem(pts[i * 2], pts[i * 2 + 1])); + i++; + } + while (size > pts.length / 2) { + removeItemImpl(--size); + } + } + + /** + * Resets the value of the associated attribute. Does nothing, since + * there is no attribute for an animated value. + */ + protected void resetAttribute() { + } + + /** + * Resets the value of the associated attribute. Does nothing, since + * there is no attribute for an animated value. + */ + protected void resetAttribute(SVGItem item) { + } + + /** + * Initializes the list, if needed. Does nothing, since there is no + * attribute to read the list from. + */ + protected void revalidate() { + valid = true; + } + } +} Added: xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedPreserveAspectRatio.java URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedPreserveAspectRatio.java?rev=1647590&view=auto ============================================================================== --- xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedPreserveAspectRatio.java (added) +++ xmlgraphics/batik/branches/submodules_cyclic_deps/sources/org/apache/batik/anim/dom/SVGOMAnimatedPreserveAspectRatio.java Tue Dec 23 15:10:45 2014 @@ -0,0 +1,289 @@ +/* + + 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.dom; + +import org.apache.batik.anim.values.AnimatablePreserveAspectRatioValue; +import org.apache.batik.anim.values.AnimatableValue; +import org.apache.batik.dom.svg.AbstractSVGPreserveAspectRatio; +import org.apache.batik.dom.svg.LiveAttributeException; + +import org.apache.batik.util.SVGConstants; + +import org.w3c.dom.Attr; +import org.w3c.dom.DOMException; +import org.w3c.dom.svg.SVGAnimatedPreserveAspectRatio; +import org.w3c.dom.svg.SVGPreserveAspectRatio; + +/** + * This class implements the {@link SVGAnimatedPreserveAspectRatio} interface. + * + * @author <a href="mailto:to...@kiyut.com">Tonny Kohar</a> + * @version $Id$ + */ +public class SVGOMAnimatedPreserveAspectRatio + extends AbstractSVGAnimatedValue + implements SVGAnimatedPreserveAspectRatio { + + /** + * The base value. + */ + protected BaseSVGPARValue baseVal; + + /** + * The animated value. + */ + protected AnimSVGPARValue animVal; + + /** + * Whether the value is changing. + */ + protected boolean changing; + + /** + * Creates a new SVGOMAnimatedPreserveAspectRatio. + * @param elt The associated element. + */ + public SVGOMAnimatedPreserveAspectRatio(AbstractElement elt) { + super(elt, null, SVGConstants.SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE); + } + + /** + * <b>DOM</b>: Implements {@link SVGAnimatedPreserveAspectRatio#getBaseVal()}. + */ + public SVGPreserveAspectRatio getBaseVal() { + if (baseVal == null) { + baseVal = new BaseSVGPARValue(); + } + return baseVal; + } + + /** + * <b>DOM</b>: Implements {@link SVGAnimatedPreserveAspectRatio#getAnimVal()}. + */ + public SVGPreserveAspectRatio getAnimVal() { + if (animVal == null) { + animVal = new AnimSVGPARValue(); + } + return animVal; + } + + + /** + * Throws an exception if the points list value is malformed. + */ + public void check() { + if (!hasAnimVal) { + if (baseVal == null) { + baseVal = new BaseSVGPARValue(); + } + if (baseVal.malformed) { + throw new LiveAttributeException + (element, localName, + LiveAttributeException.ERR_ATTRIBUTE_MALFORMED, + baseVal.getValueAsString()); + } + } + } + + /** + * Returns the base value of the attribute as an {@link AnimatableValue}. + */ + public AnimatableValue getUnderlyingValue(AnimationTarget target) { + SVGPreserveAspectRatio par = getBaseVal(); + return new AnimatablePreserveAspectRatioValue(target, par.getAlign(), + par.getMeetOrSlice()); + } + + /** + * Updates the animated value with the given {@link AnimatableValue}. + */ + protected void updateAnimatedValue(AnimatableValue val) { + if (val == null) { + hasAnimVal = false; + } else { + hasAnimVal = true; + if (animVal == null) { + animVal = new AnimSVGPARValue(); + } + AnimatablePreserveAspectRatioValue animPAR = + (AnimatablePreserveAspectRatioValue) val; + animVal.setAnimatedValue(animPAR.getAlign(), + animPAR.getMeetOrSlice()); + } + fireAnimatedAttributeListeners(); + } + + /** + * Called when an Attr node has been added. + */ + public void attrAdded(Attr node, String newv) { + if (!changing && baseVal != null) { + baseVal.invalidate(); + } + fireBaseAttributeListeners(); + if (!hasAnimVal) { + fireAnimatedAttributeListeners(); + } + } + + /** + * Called when an Attr node has been modified. + */ + public void attrModified(Attr node, String oldv, String newv) { + if (!changing && baseVal != null) { + baseVal.invalidate(); + } + fireBaseAttributeListeners(); + if (!hasAnimVal) { + fireAnimatedAttributeListeners(); + } + } + + /** + * Called when an Attr node has been removed. + */ + public void attrRemoved(Attr node, String oldv) { + if (!changing && baseVal != null) { + baseVal.invalidate(); + } + fireBaseAttributeListeners(); + if (!hasAnimVal) { + fireAnimatedAttributeListeners(); + } + } + + /** + * This class represents the SVGPreserveAspectRatio returned by {@link + * #getBaseVal()}. + */ + public class BaseSVGPARValue extends AbstractSVGPreserveAspectRatio { + + /** + * Whether the attribute is malformed. + */ + protected boolean malformed; + + /** + * Creates a new BaseSVGPARValue. + */ + public BaseSVGPARValue() { + invalidate(); + } + + /** + * Create a DOMException. + */ + protected DOMException createDOMException(short type, String key, + Object[] args) { + return element.createDOMException(type, key, args); + } + + /** + * Sets the associated DOM attribute. + */ + protected void setAttributeValue(String value) throws DOMException { + try { + changing = true; + element.setAttributeNS + (null, SVGConstants.SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE, + value); + malformed = false; + } finally { + changing = false; + } + } + + /** + * Re-reads the DOM attribute value. + */ + protected void invalidate() { + String s = element.getAttributeNS + (null, SVGConstants.SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE); + setValueAsString(s); + } + } + + /** + * This class represents the SVGPreserveAspectRatio returned by {@link + * #getAnimVal()}. + */ + public class AnimSVGPARValue extends AbstractSVGPreserveAspectRatio { + + /** + * Create a DOMException. + */ + protected DOMException createDOMException(short type, String key, + Object[] args) { + return element.createDOMException(type, key, args); + } + + /** + * Sets the associated DOM attribute. Does nothing, since animated + * values aren't reflected in the DOM. + */ + protected void setAttributeValue(String value) throws DOMException { + } + + /** + * <b>DOM</b>: Implements {@link SVGPreserveAspectRatio#getAlign()}. + */ + public short getAlign() { + if (hasAnimVal) { + return super.getAlign(); + } + return getBaseVal().getAlign(); + } + + /** + * <b>DOM</b>: Implements {@link SVGPreserveAspectRatio#getMeetOrSlice()}. + */ + public short getMeetOrSlice() { + if (hasAnimVal) { + return super.getMeetOrSlice(); + } + return getBaseVal().getMeetOrSlice(); + } + + /** + * <b>DOM</b>: Implements {@link SVGPreserveAspectRatio#setAlign(short)}. + */ + public void setAlign(short align) { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.preserve.aspect.ratio", null); + } + + /** + * <b>DOM</b>: Implements {@link SVGPreserveAspectRatio#setMeetOrSlice(short)}. + */ + public void setMeetOrSlice(short meetOrSlice) { + throw element.createDOMException + (DOMException.NO_MODIFICATION_ALLOWED_ERR, + "readonly.preserve.aspect.ratio", null); + } + + /** + * Updates the animated value. + */ + protected void setAnimatedValue(short align, short meetOrSlice) { + this.align = align; + this.meetOrSlice = meetOrSlice; + } + } +}