KHtml

SVGMarkerElement.cpp
1 /*
2  Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <[email protected]>
3  2004, 2005, 2006, 2007 Rob Buis <[email protected]>
4 
5  This file is part of the KDE project
6 
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.
11 
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.
16 
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.
21 */
22 
23 #if ENABLE(SVG)
24 #include "SVGMarkerElement.h"
25 
26 #include "PlatformString.h"
27 #include "RenderSVGViewportContainer.h"
28 #include "SVGAngle.h"
29 #include "SVGLength.h"
30 #include "SVGNames.h"
31 #include "SVGPreserveAspectRatio.h"
32 #include "SVGSVGElement.h"
33 
34 namespace WebCore
35 {
36 
37 SVGMarkerElement::SVGMarkerElement(const QualifiedName &tagName, Document *doc)
38  : SVGStyledElement(tagName, doc)
39  , SVGLangSpace()
40  , SVGExternalResourcesRequired()
41  , SVGFitToViewBox()
42  , m_refX(this, LengthModeWidth)
43  , m_refY(this, LengthModeHeight)
44  , m_markerWidth(this, LengthModeWidth)
45  , m_markerHeight(this, LengthModeHeight)
46  , m_markerUnits(SVG_MARKERUNITS_STROKEWIDTH)
47  , m_orientType(0)
48  , m_orientAngle(new SVGAngle())
49 {
50  // Spec: If the attribute is not specified, the effect is as if a value of "3" were specified.
51  setMarkerWidthBaseValue(SVGLength(this, LengthModeWidth, "3"));
52  setMarkerHeightBaseValue(SVGLength(this, LengthModeHeight, "3"));
53 }
54 
55 SVGMarkerElement::~SVGMarkerElement()
56 {
57 }
58 
59 ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, RefX, refX, SVGNames::refXAttr, m_refX)
60 ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, RefY, refY, SVGNames::refYAttr, m_refY)
61 ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, int, Enumeration, enumeration, MarkerUnits, markerUnits, SVGNames::markerUnitsAttr, m_markerUnits)
62 ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, MarkerWidth, markerWidth, SVGNames::markerWidthAttr, m_markerWidth)
63 ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, MarkerHeight, markerHeight, SVGNames::markerHeightAttr, m_markerHeight)
64 ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(SVGMarkerElement, int, Enumeration, enumeration, OrientType, orientType, SVGNames::orientAttr, "orientType", m_orientType)
65 ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(SVGMarkerElement, SVGAngle *, Angle, angle, OrientAngle, orientAngle, SVGNames::orientAttr, "orientAngle", m_orientAngle.get())
66 
67 void SVGMarkerElement::parseMappedAttribute(MappedAttribute *attr)
68 {
69  if (attr->name() == SVGNames::markerUnitsAttr) {
70  if (attr->value() == "userSpaceOnUse") {
71  setMarkerUnitsBaseValue(SVG_MARKERUNITS_USERSPACEONUSE);
72  }
73  } else if (attr->name() == SVGNames::refXAttr) {
74  setRefXBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
75  } else if (attr->name() == SVGNames::refYAttr) {
76  setRefYBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
77  } else if (attr->name() == SVGNames::markerWidthAttr) {
78  setMarkerWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
79  } else if (attr->name() == SVGNames::markerHeightAttr) {
80  setMarkerHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
81  } else if (attr->name() == SVGNames::orientAttr) {
82  if (attr->value() == "auto") {
83  setOrientToAuto();
84  } else {
85  SVGAngle *angle = new SVGAngle();
86  angle->setValueAsString(attr->value());
87  setOrientToAngle(angle);
88  }
89  } else {
90  if (SVGLangSpace::parseMappedAttribute(attr)) {
91  return;
92  }
93  if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) {
94  return;
95  }
96  if (SVGFitToViewBox::parseMappedAttribute(attr)) {
97  return;
98  }
99 
100  SVGStyledElement::parseMappedAttribute(attr);
101  }
102 }
103 
104 void SVGMarkerElement::svgAttributeChanged(const QualifiedName &attrName)
105 {
106  SVGStyledElement::svgAttributeChanged(attrName);
107 
108  if (!m_marker) {
109  return;
110  }
111 
112  if (attrName == SVGNames::markerUnitsAttr || attrName == SVGNames::refXAttr ||
113  attrName == SVGNames::refYAttr || attrName == SVGNames::markerWidthAttr ||
114  attrName == SVGNames::markerHeightAttr || attrName == SVGNames::orientAttr ||
115  SVGLangSpace::isKnownAttribute(attrName) ||
116  SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
117  SVGFitToViewBox::isKnownAttribute(attrName) ||
118  SVGStyledElement::isKnownAttribute(attrName)) {
119  if (renderer()) {
120  renderer()->setNeedsLayout(true);
121  }
122 
123  m_marker->invalidate();
124  }
125 }
126 
127 void SVGMarkerElement::childrenChanged(bool changedByParser, Node *beforeChange, Node *afterChange, int childCountDelta)
128 {
129  SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
130 
131  if (renderer()) {
132  renderer()->setNeedsLayout(true);
133  }
134 
135  if (m_marker) {
136  m_marker->invalidate();
137  }
138 }
139 
140 void SVGMarkerElement::setOrientToAuto()
141 {
142  setOrientTypeBaseValue(SVG_MARKER_ORIENT_AUTO);
143 }
144 
145 void SVGMarkerElement::setOrientToAngle(SVGAngle *angle)
146 {
147  setOrientTypeBaseValue(SVG_MARKER_ORIENT_ANGLE);
148  setOrientAngleBaseValue(angle);
149 }
150 
151 SVGResource *SVGMarkerElement::canvasResource()
152 {
153  if (!m_marker) {
154  m_marker = SVGResourceMarker::create();
155  }
156 
157  m_marker->setMarker(static_cast<RenderSVGViewportContainer *>(renderer()));
158 
159  // Spec: If the attribute is not specified, the effect is as if a
160  // value of "0" were specified.
161  if (!m_orientType) {
162  setOrientToAngle(SVGSVGElement::createSVGAngle());
163  }
164 
165  if (orientType() == SVG_MARKER_ORIENT_ANGLE) {
166  m_marker->setAngle(orientAngle()->value());
167  } else {
168  m_marker->setAutoAngle();
169  }
170 
171  m_marker->setRef(refX().value(), refY().value());
172  m_marker->setUseStrokeWidth(markerUnits() == SVG_MARKERUNITS_STROKEWIDTH);
173 
174  return m_marker.get();
175 }
176 
177 RenderObject *SVGMarkerElement::createRenderer(RenderArena *arena, RenderStyle *style)
178 {
179  RenderSVGViewportContainer *markerContainer = new(arena) RenderSVGViewportContainer(this);
180  markerContainer->setDrawsContents(false); // Marker contents will be explicitly drawn.
181  return markerContainer;
182 }
183 
184 }
185 
186 #endif // ENABLE(SVG)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Oct 26 2021 22:48:10 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.