KHTML
SVGGradientElement.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024 #include "wtf/Platform.h"
00025
00026 #if ENABLE(SVG)
00027 #include "SVGGradientElement.h"
00028
00029 #include "css/cssstyleselector.h"
00030 #include "RenderPath.h"
00031 #include "RenderSVGHiddenContainer.h"
00032 #include "SVGNames.h"
00033 #include "SVGPaintServerLinearGradient.h"
00034 #include "SVGPaintServerRadialGradient.h"
00035 #include "SVGStopElement.h"
00036 #include "SVGTransformList.h"
00037 #include "SVGTransformable.h"
00038 #include "SVGUnitTypes.h"
00039
00040 namespace WebCore {
00041
00042 SVGGradientElement::SVGGradientElement(const QualifiedName& tagName, Document* doc)
00043 : SVGStyledElement(tagName, doc)
00044 , SVGURIReference()
00045 , SVGExternalResourcesRequired()
00046 , m_spreadMethod(0)
00047 , m_gradientUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
00048 , m_gradientTransform(SVGTransformList::create(SVGNames::gradientTransformAttr))
00049 {
00050 }
00051
00052 SVGGradientElement::~SVGGradientElement()
00053 {
00054 }
00055
00056 ANIMATED_PROPERTY_DEFINITIONS(SVGGradientElement, int, Enumeration, enumeration, GradientUnits, gradientUnits, SVGNames::gradientUnitsAttr, m_gradientUnits)
00057 ANIMATED_PROPERTY_DEFINITIONS(SVGGradientElement, SVGTransformList*, TransformList, transformList, GradientTransform, gradientTransform, SVGNames::gradientTransformAttr, m_gradientTransform.get())
00058 ANIMATED_PROPERTY_DEFINITIONS(SVGGradientElement, int, Enumeration, enumeration, SpreadMethod, spreadMethod, SVGNames::spreadMethodAttr, m_spreadMethod)
00059
00060 void SVGGradientElement::parseMappedAttribute(MappedAttribute* attr)
00061 {
00062 if (attr->name() == SVGNames::gradientUnitsAttr) {
00063 if (attr->value() == "userSpaceOnUse")
00064 setGradientUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE);
00065 else if (attr->value() == "objectBoundingBox")
00066 setGradientUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX);
00067 } else if (attr->name() == SVGNames::gradientTransformAttr) {
00068 SVGTransformList* gradientTransforms = gradientTransformBaseValue();
00069 if (!SVGTransformable::parseTransformAttribute(gradientTransforms, attr->value())) {
00070 ExceptionCode ec = 0;
00071 gradientTransforms->clear(ec);
00072 }
00073 } else if (attr->name() == SVGNames::spreadMethodAttr) {
00074 if (attr->value() == "reflect")
00075 setSpreadMethodBaseValue(SVG_SPREADMETHOD_REFLECT);
00076 else if (attr->value() == "repeat")
00077 setSpreadMethodBaseValue(SVG_SPREADMETHOD_REPEAT);
00078 else if (attr->value() == "pad")
00079 setSpreadMethodBaseValue(SVG_SPREADMETHOD_PAD);
00080 } else {
00081 if (SVGURIReference::parseMappedAttribute(attr))
00082 return;
00083 if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
00084 return;
00085
00086 SVGStyledElement::parseMappedAttribute(attr);
00087 }
00088 }
00089
00090 void SVGGradientElement::svgAttributeChanged(const QualifiedName& attrName)
00091 {
00092 SVGStyledElement::svgAttributeChanged(attrName);
00093
00094 if (!m_resource)
00095 return;
00096
00097 if (attrName == SVGNames::gradientUnitsAttr ||
00098 attrName == SVGNames::gradientTransformAttr ||
00099 attrName == SVGNames::spreadMethodAttr ||
00100 SVGURIReference::isKnownAttribute(attrName) ||
00101 SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
00102 SVGStyledElement::isKnownAttribute(attrName))
00103 m_resource->invalidate();
00104 }
00105
00106 void SVGGradientElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
00107 {
00108 SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
00109
00110 if (m_resource)
00111 m_resource->invalidate();
00112 }
00113
00114 RenderObject* SVGGradientElement::createRenderer(RenderArena* arena, RenderStyle*)
00115 {
00116 return new (arena) RenderSVGHiddenContainer(this);
00117 }
00118
00119 SVGResource* SVGGradientElement::canvasResource()
00120 {
00121 kDebug() << "request gradient paint server" << endl;
00122 if (!m_resource) {
00123 if (gradientType() == LinearGradientPaintServer)
00124 m_resource = SVGPaintServerLinearGradient::create(this);
00125 else
00126 m_resource = SVGPaintServerRadialGradient::create(this);
00127 }
00128
00129 return m_resource.get();
00130 }
00131
00132 Vector<SVGGradientStop> SVGGradientElement::buildStops() const
00133 {
00134 Vector<SVGGradientStop> stops;
00135
00136 for (Node* n = firstChild(); n; n = n->nextSibling()) {
00137 SVGElement* element = n->isSVGElement() ? static_cast<SVGElement*>(n) : 0;
00138
00139 if (element && element->isGradientStop()) {
00140 SVGStopElement* stop = static_cast<SVGStopElement*>(element);
00141 float stopOffset = stop->offset();
00142
00143 RenderStyle* stopStyle = stop->computedStyle();
00144 QColor color = stopStyle->svgStyle()->stopColor();
00145 float opacity = stopStyle->svgStyle()->stopOpacity();
00146
00147 stops.append(makeGradientStop(stopOffset, QColor(color.red(), color.green(), color.blue(), int(opacity * 255.))));
00148 }
00149 }
00150
00151 return stops;
00152 }
00153
00154 }
00155
00156 #endif // ENABLE(SVG)