initial import
[vuplus_webkit] / Source / WebCore / svg / SVGStyledTransformableElement.cpp
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 "SVGElementInstance.h"
31 #include "SVGNames.h"
32
33 namespace WebCore {
34
35 // Animated property definitions
36 DEFINE_ANIMATED_TRANSFORM_LIST(SVGStyledTransformableElement, SVGNames::transformAttr, Transform, transform)
37
38 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGStyledTransformableElement)
39     REGISTER_LOCAL_ANIMATED_PROPERTY(transform)
40     REGISTER_PARENT_ANIMATED_PROPERTIES(SVGStyledLocatableElement)
41 END_REGISTER_ANIMATED_PROPERTIES
42
43 SVGStyledTransformableElement::SVGStyledTransformableElement(const QualifiedName& tagName, Document* document)
44     : SVGStyledLocatableElement(tagName, document)
45 {
46     registerAnimatedPropertiesForSVGStyledTransformableElement();
47 }
48
49 SVGStyledTransformableElement::~SVGStyledTransformableElement()
50 {
51 }
52
53 AffineTransform SVGStyledTransformableElement::getCTM(StyleUpdateStrategy styleUpdateStrategy)
54 {
55     return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope, styleUpdateStrategy);
56 }
57
58 AffineTransform SVGStyledTransformableElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy)
59 {
60     return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope, styleUpdateStrategy);
61 }
62
63 AffineTransform SVGStyledTransformableElement::animatedLocalTransform() const
64 {
65     AffineTransform matrix;
66     transform().concatenate(matrix);
67     if (m_supplementalTransform)
68         return *m_supplementalTransform * matrix;
69     return matrix;
70 }
71
72 AffineTransform* SVGStyledTransformableElement::supplementalTransform()
73 {
74     if (!m_supplementalTransform)
75         m_supplementalTransform = adoptPtr(new AffineTransform);
76     return m_supplementalTransform.get();
77 }
78
79 bool SVGStyledTransformableElement::isSupportedAttribute(const QualifiedName& attrName)
80 {
81     DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
82     if (supportedAttributes.isEmpty())
83         supportedAttributes.add(SVGNames::transformAttr);
84     return supportedAttributes.contains(attrName);
85 }
86
87 void SVGStyledTransformableElement::parseMappedAttribute(Attribute* attr)
88 {
89     if (!isSupportedAttribute(attr->name())) {
90         SVGStyledLocatableElement::parseMappedAttribute(attr);
91         return;
92     }
93
94     if (attr->name() == SVGNames::transformAttr) {
95         SVGTransformList newList;
96         if (!SVGTransformable::parseTransformAttribute(newList, attr->value()))
97             newList.clear();
98         detachAnimatedTransformListWrappers(newList.size());
99         setTransformBaseValue(newList);
100         return;
101     }
102
103     ASSERT_NOT_REACHED();
104 }
105
106 void SVGStyledTransformableElement::svgAttributeChanged(const QualifiedName& attrName)
107 {
108     if (!isSupportedAttribute(attrName)) {
109         SVGStyledLocatableElement::svgAttributeChanged(attrName);
110         return;
111     }
112
113     SVGElementInstance::InvalidationGuard invalidationGuard(this);
114
115     RenderObject* object = renderer();
116     if (!object)
117         return;
118
119     if (attrName == SVGNames::transformAttr) {
120         object->setNeedsTransformUpdate();
121         RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
122         return;
123     }
124
125     ASSERT_NOT_REACHED();
126 }
127
128 SVGElement* SVGStyledTransformableElement::nearestViewportElement() const
129 {
130     return SVGTransformable::nearestViewportElement(this);
131 }
132
133 SVGElement* SVGStyledTransformableElement::farthestViewportElement() const
134 {
135     return SVGTransformable::farthestViewportElement(this);
136 }
137
138 FloatRect SVGStyledTransformableElement::getBBox(StyleUpdateStrategy styleUpdateStrategy)
139 {
140     return SVGTransformable::getBBox(this, styleUpdateStrategy);
141 }
142
143 RenderObject* SVGStyledTransformableElement::createRenderer(RenderArena* arena, RenderStyle*)
144 {
145     // By default, any subclass is expected to do path-based drawing
146     return new (arena) RenderSVGPath(this);
147 }
148
149 void SVGStyledTransformableElement::toClipPath(Path& path)
150 {
151     toPathData(path);
152     // FIXME: How do we know the element has done a layout?
153     path.transform(animatedLocalTransform());
154 }
155
156 }
157
158 #endif // ENABLE(SVG)