• 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
SVGAnimateMotionElement.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
3  (C) 2007 Rob Buis <buis@kde.org>
4  Copyright (C) 2008 Apple Inc. All Rights Reserved.
5 
6  This file is part of the WebKit 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 "SVGAnimateMotionElement.h"
27 
28 #include "RenderObject.h"
29 #include "SVGElementInstance.h"
30 #include "SVGMPathElement.h"
31 #include "SVGParserUtilities.h"
32 #include "SVGPathElement.h"
33 #include "SVGTransformList.h"
34 #include <math.h>
35 
36 namespace WebCore {
37 
38 using namespace SVGNames;
39 
40 SVGAnimateMotionElement::SVGAnimateMotionElement(const QualifiedName& tagName, Document* doc)
41  : SVGAnimationElement(tagName, doc)
42  , m_baseIndexInTransformList(0)
43  , m_angle(0)
44 {
45 }
46 
47 SVGAnimateMotionElement::~SVGAnimateMotionElement()
48 {
49 }
50 
51 bool SVGAnimateMotionElement::hasValidTarget() const
52 {
53  if (!SVGAnimationElement::hasValidTarget())
54  return false;
55  SVGElement* targetElement = this->targetElement();
56  if (!targetElement->isStyledTransformable() && !targetElement->hasTagName(SVGNames::textTag))
57  return false;
58  // Spec: SVG 1.1 section 19.2.15
59  if (targetElement->hasTagName(gTag)
60  || targetElement->hasTagName(defsTag)
61  || targetElement->hasTagName(useTag)
62  || targetElement->hasTagName(imageTag)
63  || targetElement->hasTagName(switchTag)
64  || targetElement->hasTagName(pathTag)
65  || targetElement->hasTagName(rectTag)
66  || targetElement->hasTagName(circleTag)
67  || targetElement->hasTagName(ellipseTag)
68  || targetElement->hasTagName(lineTag)
69  || targetElement->hasTagName(polylineTag)
70  || targetElement->hasTagName(polygonTag)
71  || targetElement->hasTagName(textTag)
72  || targetElement->hasTagName(clipPathTag)
73  || targetElement->hasTagName(maskTag)
74  || targetElement->hasTagName(aTag)
75 #if ENABLE(SVG_FOREIGN_OBJECT)
76  || targetElement->hasTagName(foreignObjectTag)
77 #endif
78  )
79  return true;
80  return false;
81 }
82 
83 void SVGAnimateMotionElement::parseMappedAttribute(MappedAttribute* attr)
84 {
85  if (attr->name() == SVGNames::pathAttr) {
86  m_path = Path();
87  pathFromSVGData(m_path, attr->value());
88  } else
89  SVGAnimationElement::parseMappedAttribute(attr);
90 }
91 
92 SVGAnimateMotionElement::RotateMode SVGAnimateMotionElement::rotateMode() const
93 {
94  static const AtomicString autoVal("auto");
95  static const AtomicString autoReverse("auto-reverse");
96  String rotate = getAttribute(SVGNames::rotateAttr);
97  if (rotate == autoVal)
98  return RotateAuto;
99  if (rotate == autoReverse)
100  return RotateAutoReverse;
101  return RotateAngle;
102 }
103 
104 Path SVGAnimateMotionElement::animationPath() const
105 {
106  for (Node* child = firstChild(); child; child = child->nextSibling()) {
107  if (child->hasTagName(SVGNames::mpathTag)) {
108  SVGMPathElement* mPath = static_cast<SVGMPathElement*>(child);
109  SVGPathElement* pathElement = mPath->pathElement();
110  if (pathElement)
111  return pathElement->toPathData();
112  return Path();
113  }
114  }
115  if (hasAttribute(SVGNames::pathAttr))
116  return m_path;
117  return Path();
118 }
119 
120 static bool parsePoint(const String& s, FloatPoint& point)
121 {
122  if (s.isEmpty())
123  return false;
124  const UChar* cur = s.characters();
125  const UChar* end = cur + s.length();
126 
127  if (!skipOptionalSpaces(cur, end))
128  return false;
129 
130  float x = 0.0f;
131  if (!parseNumber(cur, end, x))
132  return false;
133 
134  float y = 0.0f;
135  if (!parseNumber(cur, end, y))
136  return false;
137 
138  point = FloatPoint(x, y);
139 
140  // disallow anything except spaces at the end
141  return !skipOptionalSpaces(cur, end);
142 }
143 
144 void SVGAnimateMotionElement::resetToBaseValue(const String&)
145 {
146  if (!hasValidTarget())
147  return;
148  SVGElement* target = targetElement();
149  AffineTransform* transform = target->supplementalTransform();
150  if (!transform)
151  return;
152  transform->reset();
153 }
154 
155 bool SVGAnimateMotionElement::calculateFromAndToValues(const String& fromString, const String& toString)
156 {
157  parsePoint(fromString, m_fromPoint);
158  parsePoint(toString, m_toPoint);
159  return true;
160 }
161 
162 bool SVGAnimateMotionElement::calculateFromAndByValues(const String& fromString, const String& byString)
163 {
164  parsePoint(fromString, m_fromPoint);
165  FloatPoint byPoint;
166  parsePoint(byString, byPoint);
167  m_toPoint = FloatPoint(m_fromPoint.x() + byPoint.x(), m_fromPoint.y() + byPoint.y());
168  return true;
169 }
170 
171 void SVGAnimateMotionElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement*)
172 {
173  SVGElement* target = targetElement();
174  if (!target)
175  return;
176  AffineTransform* transform = target->supplementalTransform();
177  if (!transform)
178  return;
179 
180  if (!isAdditive())
181  transform->reset();
182 
183  // FIXME: Implement accumulate.
184 
185  if (animationMode() == PathAnimation) {
186  ASSERT(!animationPath().isEmpty());
187  Path path = animationPath();
188  float positionOnPath = path.length() * percentage;
189  bool ok;
190  FloatPoint position = path.pointAtLength(positionOnPath, ok);
191  if (ok) {
192  transform->translate(position.x(), position.y());
193  RotateMode rotateMode = this->rotateMode();
194  if (rotateMode == RotateAuto || rotateMode == RotateAutoReverse) {
195  float angle = path.normalAngleAtLength(positionOnPath, ok);
196  if (rotateMode == RotateAutoReverse)
197  angle += 180.f;
198  transform->rotate(angle);
199  }
200  }
201  return;
202  }
203  FloatSize diff = m_toPoint - m_fromPoint;
204  transform->translate(diff.width() * percentage + m_fromPoint.x(), diff.height() * percentage + m_fromPoint.y());
205 }
206 
207 void SVGAnimateMotionElement::applyResultsToTarget()
208 {
209  // We accumulate to the target element transform list so there is not much to do here.
210  SVGElement* targetElement = this->targetElement();
211  if (targetElement && targetElement->renderer())
212  targetElement->renderer()->setNeedsLayout(true);
213 
214  // ...except in case where we have additional instances in <use> trees.
215  HashSet<SVGElementInstance*>* instances = document()->accessSVGExtensions()->instancesForElement(targetElement);
216  if (!instances)
217  return;
218  HashSet<SVGElementInstance*>::iterator end = instances->end();
219  for (HashSet<SVGElementInstance*>::iterator it = instances->begin(); it != end; ++it) {
220  SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
221  ASSERT(shadowTreeElement);
222  AffineTransform* transform = shadowTreeElement->supplementalTransform();
223  AffineTransform* t = targetElement->supplementalTransform();
224  transform->setMatrix(t->a(), t->b(), t->c(), t->d(), t->e(), t->f());
225  if (shadowTreeElement->renderer())
226  shadowTreeElement->renderer()->setNeedsLayout(true);
227  }
228 }
229 
230 float SVGAnimateMotionElement::calculateDistance(const String& fromString, const String& toString)
231 {
232  FloatPoint from;
233  FloatPoint to;
234  if (!parsePoint(fromString, from))
235  return -1.f;
236  if (!parsePoint(toString, to))
237  return -1.f;
238  FloatSize diff = to - from;
239  return sqrtf(diff.width() * diff.width() + diff.height() * diff.height());
240 }
241 
242 }
243 
244 #endif // ENABLE(SVG)
245 
246 // vim:ts=4:noet
WebCore::SVGNames::useTag
DOM::QualifiedName useTag
Definition: SVGNames.cpp:99
WebCore::SVGNames::polylineTag
DOM::QualifiedName polylineTag
Definition: SVGNames.cpp:85
SVGParserUtilities.h
WebCore::SVGNames::polygonTag
DOM::QualifiedName polygonTag
Definition: SVGNames.cpp:84
WebCore::SVGNames::aTag
DOM::QualifiedName aTag
Definition: SVGNames.cpp:21
SVGAnimateMotionElement.h
WebCore::SVGNames::circleTag
DOM::QualifiedName circleTag
Definition: SVGNames.cpp:30
WebCore::SVGNames::lineTag
DOM::QualifiedName lineTag
Definition: SVGNames.cpp:75
WebCore::SVGNames::ellipseTag
DOM::QualifiedName ellipseTag
Definition: SVGNames.cpp:37
WebCore::Path
khtml::Path Path
Definition: PathTraversalState.h:37
SVGPathElement.h
WebCore::SVGNames::rectTag
DOM::QualifiedName rectTag
Definition: SVGNames.cpp:87
WebCore::SVGNames::pathTag
DOM::QualifiedName pathTag
Definition: SVGNames.cpp:82
SVGMPathElement.h
WebCore::SVGNames::maskTag
DOM::QualifiedName maskTag
Definition: SVGNames.cpp:78
WebCore::SVGNames::imageTag
DOM::QualifiedName imageTag
Definition: SVGNames.cpp:74
ok
KGuiItem ok()
WebCore::SVGNames::switchTag
DOM::QualifiedName switchTag
Definition: SVGNames.cpp:92
WebCore::SVGNames::mpathTag
DOM::QualifiedName mpathTag
Definition: SVGNames.cpp:81
WebCore::SVGNames::pathAttr
DOM::QualifiedName pathAttr
Definition: SVGNames.cpp:247
WebCore::SVGNames::gTag
DOM::QualifiedName gTag
Definition: SVGNames.cpp:70
SVGTransformList.h
WebCore::SVGNames::rotateAttr
DOM::QualifiedName rotateAttr
Definition: SVGNames.cpp:271
WebCore::SVGNames::foreignObjectTag
DOM::QualifiedName foreignObjectTag
Definition: SVGNames.cpp:69
SVGElementInstance.h
WebCore::String
DOM::DOMString String
Definition: PlatformString.h:8
RenderObject.h
end
const KShortcut & end()
WebCore::SVGNames::defsTag
DOM::QualifiedName defsTag
Definition: SVGNames.cpp:35
WebCore::SVGNames::clipPathTag
DOM::QualifiedName clipPathTag
Definition: SVGNames.cpp:31
WebCore::SVGNames::textTag
DOM::QualifiedName textTag
Definition: SVGNames.cpp:94
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