2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
4 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
24 #include "core/svg/SVGMarkerElement.h"
26 #include "core/SVGNames.h"
27 #include "core/rendering/svg/RenderSVGResourceMarker.h"
28 #include "core/svg/SVGAngleTearOff.h"
32 template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGMarkerUnitsType>()
34 DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
35 if (entries.isEmpty()) {
36 entries.append(std::make_pair(SVGMarkerUnitsUserSpaceOnUse, "userSpaceOnUse"));
37 entries.append(std::make_pair(SVGMarkerUnitsStrokeWidth, "strokeWidth"));
43 inline SVGMarkerElement::SVGMarkerElement(Document& document)
44 : SVGElement(SVGNames::markerTag, document)
45 , SVGFitToViewBox(this)
46 , m_refX(SVGAnimatedLength::create(this, SVGNames::refXAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
47 , m_refY(SVGAnimatedLength::create(this, SVGNames::refYAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
48 , m_markerWidth(SVGAnimatedLength::create(this, SVGNames::markerWidthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
49 , m_markerHeight(SVGAnimatedLength::create(this, SVGNames::markerHeightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths))
50 , m_orientAngle(SVGAnimatedAngle::create(this))
51 , m_markerUnits(SVGAnimatedEnumeration<SVGMarkerUnitsType>::create(this, SVGNames::markerUnitsAttr, SVGMarkerUnitsStrokeWidth))
53 // Spec: If the markerWidth/markerHeight attribute is not specified, the effect is as if a value of "3" were specified.
54 m_markerWidth->setDefaultValueAsString("3");
55 m_markerHeight->setDefaultValueAsString("3");
57 addToPropertyMap(m_refX);
58 addToPropertyMap(m_refY);
59 addToPropertyMap(m_markerWidth);
60 addToPropertyMap(m_markerHeight);
61 addToPropertyMap(m_orientAngle);
62 addToPropertyMap(m_markerUnits);
65 DEFINE_NODE_FACTORY(SVGMarkerElement)
67 AffineTransform SVGMarkerElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const
69 return SVGFitToViewBox::viewBoxToViewTransform(viewBox()->currentValue()->value(), preserveAspectRatio()->currentValue(), viewWidth, viewHeight);
72 bool SVGMarkerElement::isSupportedAttribute(const QualifiedName& attrName)
74 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
75 if (supportedAttributes.isEmpty()) {
76 SVGFitToViewBox::addSupportedAttributes(supportedAttributes);
77 supportedAttributes.add(SVGNames::markerUnitsAttr);
78 supportedAttributes.add(SVGNames::refXAttr);
79 supportedAttributes.add(SVGNames::refYAttr);
80 supportedAttributes.add(SVGNames::markerWidthAttr);
81 supportedAttributes.add(SVGNames::markerHeightAttr);
82 supportedAttributes.add(SVGNames::orientAttr);
84 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
87 void SVGMarkerElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
89 parseAttributeNew(name, value);
92 void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName)
94 if (!isSupportedAttribute(attrName)) {
95 SVGElement::svgAttributeChanged(attrName);
99 SVGElement::InvalidationGuard invalidationGuard(this);
101 if (attrName == SVGNames::refXAttr
102 || attrName == SVGNames::refYAttr
103 || attrName == SVGNames::markerWidthAttr
104 || attrName == SVGNames::markerHeightAttr)
105 updateRelativeLengthsInformation();
107 RenderSVGResourceContainer* renderer = toRenderSVGResourceContainer(this->renderer());
109 renderer->invalidateCacheAndMarkForLayout();
112 void SVGMarkerElement::childrenChanged(const ChildrenChange& change)
114 SVGElement::childrenChanged(change);
119 if (RenderObject* object = renderer())
120 object->setNeedsLayoutAndFullPaintInvalidation();
123 void SVGMarkerElement::setOrientToAuto()
125 m_orientAngle->baseValue()->orientType()->setEnumValue(SVGMarkerOrientAuto);
126 invalidateSVGAttributes();
127 svgAttributeChanged(SVGNames::orientAttr);
130 void SVGMarkerElement::setOrientToAngle(PassRefPtr<SVGAngleTearOff> angle)
133 RefPtr<SVGAngle> target = angle->target();
134 m_orientAngle->baseValue()->newValueSpecifiedUnits(target->unitType(), target->valueInSpecifiedUnits());
135 invalidateSVGAttributes();
136 svgAttributeChanged(SVGNames::orientAttr);
139 RenderObject* SVGMarkerElement::createRenderer(RenderStyle*)
141 return new RenderSVGResourceMarker(this);
144 bool SVGMarkerElement::selfHasRelativeLengths() const
146 return m_refX->currentValue()->isRelative()
147 || m_refY->currentValue()->isRelative()
148 || m_markerWidth->currentValue()->isRelative()
149 || m_markerHeight->currentValue()->isRelative();