1 /*
2 * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #include "config.h"
22
23 #if ENABLE(SVG)
24 #include "SVGStyledTransformableElement.h"
25
26 #include "AffineTransform.h"
27 #include "Attribute.h"
28 #include "RenderSVGPath.h"
29 #include "RenderSVGResource.h"
30 #include "SVGNames.h"
31
32 namespace WebCore {
33
34 // Animated property definitions
DEFINE_ANIMATED_TRANSFORM_LIST(SVGStyledTransformableElement,SVGNames::transformAttr,Transform,transform)35 DEFINE_ANIMATED_TRANSFORM_LIST(SVGStyledTransformableElement, SVGNames::transformAttr, Transform, transform)
36
37 SVGStyledTransformableElement::SVGStyledTransformableElement(const QualifiedName& tagName, Document* document)
38 : SVGStyledLocatableElement(tagName, document)
39 {
40 }
41
~SVGStyledTransformableElement()42 SVGStyledTransformableElement::~SVGStyledTransformableElement()
43 {
44 }
45
getCTM(StyleUpdateStrategy styleUpdateStrategy) const46 AffineTransform SVGStyledTransformableElement::getCTM(StyleUpdateStrategy styleUpdateStrategy) const
47 {
48 return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope, styleUpdateStrategy);
49 }
50
getScreenCTM(StyleUpdateStrategy styleUpdateStrategy) const51 AffineTransform SVGStyledTransformableElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy) const
52 {
53 return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope, styleUpdateStrategy);
54 }
55
animatedLocalTransform() const56 AffineTransform SVGStyledTransformableElement::animatedLocalTransform() const
57 {
58 AffineTransform matrix;
59 transform().concatenate(matrix);
60 if (m_supplementalTransform)
61 matrix *= *m_supplementalTransform;
62 return matrix;
63 }
64
supplementalTransform()65 AffineTransform* SVGStyledTransformableElement::supplementalTransform()
66 {
67 if (!m_supplementalTransform)
68 m_supplementalTransform.set(new AffineTransform());
69 return m_supplementalTransform.get();
70 }
71
parseMappedAttribute(Attribute * attr)72 void SVGStyledTransformableElement::parseMappedAttribute(Attribute* attr)
73 {
74 if (SVGTransformable::isKnownAttribute(attr->name())) {
75 SVGTransformList newList;
76 if (!SVGTransformable::parseTransformAttribute(newList, attr->value()))
77 newList.clear();
78 detachAnimatedTransformListWrappers(newList.size());
79 setTransformBaseValue(newList);
80 } else
81 SVGStyledLocatableElement::parseMappedAttribute(attr);
82 }
83
svgAttributeChanged(const QualifiedName & attrName)84 void SVGStyledTransformableElement::svgAttributeChanged(const QualifiedName& attrName)
85 {
86 SVGStyledLocatableElement::svgAttributeChanged(attrName);
87
88 if (!SVGStyledTransformableElement::isKnownAttribute(attrName))
89 return;
90
91 RenderObject* object = renderer();
92 if (!object)
93 return;
94
95 object->setNeedsTransformUpdate();
96 RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
97 }
98
synchronizeProperty(const QualifiedName & attrName)99 void SVGStyledTransformableElement::synchronizeProperty(const QualifiedName& attrName)
100 {
101 SVGStyledLocatableElement::synchronizeProperty(attrName);
102
103 if (attrName == anyQName() || SVGTransformable::isKnownAttribute(attrName))
104 synchronizeTransform();
105 }
106
isKnownAttribute(const QualifiedName & attrName)107 bool SVGStyledTransformableElement::isKnownAttribute(const QualifiedName& attrName)
108 {
109 return SVGTransformable::isKnownAttribute(attrName) || SVGStyledLocatableElement::isKnownAttribute(attrName);
110 }
111
nearestViewportElement() const112 SVGElement* SVGStyledTransformableElement::nearestViewportElement() const
113 {
114 return SVGTransformable::nearestViewportElement(this);
115 }
116
farthestViewportElement() const117 SVGElement* SVGStyledTransformableElement::farthestViewportElement() const
118 {
119 return SVGTransformable::farthestViewportElement(this);
120 }
121
getBBox(StyleUpdateStrategy styleUpdateStrategy) const122 FloatRect SVGStyledTransformableElement::getBBox(StyleUpdateStrategy styleUpdateStrategy) const
123 {
124 return SVGTransformable::getBBox(this, styleUpdateStrategy);
125 }
126
createRenderer(RenderArena * arena,RenderStyle *)127 RenderObject* SVGStyledTransformableElement::createRenderer(RenderArena* arena, RenderStyle*)
128 {
129 // By default, any subclass is expected to do path-based drawing
130 return new (arena) RenderSVGPath(this);
131 }
132
fillPassedAttributeToPropertyTypeMap(AttributeToPropertyTypeMap & attributeToPropertyTypeMap)133 void SVGStyledTransformableElement::fillPassedAttributeToPropertyTypeMap(AttributeToPropertyTypeMap& attributeToPropertyTypeMap)
134 {
135 SVGStyledElement::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap);
136
137 attributeToPropertyTypeMap.set(SVGNames::transformAttr, AnimatedTransformList);
138 }
139
toClipPath(Path & path) const140 void SVGStyledTransformableElement::toClipPath(Path& path) const
141 {
142 toPathData(path);
143 // FIXME: How do we know the element has done a layout?
144 path.transform(animatedLocalTransform());
145 }
146
147 }
148
149 #endif // ENABLE(SVG)
150