fix tricky regression noticed by Vyacheslav Tokarev on Google Reader.
[kdelibs.git] / khtml / svg / SVGMarkerElement.cpp
blob60d6a51331ad79c59081d34f0a7e6feb58226430
1 /*
2 Copyright (C) 2004, 2005, 2006, 2007, 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"
25 #if ENABLE(SVG)
26 #include "SVGMarkerElement.h"
28 #include "PlatformString.h"
29 #include "RenderSVGViewportContainer.h"
30 #include "SVGAngle.h"
31 #include "SVGFitToViewBox.h"
32 #include "SVGLength.h"
33 #include "SVGNames.h"
34 #include "SVGPreserveAspectRatio.h"
35 #include "SVGSVGElement.h"
37 namespace WebCore {
39 SVGMarkerElement::SVGMarkerElement(const QualifiedName& tagName, Document* doc)
40 : SVGStyledElement(tagName, doc)
41 , SVGLangSpace()
42 , SVGExternalResourcesRequired()
43 , SVGFitToViewBox()
44 , m_refX(this, LengthModeWidth)
45 , m_refY(this, LengthModeHeight)
46 , m_markerWidth(this, LengthModeWidth)
47 , m_markerHeight(this, LengthModeHeight)
48 , m_markerUnits(SVG_MARKERUNITS_STROKEWIDTH)
49 , m_orientType(0)
50 , m_orientAngle(new SVGAngle())
52 // Spec: If the attribute is not specified, the effect is as if a value of "3" were specified.
53 setMarkerWidthBaseValue(SVGLength(this, LengthModeWidth, "3"));
54 setMarkerHeightBaseValue(SVGLength(this, LengthModeHeight, "3"));
57 SVGMarkerElement::~SVGMarkerElement()
61 ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, RefX, refX, SVGNames::refXAttr, m_refX)
62 ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, RefY, refY, SVGNames::refYAttr, m_refY)
63 ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, int, Enumeration, enumeration, MarkerUnits, markerUnits, SVGNames::markerUnitsAttr, m_markerUnits)
64 ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, MarkerWidth, markerWidth, SVGNames::markerWidthAttr, m_markerWidth)
65 ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, MarkerHeight, markerHeight, SVGNames::markerHeightAttr, m_markerHeight)
66 ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(SVGMarkerElement, int, Enumeration, enumeration, OrientType, orientType, SVGNames::orientAttr, "orientType", m_orientType)
67 ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(SVGMarkerElement, SVGAngle*, Angle, angle, OrientAngle, orientAngle, SVGNames::orientAttr, "orientAngle", m_orientAngle.get())
69 void SVGMarkerElement::parseMappedAttribute(MappedAttribute* attr)
71 if (attr->name() == SVGNames::markerUnitsAttr) {
72 if (attr->value() == "userSpaceOnUse")
73 setMarkerUnitsBaseValue(SVG_MARKERUNITS_USERSPACEONUSE);
74 } else if (attr->name() == SVGNames::refXAttr)
75 setRefXBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
76 else if (attr->name() == SVGNames::refYAttr)
77 setRefYBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
78 else if (attr->name() == SVGNames::markerWidthAttr)
79 setMarkerWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
80 else if (attr->name() == SVGNames::markerHeightAttr)
81 setMarkerHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
82 else if (attr->name() == SVGNames::orientAttr) {
83 if (attr->value() == "auto")
84 setOrientToAuto();
85 else {
86 SVGAngle* angle = new SVGAngle();
87 angle->setValueAsString(attr->value());
88 setOrientToAngle(angle);
90 } else {
91 if (SVGLangSpace::parseMappedAttribute(attr))
92 return;
93 if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
94 return;
95 if (SVGFitToViewBox::parseMappedAttribute(attr))
96 return;
98 SVGStyledElement::parseMappedAttribute(attr);
102 void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName)
104 SVGStyledElement::svgAttributeChanged(attrName);
106 if (!m_marker)
107 return;
109 if (attrName == SVGNames::markerUnitsAttr || attrName == SVGNames::refXAttr ||
110 attrName == SVGNames::refYAttr || attrName == SVGNames::markerWidthAttr ||
111 attrName == SVGNames::markerHeightAttr || attrName == SVGNames::orientAttr ||
112 SVGLangSpace::isKnownAttribute(attrName) ||
113 SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
114 SVGFitToViewBox::isKnownAttribute(attrName) ||
115 SVGStyledElement::isKnownAttribute(attrName)) {
116 if (renderer())
117 renderer()->setNeedsLayout(true);
119 m_marker->invalidate();
123 void SVGMarkerElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
125 SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
127 if (renderer())
128 renderer()->setNeedsLayout(true);
130 if (m_marker)
131 m_marker->invalidate();
134 void SVGMarkerElement::setOrientToAuto()
136 setOrientTypeBaseValue(SVG_MARKER_ORIENT_AUTO);
139 void SVGMarkerElement::setOrientToAngle(SVGAngle* angle)
141 setOrientTypeBaseValue(SVG_MARKER_ORIENT_ANGLE);
142 setOrientAngleBaseValue(angle);
145 SVGResource* SVGMarkerElement::canvasResource()
147 if (!m_marker)
148 m_marker = SVGResourceMarker::create();
150 m_marker->setMarker(static_cast<RenderSVGViewportContainer*>(renderer()));
152 // Spec: If the attribute is not specified, the effect is as if a
153 // value of "0" were specified.
154 if (!m_orientType)
155 setOrientToAngle(SVGSVGElement::createSVGAngle());
157 if (orientType() == SVG_MARKER_ORIENT_ANGLE)
158 m_marker->setAngle(orientAngle()->value());
159 else
160 m_marker->setAutoAngle();
162 m_marker->setRef(refX().value(), refY().value());
163 m_marker->setUseStrokeWidth(markerUnits() == SVG_MARKERUNITS_STROKEWIDTH);
165 return m_marker.get();
168 RenderObject* SVGMarkerElement::createRenderer(RenderArena* arena, RenderStyle* style)
170 RenderSVGViewportContainer* markerContainer = new (arena) RenderSVGViewportContainer(this);
171 markerContainer->setDrawsContents(false); // Marker contents will be explicitly drawn.
172 return markerContainer;
177 #endif // ENABLE(SVG)