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

KHTML

  • 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
36namespace WebCore {
37
38using namespace SVGNames;
39
40SVGAnimateMotionElement::SVGAnimateMotionElement(const QualifiedName& tagName, Document* doc)
41 : SVGAnimationElement(tagName, doc)
42 , m_baseIndexInTransformList(0)
43 , m_angle(0)
44{
45}
46
47SVGAnimateMotionElement::~SVGAnimateMotionElement()
48{
49}
50
51bool 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
83void 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
92SVGAnimateMotionElement::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
104Path 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
120static 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
144void 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
155bool SVGAnimateMotionElement::calculateFromAndToValues(const String& fromString, const String& toString)
156{
157 parsePoint(fromString, m_fromPoint);
158 parsePoint(toString, m_toPoint);
159 return true;
160}
161
162bool 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
171void 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
207void 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
230float 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
RenderObject.h
SVGAnimateMotionElement.h
SVGElementInstance.h
SVGMPathElement.h
SVGParserUtilities.h
SVGPathElement.h
SVGTransformList.h
ok
KGuiItem ok()
end
const KShortcut & end()
WebCore
Definition: CSSHelper.h:7
WebCore::String
DOM::DOMString String
Definition: PlatformString.h:8
WebCore::Path
khtml::Path Path
Definition: PathTraversalState.h:37
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 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-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 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
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
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