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.
24 #include "wtf/Platform.h"
27 #include "SVGGradientElement.h"
29 #include "CSSStyleSelector.h"
30 #include "RenderPath.h"
31 #include "RenderSVGHiddenContainer.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"
42 SVGGradientElement::SVGGradientElement(const QualifiedName
& tagName
, Document
* doc
)
43 : SVGStyledElement(tagName
, doc
)
45 , SVGExternalResourcesRequired()
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())) {
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
);
81 if (SVGURIReference::parseMappedAttribute(attr
))
83 if (SVGExternalResourcesRequired::parseMappedAttribute(attr
))
86 SVGStyledElement::parseMappedAttribute(attr
);
90 void SVGGradientElement::svgAttributeChanged(const QualifiedName
& attrName
)
92 SVGStyledElement::svgAttributeChanged(attrName
);
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
);
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
;
123 if (gradientType() == LinearGradientPaintServer
)
124 m_resource
= SVGPaintServerLinearGradient::create(this);
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();
147 if (stop
->renderer()) {
148 RenderStyle
* stopStyle
= stop
->renderer()->style();
149 color
= stopStyle
->svgStyle()->stopColor();
150 opacity
= stopStyle
->svgStyle()->stopOpacity();
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
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.))));
171 gradientStyle->deref(document()->renderArena());*/
178 #endif // ENABLE(SVG)