don't discard iframe children.
[kdelibs.git] / khtml / svg / SVGGradientElement.cpp
blobbab72d49171b3f6ec92262f5d01d431ae1910cd4
1 /*
2 Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
5 This file is part of the KDE project
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
23 #include "config.h"
24 #include "wtf/Platform.h"
26 #if ENABLE(SVG)
27 #include "SVGGradientElement.h"
29 #include "CSSStyleSelector.h"
30 #include "RenderPath.h"
31 #include "RenderSVGHiddenContainer.h"
32 #include "SVGNames.h"
33 #include "SVGPaintServerLinearGradient.h"
34 #include "SVGPaintServerRadialGradient.h"
35 #include "SVGStopElement.h"
36 #include "SVGTransformList.h"
37 #include "SVGTransformable.h"
38 #include "SVGUnitTypes.h"
40 namespace WebCore {
42 SVGGradientElement::SVGGradientElement(const QualifiedName& tagName, Document* doc)
43 : SVGStyledElement(tagName, doc)
44 , SVGURIReference()
45 , SVGExternalResourcesRequired()
46 , m_spreadMethod(0)
47 , m_gradientUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
48 , m_gradientTransform(SVGTransformList::create(SVGNames::gradientTransformAttr))
52 SVGGradientElement::~SVGGradientElement()
56 ANIMATED_PROPERTY_DEFINITIONS(SVGGradientElement, int, Enumeration, enumeration, GradientUnits, gradientUnits, SVGNames::gradientUnitsAttr, m_gradientUnits)
57 ANIMATED_PROPERTY_DEFINITIONS(SVGGradientElement, SVGTransformList*, TransformList, transformList, GradientTransform, gradientTransform, SVGNames::gradientTransformAttr, m_gradientTransform.get())
58 ANIMATED_PROPERTY_DEFINITIONS(SVGGradientElement, int, Enumeration, enumeration, SpreadMethod, spreadMethod, SVGNames::spreadMethodAttr, m_spreadMethod)
60 void SVGGradientElement::parseMappedAttribute(MappedAttribute* attr)
62 if (attr->name() == SVGNames::gradientUnitsAttr) {
63 if (attr->value() == "userSpaceOnUse")
64 setGradientUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE);
65 else if (attr->value() == "objectBoundingBox")
66 setGradientUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX);
67 } else if (attr->name() == SVGNames::gradientTransformAttr) {
68 SVGTransformList* gradientTransforms = gradientTransformBaseValue();
69 if (!SVGTransformable::parseTransformAttribute(gradientTransforms, attr->value())) {
70 ExceptionCode ec = 0;
71 gradientTransforms->clear(ec);
73 } else if (attr->name() == SVGNames::spreadMethodAttr) {
74 if (attr->value() == "reflect")
75 setSpreadMethodBaseValue(SVG_SPREADMETHOD_REFLECT);
76 else if (attr->value() == "repeat")
77 setSpreadMethodBaseValue(SVG_SPREADMETHOD_REPEAT);
78 else if (attr->value() == "pad")
79 setSpreadMethodBaseValue(SVG_SPREADMETHOD_PAD);
80 } else {
81 if (SVGURIReference::parseMappedAttribute(attr))
82 return;
83 if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
84 return;
86 SVGStyledElement::parseMappedAttribute(attr);
90 void SVGGradientElement::svgAttributeChanged(const QualifiedName& attrName)
92 SVGStyledElement::svgAttributeChanged(attrName);
94 if (!m_resource)
95 return;
97 if (attrName == SVGNames::gradientUnitsAttr ||
98 attrName == SVGNames::gradientTransformAttr ||
99 attrName == SVGNames::spreadMethodAttr ||
100 SVGURIReference::isKnownAttribute(attrName) ||
101 SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
102 SVGStyledElement::isKnownAttribute(attrName))
103 m_resource->invalidate();
106 void SVGGradientElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
108 SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
110 if (m_resource)
111 m_resource->invalidate();
114 RenderObject* SVGGradientElement::createRenderer(RenderArena* arena, RenderStyle*)
116 return new (arena) RenderSVGHiddenContainer(this);
119 SVGResource* SVGGradientElement::canvasResource()
121 kDebug() << "request gradient paint server" << endl;
122 if (!m_resource) {
123 if (gradientType() == LinearGradientPaintServer)
124 m_resource = SVGPaintServerLinearGradient::create(this);
125 else
126 m_resource = SVGPaintServerRadialGradient::create(this);
129 return m_resource.get();
132 Vector<SVGGradientStop> SVGGradientElement::buildStops() const
134 Vector<SVGGradientStop> stops;
135 RenderStyle* gradientStyle = 0;
137 for (Node* n = firstChild(); n; n = n->nextSibling()) {
138 SVGElement* element = n->isSVGElement() ? static_cast<SVGElement*>(n) : 0;
140 if (element && element->isGradientStop()) {
141 SVGStopElement* stop = static_cast<SVGStopElement*>(element);
142 float stopOffset = stop->offset();
144 Color color;
145 float opacity;
147 if (stop->renderer()) {
148 RenderStyle* stopStyle = stop->renderer()->style();
149 color = stopStyle->svgStyle()->stopColor();
150 opacity = stopStyle->svgStyle()->stopOpacity();
151 } else {
152 // If there is no renderer for this stop element, then a parent element
153 // set display="none" - ie. <g display="none"><linearGradient><stop>..
154 // Unfortunately we have to manually rebuild the stop style. See pservers-grad-19-b.svg
155 if (!gradientStyle)
156 gradientStyle = const_cast<SVGGradientElement*>(this)->styleForRenderer(parent()->renderer());
158 RenderStyle* stopStyle = stop->resolveStyle(gradientStyle);
160 color = stopStyle->svgStyle()->stopColor();
161 opacity = stopStyle->svgStyle()->stopOpacity();
163 /*stopStyle->deref(document()->renderArena());*/
166 stops.append(makeGradientStop(stopOffset, qRgba(color.red(), color.green(), color.blue(), int(opacity * 255.))));
170 /*if (gradientStyle)
171 gradientStyle->deref(document()->renderArena());*/
173 return stops;
178 #endif // ENABLE(SVG)