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

KHTML

  • khtml
  • svg
SVGAnimateTransformElement.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
3 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
4 Copyright (C) 2007 Eric Seidel <eric@webkit.org>
5 Copyright (C) 2008 Apple Inc. All Rights Reserved.
6
7 This file is part of the WebKit project
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
18
19 You should have received a copy of the GNU Library General Public License
20 along with this library; see the file COPYING.LIB. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA.
23*/
24
25#include "config.h"
26#if ENABLE(SVG) && ENABLE(SVG_ANIMATION)
27#include "SVGAnimateTransformElement.h"
28
29#include "AffineTransform.h"
30#include "RenderObject.h"
31#include "SVGAngle.h"
32#include "SVGElementInstance.h"
33#include "SVGParserUtilities.h"
34#include "SVGSVGElement.h"
35#include "SVGStyledTransformableElement.h"
36#include "SVGTextElement.h"
37#include "SVGTransform.h"
38#include "SVGTransformList.h"
39#include "SVGUseElement.h"
40
41#include <math.h>
42#include <wtf/MathExtras.h>
43
44using namespace std;
45
46namespace WebCore {
47
48SVGAnimateTransformElement::SVGAnimateTransformElement(const QualifiedName& tagName, Document* doc)
49 : SVGAnimationElement(tagName, doc)
50 , m_type(SVGTransform::SVG_TRANSFORM_UNKNOWN)
51 , m_baseIndexInTransformList(0)
52{
53}
54
55SVGAnimateTransformElement::~SVGAnimateTransformElement()
56{
57}
58
59bool SVGAnimateTransformElement::hasValidTarget() const
60{
61 SVGElement* targetElement = this->targetElement();
62 return SVGAnimationElement::hasValidTarget() && (targetElement->isStyledTransformable() || targetElement->hasTagName(SVGNames::textTag));
63}
64
65void SVGAnimateTransformElement::parseMappedAttribute(MappedAttribute* attr)
66{
67 if (attr->name() == SVGNames::typeAttr) {
68 if (attr->value() == "translate")
69 m_type = SVGTransform::SVG_TRANSFORM_TRANSLATE;
70 else if (attr->value() == "scale")
71 m_type = SVGTransform::SVG_TRANSFORM_SCALE;
72 else if (attr->value() == "rotate")
73 m_type = SVGTransform::SVG_TRANSFORM_ROTATE;
74 else if (attr->value() == "skewX")
75 m_type = SVGTransform::SVG_TRANSFORM_SKEWX;
76 else if (attr->value() == "skewY")
77 m_type = SVGTransform::SVG_TRANSFORM_SKEWY;
78 } else
79 SVGAnimationElement::parseMappedAttribute(attr);
80}
81
82
83static PassRefPtr<SVGTransformList> transformListFor(SVGElement* element)
84{
85 ASSERT(element);
86 if (element->isStyledTransformable())
87 return static_cast<SVGStyledTransformableElement*>(element)->transform();
88 if (element->hasTagName(SVGNames::textTag))
89 return static_cast<SVGTextElement*>(element)->transform();
90 return 0;
91}
92
93void SVGAnimateTransformElement::resetToBaseValue(const String& baseValue)
94{
95 if (!hasValidTarget())
96 return;
97 if (baseValue.isEmpty()) {
98 ExceptionCode ec;
99 RefPtr<SVGTransformList> list = transformListFor(targetElement());
100 list->clear(ec);
101 } else
102 targetElement()->setAttribute(SVGNames::transformAttr, baseValue);
103}
104
105void SVGAnimateTransformElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement)
106{
107 if (!hasValidTarget())
108 return;
109 SVGElement* targetElement = resultElement->targetElement();
110 RefPtr<SVGTransformList> transformList = transformListFor(targetElement);
111 ASSERT(transformList);
112
113 ExceptionCode ec;
114 if (!isAdditive())
115 transformList->clear(ec);
116 if (isAccumulated() && repeat) {
117 SVGTransform accumulatedTransform = SVGTransformDistance(m_fromTransform, m_toTransform).scaledDistance(repeat).addToSVGTransform(SVGTransform());
118 transformList->appendItem(accumulatedTransform, ec);
119 }
120 SVGTransform transform = SVGTransformDistance(m_fromTransform, m_toTransform).scaledDistance(percentage).addToSVGTransform(m_fromTransform);
121 transformList->appendItem(transform, ec);
122}
123
124bool SVGAnimateTransformElement::calculateFromAndToValues(const String& fromString, const String& toString)
125{
126 m_fromTransform = parseTransformValue(fromString);
127 if (!m_fromTransform.isValid())
128 return false;
129 m_toTransform = parseTransformValue(toString);
130 return m_toTransform.isValid();
131}
132
133bool SVGAnimateTransformElement::calculateFromAndByValues(const String& fromString, const String& byString)
134{
135
136 m_fromTransform = parseTransformValue(fromString);
137 if (!m_fromTransform.isValid())
138 return false;
139 m_toTransform = SVGTransformDistance::addSVGTransforms(m_fromTransform, parseTransformValue(byString));
140 return m_toTransform.isValid();
141}
142
143SVGTransform SVGAnimateTransformElement::parseTransformValue(const String& value) const
144{
145 if (value.isEmpty())
146 return SVGTransform(m_type);
147 SVGTransform result;
148 // FIXME: This is pretty dumb but parseTransformValue() wants those parenthesis.
149 String parseString("(" + value + ")");
150 const UChar* ptr = parseString.characters();
151 SVGTransformable::parseTransformValue(m_type, ptr, ptr + parseString.length(), result); // ignoring return value
152 return result;
153}
154
155void SVGAnimateTransformElement::applyResultsToTarget()
156{
157 if (!hasValidTarget())
158 return;
159 // We accumulate to the target element transform list so there is not much to do here.
160 SVGElement* targetElement = this->targetElement();
161 if (targetElement->renderer())
162 targetElement->renderer()->setNeedsLayout(true);
163
164 // ...except in case where we have additional instances in <use> trees.
165 HashSet<SVGElementInstance*>* instances = document()->accessSVGExtensions()->instancesForElement(targetElement);
166 if (!instances)
167 return;
168 RefPtr<SVGTransformList> transformList = transformListFor(targetElement);
169 HashSet<SVGElementInstance*>::iterator end = instances->end();
170 for (HashSet<SVGElementInstance*>::iterator it = instances->begin(); it != end; ++it) {
171 SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
172 ASSERT(shadowTreeElement);
173 if (shadowTreeElement->isStyledTransformable())
174 static_cast<SVGStyledTransformableElement*>(shadowTreeElement)->setTransform(transformList.get());
175 else if (shadowTreeElement->hasTagName(SVGNames::textTag))
176 static_cast<SVGTextElement*>(shadowTreeElement)->setTransform(transformList.get());
177 if (shadowTreeElement->renderer())
178 shadowTreeElement->renderer()->setNeedsLayout(true);
179 }
180}
181
182float SVGAnimateTransformElement::calculateDistance(const String& fromString, const String& toString)
183{
184 // FIXME: This is not correct in all cases. The spec demands that each component (translate x and y for example)
185 // is paced separately. To implement this we need to treat each component as individual animation everywhere.
186 SVGTransform from = parseTransformValue(fromString);
187 if (!from.isValid())
188 return -1.f;
189 SVGTransform to = parseTransformValue(toString);
190 if (!to.isValid() || from.type() != to.type())
191 return -1.f;
192 if (to.type() == SVGTransform::SVG_TRANSFORM_TRANSLATE) {
193 FloatSize diff = to.translate() - from.translate();
194 return sqrtf(diff.width() * diff.width() + diff.height() * diff.height());
195 }
196 if (to.type() == SVGTransform::SVG_TRANSFORM_ROTATE)
197 return fabsf(to.angle() - from.angle());
198 if (to.type() == SVGTransform::SVG_TRANSFORM_SCALE) {
199 FloatSize diff = to.scale() - from.scale();
200 return sqrtf(diff.width() * diff.width() + diff.height() * diff.height());
201 }
202 return -1.f;
203}
204
205}
206
207// vim:ts=4:noet
208#endif // ENABLE(SVG)
209
AffineTransform.h
RenderObject.h
SVGAngle.h
SVGAnimateTransformElement.h
SVGElementInstance.h
SVGParserUtilities.h
SVGSVGElement.h
SVGStyledTransformableElement.h
SVGTextElement.h
SVGTransformList.h
SVGTransform.h
SVGUseElement.h
list
QStringList list(const QString &fileClass)
end
const KShortcut & end()
WebCore
Definition: CSSHelper.h:7
WebCore::String
DOM::DOMString String
Definition: PlatformString.h:8
khtml::ExceptionCode
unsigned short ExceptionCode
Definition: ExceptionCode.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