PageRenderTime 65ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/batik-1.8/sources/org/apache/batik/bridge/SVGAnimateElementBridge.java

#
Java | 327 lines | 251 code | 15 blank | 61 comment | 91 complexity | 8d8e5a24a905a2b7902c2abb4e709477 MD5 | raw file
Possible License(s): Apache-2.0, GPL-2.0, IPL-1.0
  1. /*
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. */
  15. package org.apache.batik.bridge;
  16. import java.util.ArrayList;
  17. import java.util.List;
  18. import org.apache.batik.anim.AbstractAnimation;
  19. import org.apache.batik.anim.AnimationEngine;
  20. import org.apache.batik.dom.anim.AnimationTarget;
  21. import org.apache.batik.anim.SimpleAnimation;
  22. import org.apache.batik.anim.values.AnimatableValue;
  23. import org.apache.batik.util.SMILConstants;
  24. /**
  25. * Bridge class for the 'animate' animation element.
  26. *
  27. * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
  28. * @version $Id: SVGAnimateElementBridge.java 501922 2007-01-31 17:47:47Z dvholten $
  29. */
  30. public class SVGAnimateElementBridge extends SVGAnimationElementBridge {
  31. /**
  32. * Returns 'animate'.
  33. */
  34. public String getLocalName() {
  35. return SVG_ANIMATE_TAG;
  36. }
  37. /**
  38. * Returns a new instance of this bridge.
  39. */
  40. public Bridge getInstance() {
  41. return new SVGAnimateElementBridge();
  42. }
  43. /**
  44. * Creates the animation object for the animation element.
  45. */
  46. protected AbstractAnimation createAnimation(AnimationTarget target) {
  47. AnimatableValue from = parseAnimatableValue(SVG_FROM_ATTRIBUTE);
  48. AnimatableValue to = parseAnimatableValue(SVG_TO_ATTRIBUTE);
  49. AnimatableValue by = parseAnimatableValue(SVG_BY_ATTRIBUTE);
  50. return new SimpleAnimation(timedElement,
  51. this,
  52. parseCalcMode(),
  53. parseKeyTimes(),
  54. parseKeySplines(),
  55. parseAdditive(),
  56. parseAccumulate(),
  57. parseValues(),
  58. from,
  59. to,
  60. by);
  61. }
  62. /**
  63. * Returns the parsed 'calcMode' attribute from the animation element.
  64. */
  65. protected int parseCalcMode() {
  66. // If the attribute being animated has only non-additive values, take
  67. // the animation as having calcMode="discrete".
  68. if (animationType == AnimationEngine.ANIM_TYPE_CSS
  69. && !targetElement.isPropertyAdditive(attributeLocalName)
  70. || animationType == AnimationEngine.ANIM_TYPE_XML
  71. && !targetElement.isAttributeAdditive(attributeNamespaceURI,
  72. attributeLocalName)) {
  73. return SimpleAnimation.CALC_MODE_DISCRETE;
  74. }
  75. String calcModeString = element.getAttributeNS(null,
  76. SVG_CALC_MODE_ATTRIBUTE);
  77. if (calcModeString.length() == 0) {
  78. return getDefaultCalcMode();
  79. } else if (calcModeString.equals(SMILConstants.SMIL_LINEAR_VALUE)) {
  80. return SimpleAnimation.CALC_MODE_LINEAR;
  81. } else if (calcModeString.equals(SMILConstants.SMIL_DISCRETE_VALUE)) {
  82. return SimpleAnimation.CALC_MODE_DISCRETE;
  83. } else if (calcModeString.equals(SMILConstants.SMIL_PACED_VALUE)) {
  84. return SimpleAnimation.CALC_MODE_PACED;
  85. } else if (calcModeString.equals(SMILConstants.SMIL_SPLINE_VALUE)) {
  86. return SimpleAnimation.CALC_MODE_SPLINE;
  87. }
  88. throw new BridgeException
  89. (ctx, element, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
  90. new Object[] { SVG_CALC_MODE_ATTRIBUTE, calcModeString });
  91. }
  92. /**
  93. * Returns the parsed 'additive' attribute from the animation element.
  94. */
  95. protected boolean parseAdditive() {
  96. String additiveString = element.getAttributeNS(null,
  97. SVG_ADDITIVE_ATTRIBUTE);
  98. if (additiveString.length() == 0
  99. || additiveString.equals(SMILConstants.SMIL_REPLACE_VALUE)) {
  100. return false;
  101. } else if (additiveString.equals(SMILConstants.SMIL_SUM_VALUE)) {
  102. return true;
  103. }
  104. throw new BridgeException
  105. (ctx, element, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
  106. new Object[] { SVG_ADDITIVE_ATTRIBUTE, additiveString });
  107. }
  108. /**
  109. * Returns the parsed 'accumulate' attribute from the animation element.
  110. */
  111. protected boolean parseAccumulate() {
  112. String accumulateString =
  113. element.getAttributeNS(null, SVG_ACCUMULATE_ATTRIBUTE);
  114. if (accumulateString.length() == 0 ||
  115. accumulateString.equals(SMILConstants.SMIL_NONE_VALUE)) {
  116. return false;
  117. } else if (accumulateString.equals(SMILConstants.SMIL_SUM_VALUE)) {
  118. return true;
  119. }
  120. throw new BridgeException
  121. (ctx, element, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
  122. new Object[] { SVG_ACCUMULATE_ATTRIBUTE, accumulateString });
  123. }
  124. /**
  125. * Returns the parsed 'values' attribute from the animation element.
  126. */
  127. protected AnimatableValue[] parseValues() {
  128. boolean isCSS = animationType == AnimationEngine.ANIM_TYPE_CSS;
  129. String valuesString = element.getAttributeNS(null,
  130. SVG_VALUES_ATTRIBUTE);
  131. int len = valuesString.length();
  132. if (len == 0) {
  133. return null;
  134. }
  135. ArrayList values = new ArrayList(7);
  136. int i = 0, start = 0, end;
  137. char c;
  138. outer: while (i < len) {
  139. while (valuesString.charAt(i) == ' ') {
  140. i++;
  141. if (i == len) {
  142. break outer;
  143. }
  144. }
  145. start = i++;
  146. if (i != len) {
  147. c = valuesString.charAt(i);
  148. while (c != ';') {
  149. i++;
  150. if (i == len) {
  151. break;
  152. }
  153. c = valuesString.charAt(i);
  154. }
  155. }
  156. end = i++;
  157. AnimatableValue val = eng.parseAnimatableValue
  158. (element, animationTarget, attributeNamespaceURI,
  159. attributeLocalName, isCSS, valuesString.substring(start, end));
  160. if (!checkValueType(val)) {
  161. throw new BridgeException
  162. (ctx, element, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
  163. new Object[] { SVG_VALUES_ATTRIBUTE, valuesString });
  164. }
  165. values.add(val);
  166. }
  167. AnimatableValue[] ret = new AnimatableValue[values.size()];
  168. return (AnimatableValue[]) values.toArray(ret);
  169. }
  170. /**
  171. * Returns the parsed 'keyTimes' attribute from the animation element.
  172. */
  173. protected float[] parseKeyTimes() {
  174. String keyTimesString =
  175. element.getAttributeNS(null, SVG_KEY_TIMES_ATTRIBUTE);
  176. int len = keyTimesString.length();
  177. if (len == 0) {
  178. return null;
  179. }
  180. ArrayList keyTimes = new ArrayList(7);
  181. int i = 0, start = 0, end;
  182. char c;
  183. outer: while (i < len) {
  184. while (keyTimesString.charAt(i) == ' ') {
  185. i++;
  186. if (i == len) {
  187. break outer;
  188. }
  189. }
  190. start = i++;
  191. if (i != len) {
  192. c = keyTimesString.charAt(i);
  193. while (c != ' ' && c != ';') {
  194. i++;
  195. if (i == len) {
  196. break;
  197. }
  198. c = keyTimesString.charAt(i);
  199. }
  200. }
  201. end = i++;
  202. try {
  203. float keyTime =
  204. Float.parseFloat(keyTimesString.substring(start, end));
  205. keyTimes.add(new Float(keyTime));
  206. } catch (NumberFormatException nfEx ) {
  207. throw new BridgeException
  208. (ctx, element, nfEx, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
  209. new Object[] { SVG_KEY_TIMES_ATTRIBUTE, keyTimesString });
  210. }
  211. }
  212. len = keyTimes.size();
  213. float[] ret = new float[len];
  214. for (int j = 0; j < len; j++) {
  215. ret[j] = ((Float) keyTimes.get(j)).floatValue();
  216. }
  217. return ret;
  218. }
  219. /**
  220. * Returns the parsed 'keySplines' attribute from the animation element.
  221. */
  222. protected float[] parseKeySplines() {
  223. String keySplinesString =
  224. element.getAttributeNS(null, SVG_KEY_SPLINES_ATTRIBUTE);
  225. int len = keySplinesString.length();
  226. if (len == 0) {
  227. return null;
  228. }
  229. List keySplines = new ArrayList(7);
  230. int count = 0, i = 0, start = 0, end;
  231. char c;
  232. outer: while (i < len) {
  233. while (keySplinesString.charAt(i) == ' ') {
  234. i++;
  235. if (i == len) {
  236. break outer;
  237. }
  238. }
  239. start = i++;
  240. if (i != len) {
  241. c = keySplinesString.charAt(i);
  242. while (c != ' ' && c != ',' && c != ';') {
  243. i++;
  244. if (i == len) {
  245. break;
  246. }
  247. c = keySplinesString.charAt(i);
  248. }
  249. end = i++;
  250. if (c == ' ') {
  251. do {
  252. if (i == len) {
  253. break;
  254. }
  255. c = keySplinesString.charAt(i++);
  256. } while (c == ' ');
  257. if (c != ';' && c != ',') {
  258. i--;
  259. }
  260. }
  261. if (c == ';') {
  262. if (count == 3) {
  263. count = 0;
  264. } else {
  265. throw new BridgeException
  266. (ctx, element,
  267. ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
  268. new Object[] { SVG_KEY_SPLINES_ATTRIBUTE,
  269. keySplinesString });
  270. }
  271. } else {
  272. count++;
  273. }
  274. } else {
  275. end = i++;
  276. }
  277. try {
  278. float keySplineValue =
  279. Float.parseFloat(keySplinesString.substring(start, end));
  280. keySplines.add(new Float(keySplineValue));
  281. } catch (NumberFormatException nfEx ) {
  282. throw new BridgeException
  283. (ctx, element, nfEx, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
  284. new Object[] { SVG_KEY_SPLINES_ATTRIBUTE, keySplinesString });
  285. }
  286. }
  287. len = keySplines.size();
  288. float[] ret = new float[len];
  289. for (int j = 0; j < len; j++) {
  290. ret[j] = ((Float) keySplines.get(j)).floatValue();
  291. }
  292. return ret;
  293. }
  294. /**
  295. * Returns the calcMode that the animation defaults to if none is specified.
  296. */
  297. protected int getDefaultCalcMode() {
  298. return SimpleAnimation.CALC_MODE_LINEAR;
  299. }
  300. /**
  301. * Returns whether the animation element being handled by this bridge can
  302. * animate attributes of the specified type.
  303. * @param type one of the TYPE_ constants defined in {@link org.apache.batik.util.SVGTypes}.
  304. */
  305. protected boolean canAnimateType(int type) {
  306. return true;
  307. }
  308. }