KHTML
SVGMarkerElement.cpp
Go to the documentation of this file.
00001 /* 00002 Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 00003 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> 00004 00005 This file is part of the KDE project 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Library General Public License for more details. 00016 00017 You should have received a copy of the GNU Library General Public License 00018 along with this library; see the file COPYING.LIB. If not, write to 00019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00020 Boston, MA 02110-1301, USA. 00021 */ 00022 00023 #include "config.h" 00024 00025 #if ENABLE(SVG) 00026 #include "SVGMarkerElement.h" 00027 00028 #include "PlatformString.h" 00029 #include "RenderSVGViewportContainer.h" 00030 #include "SVGAngle.h" 00031 #include "SVGFitToViewBox.h" 00032 #include "SVGLength.h" 00033 #include "SVGNames.h" 00034 #include "SVGPreserveAspectRatio.h" 00035 #include "SVGSVGElement.h" 00036 00037 namespace WebCore { 00038 00039 SVGMarkerElement::SVGMarkerElement(const QualifiedName& tagName, Document* doc) 00040 : SVGStyledElement(tagName, doc) 00041 , SVGLangSpace() 00042 , SVGExternalResourcesRequired() 00043 , SVGFitToViewBox() 00044 , m_refX(this, LengthModeWidth) 00045 , m_refY(this, LengthModeHeight) 00046 , m_markerWidth(this, LengthModeWidth) 00047 , m_markerHeight(this, LengthModeHeight) 00048 , m_markerUnits(SVG_MARKERUNITS_STROKEWIDTH) 00049 , m_orientType(0) 00050 , m_orientAngle(new SVGAngle()) 00051 { 00052 // Spec: If the attribute is not specified, the effect is as if a value of "3" were specified. 00053 setMarkerWidthBaseValue(SVGLength(this, LengthModeWidth, "3")); 00054 setMarkerHeightBaseValue(SVGLength(this, LengthModeHeight, "3")); 00055 } 00056 00057 SVGMarkerElement::~SVGMarkerElement() 00058 { 00059 } 00060 00061 ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, RefX, refX, SVGNames::refXAttr, m_refX) 00062 ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, RefY, refY, SVGNames::refYAttr, m_refY) 00063 ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, int, Enumeration, enumeration, MarkerUnits, markerUnits, SVGNames::markerUnitsAttr, m_markerUnits) 00064 ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, MarkerWidth, markerWidth, SVGNames::markerWidthAttr, m_markerWidth) 00065 ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, MarkerHeight, markerHeight, SVGNames::markerHeightAttr, m_markerHeight) 00066 ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(SVGMarkerElement, int, Enumeration, enumeration, OrientType, orientType, SVGNames::orientAttr, "orientType", m_orientType) 00067 ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(SVGMarkerElement, SVGAngle*, Angle, angle, OrientAngle, orientAngle, SVGNames::orientAttr, "orientAngle", m_orientAngle.get()) 00068 00069 void SVGMarkerElement::parseMappedAttribute(MappedAttribute* attr) 00070 { 00071 if (attr->name() == SVGNames::markerUnitsAttr) { 00072 if (attr->value() == "userSpaceOnUse") 00073 setMarkerUnitsBaseValue(SVG_MARKERUNITS_USERSPACEONUSE); 00074 } else if (attr->name() == SVGNames::refXAttr) 00075 setRefXBaseValue(SVGLength(this, LengthModeWidth, attr->value())); 00076 else if (attr->name() == SVGNames::refYAttr) 00077 setRefYBaseValue(SVGLength(this, LengthModeHeight, attr->value())); 00078 else if (attr->name() == SVGNames::markerWidthAttr) 00079 setMarkerWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value())); 00080 else if (attr->name() == SVGNames::markerHeightAttr) 00081 setMarkerHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value())); 00082 else if (attr->name() == SVGNames::orientAttr) { 00083 if (attr->value() == "auto") 00084 setOrientToAuto(); 00085 else { 00086 SVGAngle* angle = new SVGAngle(); 00087 angle->setValueAsString(attr->value()); 00088 setOrientToAngle(angle); 00089 } 00090 } else { 00091 if (SVGLangSpace::parseMappedAttribute(attr)) 00092 return; 00093 if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) 00094 return; 00095 if (SVGFitToViewBox::parseMappedAttribute(attr)) 00096 return; 00097 00098 SVGStyledElement::parseMappedAttribute(attr); 00099 } 00100 } 00101 00102 void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName) 00103 { 00104 SVGStyledElement::svgAttributeChanged(attrName); 00105 00106 if (!m_marker) 00107 return; 00108 00109 if (attrName == SVGNames::markerUnitsAttr || attrName == SVGNames::refXAttr || 00110 attrName == SVGNames::refYAttr || attrName == SVGNames::markerWidthAttr || 00111 attrName == SVGNames::markerHeightAttr || attrName == SVGNames::orientAttr || 00112 SVGLangSpace::isKnownAttribute(attrName) || 00113 SVGExternalResourcesRequired::isKnownAttribute(attrName) || 00114 SVGFitToViewBox::isKnownAttribute(attrName) || 00115 SVGStyledElement::isKnownAttribute(attrName)) { 00116 if (renderer()) 00117 renderer()->setNeedsLayout(true); 00118 00119 m_marker->invalidate(); 00120 } 00121 } 00122 00123 void SVGMarkerElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) 00124 { 00125 SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); 00126 00127 if (renderer()) 00128 renderer()->setNeedsLayout(true); 00129 00130 if (m_marker) 00131 m_marker->invalidate(); 00132 } 00133 00134 void SVGMarkerElement::setOrientToAuto() 00135 { 00136 setOrientTypeBaseValue(SVG_MARKER_ORIENT_AUTO); 00137 } 00138 00139 void SVGMarkerElement::setOrientToAngle(SVGAngle* angle) 00140 { 00141 setOrientTypeBaseValue(SVG_MARKER_ORIENT_ANGLE); 00142 setOrientAngleBaseValue(angle); 00143 } 00144 00145 SVGResource* SVGMarkerElement::canvasResource() 00146 { 00147 if (!m_marker) 00148 m_marker = SVGResourceMarker::create(); 00149 00150 m_marker->setMarker(static_cast<RenderSVGViewportContainer*>(renderer())); 00151 00152 // Spec: If the attribute is not specified, the effect is as if a 00153 // value of "0" were specified. 00154 if (!m_orientType) 00155 setOrientToAngle(SVGSVGElement::createSVGAngle()); 00156 00157 if (orientType() == SVG_MARKER_ORIENT_ANGLE) 00158 m_marker->setAngle(orientAngle()->value()); 00159 else 00160 m_marker->setAutoAngle(); 00161 00162 m_marker->setRef(refX().value(), refY().value()); 00163 m_marker->setUseStrokeWidth(markerUnits() == SVG_MARKERUNITS_STROKEWIDTH); 00164 00165 return m_marker.get(); 00166 } 00167 00168 RenderObject* SVGMarkerElement::createRenderer(RenderArena* arena, RenderStyle* style) 00169 { 00170 RenderSVGViewportContainer* markerContainer = new (arena) RenderSVGViewportContainer(this); 00171 markerContainer->setDrawsContents(false); // Marker contents will be explicitly drawn. 00172 return markerContainer; 00173 } 00174 00175 } 00176 00177 #endif // ENABLE(SVG)
KDE 4.6 API Reference