/*
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.anim.dom.AnimationTarget;
import org.w3c.dom.svg.SVGLength;
An SVG length value in the animation system.
Author: Cameron McCormack Version: $Id: AnimatableLengthValue.java 1733416 2016-03-03 07:07:13Z gadams $
/**
* An SVG length value in the animation system.
*
* @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
* @version $Id: AnimatableLengthValue.java 1733416 2016-03-03 07:07:13Z gadams $
*/
public class AnimatableLengthValue extends AnimatableValue {
Length units.
/**
* Length units.
*/
protected static final String[] UNITS = {
"", "%", "em", "ex", "px", "cm", "mm", "in", "pt", "pc"
};
The length type.
/**
* The length type.
*/
protected short lengthType;
The length value. This should be one of the constants defined in SVGLength
. /**
* 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 AnimationTarget
.PERCENTAGE_* constants. /**
* How to interpret percentage values. One of the
* {@link AnimationTarget}.PERCENTAGE_* constants.
*/
protected short percentageInterpretation;
Creates a new AnimatableLengthValue with no length.
/**
* Creates a new AnimatableLengthValue with no length.
*/
protected AnimatableLengthValue(AnimationTarget target) {
super(target);
}
Creates a new AnimatableLengthValue.
/**
* 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.
/**
* 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.
Params: - t1 – the first SVG length type
- pi1 – the first percentage interpretation type
- t2 – the second SVG length type
- pi2 – the second percentage interpretation type
/**
* 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.
/**
* Returns the unit type of this length value.
*/
public int getLengthType() {
return lengthType;
}
Returns the magnitude of this length value.
/**
* 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.
/**
* 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.
/**
* 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.
/**
* 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.
/**
* 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];
}
}