• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KHTML

  • sources
  • kde-4.12
  • kdelibs
  • khtml
  • svg
SVGAnimateElement.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
3  2004, 2005, 2006 Rob Buis <buis@kde.org>
4  Copyright (C) 2008 Apple Inc. All rights reserved.
5 
6  This file is part of the KDE project
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Library General Public
10  License as published by the Free Software Foundation; either
11  version 2 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Library General Public License for more details.
17 
18  You should have received a copy of the GNU Library General Public License
19  along with this library; see the file COPYING.LIB. If not, write to
20  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  Boston, MA 02110-1301, USA.
22 */
23 
24 #include "config.h"
25 #if ENABLE(SVG) && ENABLE(SVG_ANIMATION)
26 #include "SVGAnimateElement.h"
27 
28 #include "ColorDistance.h"
29 #include "FloatConversion.h"
30 #include "SVGColor.h"
31 #include "SVGParserUtilities.h"
32 #include <math.h>
33 
34 using namespace std;
35 
36 namespace WebCore {
37 
38 SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName, Document* doc)
39  : SVGAnimationElement(tagName, doc)
40  , m_propertyType(StringProperty)
41  , m_fromNumber(0)
42  , m_toNumber(0)
43  , m_animatedNumber(numeric_limits<double>::infinity())
44 {
45 }
46 
47 SVGAnimateElement::~SVGAnimateElement()
48 {
49 }
50 
51 static bool parseNumberValueAndUnit(const String& in, double& value, String& unit)
52 {
53  // FIXME: These are from top of my head, figure out all property types that can be animated as numbers.
54  unsigned unitLength = 0;
55  String parse = in.stripWhiteSpace();
56  if (parse.endsWith("%"))
57  unitLength = 1;
58  else if (parse.endsWith("px") || parse.endsWith("pt") || parse.endsWith("em"))
59  unitLength = 2;
60  else if (parse.endsWith("deg") || parse.endsWith("rad"))
61  unitLength = 3;
62  else if (parse.endsWith("grad"))
63  unitLength = 4;
64  String newUnit = parse.right(unitLength);
65  String number = parse.left(parse.length() - unitLength);
66  if (!unit.isEmpty() && newUnit != unit || number.isEmpty())
67  return false;
68  UChar last = number[number.length() - 1];
69  if (last < '0' || last > '9')
70  return false;
71  unit = newUnit;
72  bool ok;
73  value = number.toDouble(&ok);
74  return ok;
75 }
76 
77 SVGAnimateElement::PropertyType SVGAnimateElement::determinePropertyType(const String& attribute) const
78 {
79  // FIXME: We need a full property table for figuring this out reliably.
80  if (hasTagName(SVGNames::animateColorTag))
81  return ColorProperty;
82  if (attribute == "color" || attribute == "fill" || attribute == "stroke")
83  return ColorProperty;
84  return NumberProperty;
85 }
86 
87 void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement)
88 {
89  ASSERT(percentage >= 0.f && percentage <= 1.f);
90  ASSERT(resultElement);
91  if (hasTagName(SVGNames::setTag))
92  percentage = 1.f;
93  if (!resultElement->hasTagName(SVGNames::animateTag) && !resultElement->hasTagName(SVGNames::animateColorTag)
94  && !resultElement->hasTagName(SVGNames::setTag))
95  return;
96  SVGAnimateElement* results = static_cast<SVGAnimateElement*>(resultElement);
97  // Can't accumulate over a string property.
98  if (results->m_propertyType == StringProperty && m_propertyType != StringProperty)
99  return;
100  if (m_propertyType == NumberProperty) {
101  // To animation uses contributions from the lower priority animations as the base value.
102  if (animationMode() == ToAnimation)
103  m_fromNumber = results->m_animatedNumber;
104 
105  double number = (m_toNumber - m_fromNumber) * percentage + m_fromNumber;
106 
107  // FIXME: This is not correct for values animation.
108  if (isAccumulated() && repeat)
109  number += m_toNumber * repeat;
110  if (isAdditive() && animationMode() != ToAnimation)
111  results->m_animatedNumber += number;
112  else
113  results->m_animatedNumber = number;
114  return;
115  }
116  if (m_propertyType == ColorProperty) {
117  if (animationMode() == ToAnimation)
118  m_fromColor = results->m_animatedColor;
119  Color color = ColorDistance(m_fromColor, m_toColor).scaledDistance(percentage).addToColorAndClamp(m_fromColor);
120  // FIXME: Accumulate colors.
121  if (isAdditive() && animationMode() != ToAnimation)
122  results->m_animatedColor = ColorDistance::addColorsAndClamp(results->m_animatedColor, color);
123  else
124  results->m_animatedColor = color;
125  return;
126  }
127  AnimationMode animationMode = this->animationMode();
128  ASSERT(animationMode == FromToAnimation || animationMode == ToAnimation || animationMode == ValuesAnimation);
129  if ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1.0f)
130  results->m_animatedString = m_toString;
131  else
132  results->m_animatedString = m_fromString;
133  // Higher priority replace animation overrides any additive results so far.
134  results->m_propertyType = StringProperty;
135 }
136 
137 bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const String& toString)
138 {
139  // FIXME: Needs more solid way determine target attribute type.
140  m_propertyType = determinePropertyType(attributeName());
141  if (m_propertyType == ColorProperty) {
142  m_fromColor = SVGColor::colorFromRGBColorString(fromString);
143  m_toColor = SVGColor::colorFromRGBColorString(toString);
144  if (m_fromColor.isValid() && m_toColor.isValid())
145  return true;
146  } else if (m_propertyType == NumberProperty) {
147  m_numberUnit = String();
148  if (parseNumberValueAndUnit(toString, m_toNumber, m_numberUnit)) {
149  // For to-animations the from number is calculated later
150  if (animationMode() == ToAnimation || parseNumberValueAndUnit(fromString, m_fromNumber, m_numberUnit))
151  return true;
152  }
153  }
154  m_fromString = fromString;
155  m_toString = toString;
156  m_propertyType = StringProperty;
157  return true;
158 }
159 
160 bool SVGAnimateElement::calculateFromAndByValues(const String& fromString, const String& byString)
161 {
162  ASSERT(!hasTagName(SVGNames::setTag));
163  m_propertyType = determinePropertyType(attributeName());
164  if (m_propertyType == ColorProperty) {
165  m_fromColor = fromString.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(fromString);
166  m_toColor = ColorDistance::addColorsAndClamp(m_fromColor, SVGColor::colorFromRGBColorString(byString));
167  if (!m_fromColor.isValid() || !m_toColor.isValid())
168  return false;
169  } else {
170  m_numberUnit = String();
171  m_fromNumber = 0;
172  if (!fromString.isEmpty() && !parseNumberValueAndUnit(fromString, m_fromNumber, m_numberUnit))
173  return false;
174  if (!parseNumberValueAndUnit(byString, m_toNumber, m_numberUnit))
175  return false;
176  m_toNumber += m_fromNumber;
177  }
178  return true;
179 }
180 
181 void SVGAnimateElement::resetToBaseValue(const String& baseString)
182 {
183  m_animatedString = baseString;
184  m_propertyType = determinePropertyType(attributeName());
185  if (m_propertyType == ColorProperty) {
186  m_animatedColor = baseString.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(baseString);
187  if (m_animatedColor.isValid())
188  return;
189  } else if (m_propertyType == NumberProperty) {
190  if (baseString.isEmpty()) {
191  m_animatedNumber = 0;
192  m_numberUnit = String();
193  return;
194  }
195  if (parseNumberValueAndUnit(baseString, m_animatedNumber, m_numberUnit))
196  return;
197  }
198  m_propertyType = StringProperty;
199 }
200 
201 void SVGAnimateElement::applyResultsToTarget()
202 {
203  String valueToApply;
204  if (m_propertyType == ColorProperty)
205  valueToApply = m_animatedColor.name();
206  else if (m_propertyType == NumberProperty)
207  valueToApply = String::number(m_animatedNumber) + m_numberUnit;
208  else
209  valueToApply = m_animatedString;
210 
211  setTargetAttributeAnimatedValue(valueToApply);
212 }
213 
214 float SVGAnimateElement::calculateDistance(const String& fromString, const String& toString)
215 {
216  m_propertyType = determinePropertyType(attributeName());
217  if (m_propertyType == NumberProperty) {
218  double from;
219  double to;
220  String unit;
221  if (!parseNumberValueAndUnit(fromString, from, unit))
222  return -1.f;
223  if (!parseNumberValueAndUnit(toString, to, unit))
224  return -1.f;
225  return narrowPrecisionToFloat(fabs(to - from));
226  } else if (m_propertyType == ColorProperty) {
227  Color from = SVGColor::colorFromRGBColorString(fromString);
228  if (!from.isValid())
229  return -1.f;
230  Color to = SVGColor::colorFromRGBColorString(toString);
231  if (!to.isValid())
232  return -1.f;
233  return ColorDistance(from, to).distance();
234  }
235  return -1.f;
236 }
237 
238 }
239 
240 // vim:ts=4:noet
241 #endif // ENABLE(SVG)
242 
SVGParserUtilities.h
ColorDistance.h
double
SVGAnimateElement.h
WebCore::narrowPrecisionToFloat
float narrowPrecisionToFloat(T)
WebCore::SVGNames::animateColorTag
DOM::QualifiedName animateColorTag
Definition: SVGNames.cpp:26
FloatConversion.h
WebCore::SVGNames::setTag
DOM::QualifiedName setTag
Definition: SVGNames.cpp:29
WebCore::SVGNames::animateTag
DOM::QualifiedName animateTag
Definition: SVGNames.cpp:25
ok
KGuiItem ok()
WebCore::String
DOM::DOMString String
Definition: PlatformString.h:8
parse
QList< Action > parse(QSettings &ini)
number
QString number(KIO::filesize_t size)
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:51:22 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KHTML

Skip menu "KHTML"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal