001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.perseus.model;
028:
029: import com.sun.perseus.platform.MathSupport;
030:
031: import org.w3c.dom.DOMException;
032:
033: /**
034: * @version $Id: TransformTraitAnim.java,v 1.3 2006/06/29 10:47:36 ln156897 Exp $
035: */
036: class TransformTraitAnim extends FloatTraitAnim {
037: /**
038: * Constructs a new TransformTraitAnim for a given ElementNode trait.
039: *
040: * @param targetElement the ElementNode whose trait is animated.
041: * @param targetTrait the name of the animated trait.
042: */
043: public TransformTraitAnim(final ElementNode targetElement,
044: final String traitName) {
045: super (targetElement, traitName,
046: ElementNode.TRAIT_TYPE_SVG_MATRIX);
047: }
048:
049: /**
050: * Converts the input values set to a RefValues object.
051: *
052: * @param anim the <code>Animation</code> for which the values should be
053: * converted.
054: * @param values a semi-colon seperated list of values which need to be
055: * validated.
056: * @param reqTraitNamespace the namespace of the trait which has the values
057: * value on the requesting element.
058: * @param reqTraitName the name of the trait which has the values value on
059: * the requesting element.
060: * @throws DOMException with error code INVALID_ACCESS_ERR if the input
061: * value is incompatible with the given trait.
062: * @throws NullPointerException if values is null.
063: */
064: RefValues toRefValues(final Animation anim, String[] values,
065: final String reqTraitNamespace, final String reqTraitName)
066: throws DOMException {
067: // If we are dealing with a generic animation, the values should be
068: // as in the transform attribute: we can use the default FloatTraitAnim
069: // toRefValues.
070: if (anim.type == Animation.TYPE_GENERIC) {
071: return super .toRefValues(anim, values, reqTraitNamespace,
072: reqTraitName);
073: }
074:
075: // The interpretation of values depends on the animation type.
076: TransformRefValues refValues = new TransformRefValues();
077:
078: if (values.length < 1) {
079: throw new IllegalArgumentException();
080: }
081:
082: if (values.length == 1) {
083: String[] tmpValues = new String[2];
084: tmpValues[0] = values[0];
085: tmpValues[1] = values[0];
086: values = tmpValues;
087: }
088:
089: int nSegments = values.length - 1;
090: TransformSegment[] segments = new TransformSegment[nSegments];
091:
092: // Build the first segment.
093: segments[0] = new TransformSegment();
094: segments[0].start = validateValue(anim, reqTraitNamespace,
095: reqTraitName, values[0]);
096: segments[0].end = validateValue(anim, reqTraitNamespace,
097: reqTraitName, values[1]);
098: segments[0].type = anim.type;
099:
100: TransformSegment prevSegment = segments[0];
101:
102: for (int i = 1; i < nSegments; i++) {
103: segments[i] = new TransformSegment();
104: segments[i].start = prevSegment.end;
105: segments[i].end = validateValue(anim, reqTraitNamespace,
106: reqTraitName, values[i + 1]);
107: segments[i].type = anim.type;
108: prevSegment = segments[i];
109: }
110:
111: refValues.segments = segments;
112: return refValues;
113: }
114:
115: /**
116: * Validates the input trait value.
117: *
118: * @param anim the animation for which the value is validated
119: * @param traitNamespace the namespace trait
120: * @param traitName the name of the trait to be validated.
121: * @param value the value to be validated
122: * @throws DOMException with error code INVALID_ACCESS_ERR if the input
123: * value is incompatible with the given trait.
124: */
125: public float[] validateValue(final Animation anim,
126: final String traitNamespace, final String traitName,
127: final String value) {
128: float[] v = null;
129:
130: switch (anim.type) {
131: case AnimateTransform.TYPE_TRANSLATE:
132: v = anim.parseFloatArrayTrait(traitName, value);
133: if (v.length < 1 || v.length > 2) {
134: throw anim.illegalTraitValue(traitName, value);
135: }
136:
137: if (v.length == 1) {
138: float[] tv = new float[2];
139: tv[0] = v[0];
140: tv[1] = 0;
141: v = tv;
142: }
143:
144: return v;
145:
146: case AnimateTransform.TYPE_SCALE:
147: v = anim.parseFloatArrayTrait(traitName, value);
148: if (v.length < 1 || v.length > 2) {
149: throw anim.illegalTraitValue(traitName, value);
150: }
151:
152: if (v.length == 1) {
153: float[] tv = new float[2];
154: tv[0] = v[0];
155: tv[1] = v[0];
156: v = tv;
157: }
158:
159: return v;
160:
161: case AnimateTransform.TYPE_ROTATE:
162: // This should be enhanced to support
163: v = anim.parseFloatArrayTrait(traitName, value);
164: if (v.length != 1 && v.length != 3) {
165: throw anim.illegalTraitValue(traitName, value);
166: }
167:
168: if (v.length != 3) {
169: float[] tv = new float[3];
170: tv[0] = v[0];
171: tv[1] = 0;
172: tv[2] = 0;
173: v = tv;
174: }
175:
176: v[0] = MathSupport.toRadians(v[0]);
177: return v;
178:
179: case AnimateTransform.TYPE_SKEW_X:
180: case AnimateTransform.TYPE_SKEW_Y:
181: default:
182: v = new float[] { anim.parseFloatTrait(traitName, value) };
183: v[0] = MathSupport.toRadians(v[0]);
184: return v;
185: }
186: }
187:
188: /**
189: * Used to sum two animated trait values.
190: *
191: * @param valueA the base value. May be null.
192: * @param valueB the value to add to the base value. If the baseValue
193: */
194: public Object[] sum(Object[] valueA, Object[] valueB) {
195: if (valueA == null) {
196: return valueB;
197: }
198:
199: float[][] fva = (float[][]) valueA;
200: float[][] fvb = (float[][]) valueB;
201:
202: // For transforms, we should do matrices multiplication, not
203: // simple float additions.
204: float[][] fv = new float[6][1];
205:
206: fv[0][0] = fvb[0][0] * fva[0][0] + fvb[1][0] * fva[2][0];
207: fv[1][0] = fvb[0][0] * fva[1][0] + fvb[1][0] * fva[3][0];
208:
209: fv[2][0] = fvb[2][0] * fva[0][0] + fvb[3][0] * fva[2][0];
210: fv[3][0] = fvb[2][0] * fva[1][0] + fvb[3][0] * fva[3][0];
211:
212: fv[4][0] = fvb[4][0] * fva[0][0] + fvb[5][0] * fva[2][0]
213: + fva[4][0];
214: fv[5][0] = fvb[4][0] * fva[1][0] + fvb[5][0] * fva[3][0]
215: + fva[5][0];
216:
217: return fv;
218: }
219:
220: /**
221: * Used to multiply an animated trait value by a number of iterations.
222: *
223: * @param value the animated trait value to multiply.
224: * @param iter the number of iteration to account for.
225: * @return the multiply result.
226: */
227: public Object[] multiply(Object[] value, int iter) {
228: for (int i = 1; i < iter; i++) {
229: value = sum(value, value);
230: }
231:
232: return value;
233: }
234:
235: }
|