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

KHTML

  • sources
  • kde-4.14
  • kdelibs
  • 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 
44 using namespace std;
45 
46 namespace WebCore {
47 
48 SVGAnimateTransformElement::SVGAnimateTransformElement(const QualifiedName& tagName, Document* doc)
49  : SVGAnimationElement(tagName, doc)
50  , m_type(SVGTransform::SVG_TRANSFORM_UNKNOWN)
51  , m_baseIndexInTransformList(0)
52 {
53 }
54 
55 SVGAnimateTransformElement::~SVGAnimateTransformElement()
56 {
57 }
58 
59 bool SVGAnimateTransformElement::hasValidTarget() const
60 {
61  SVGElement* targetElement = this->targetElement();
62  return SVGAnimationElement::hasValidTarget() && (targetElement->isStyledTransformable() || targetElement->hasTagName(SVGNames::textTag));
63 }
64 
65 void 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 
83 static 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 
93 void 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 
105 void 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 
124 bool 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 
133 bool 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 
143 SVGTransform 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 
155 void 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 
182 float 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 
SVGTextElement.h
SVGAngle.h
SVGParserUtilities.h
WebCore::SVGNames::transformAttr
DOM::QualifiedName transformAttr
Definition: SVGNames.cpp:312
WebCore::XLinkNames::typeAttr
DOM::QualifiedName typeAttr
Definition: SVGNames.cpp:17
SVGAnimateTransformElement.h
SVGSVGElement.h
SVGStyledTransformableElement.h
AffineTransform.h
SVGUseElement.h
SVGTransform.h
SVGTransformList.h
SVGElementInstance.h
WebCore::String
DOM::DOMString String
Definition: PlatformString.h:8
RenderObject.h
end
const KShortcut & end()
WebCore::SVGNames::textTag
DOM::QualifiedName textTag
Definition: SVGNames.cpp:94
list
QStringList list(const QString &fileClass)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:26:19 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
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • 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