1/* 2 * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org> 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 */ 20 21#include "config.h" 22 23#if ENABLE(SVG) 24#include "SVGTextPositioningElement.h" 25 26#include "Attribute.h" 27#include "RenderSVGResource.h" 28#include "RenderSVGText.h" 29#include "SVGElementInstance.h" 30#include "SVGLengthList.h" 31#include "SVGNames.h" 32#include "SVGNumberList.h" 33 34namespace WebCore { 35 36// Animated property definitions 37DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::xAttr, X, x) 38DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::yAttr, Y, y) 39DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::dxAttr, Dx, dx) 40DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::dyAttr, Dy, dy) 41DEFINE_ANIMATED_NUMBER_LIST(SVGTextPositioningElement, SVGNames::rotateAttr, Rotate, rotate) 42 43BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGTextPositioningElement) 44 REGISTER_LOCAL_ANIMATED_PROPERTY(x) 45 REGISTER_LOCAL_ANIMATED_PROPERTY(y) 46 REGISTER_LOCAL_ANIMATED_PROPERTY(dx) 47 REGISTER_LOCAL_ANIMATED_PROPERTY(dy) 48 REGISTER_LOCAL_ANIMATED_PROPERTY(rotate) 49 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTextContentElement) 50END_REGISTER_ANIMATED_PROPERTIES 51 52SVGTextPositioningElement::SVGTextPositioningElement(const QualifiedName& tagName, Document* document) 53 : SVGTextContentElement(tagName, document) 54{ 55 registerAnimatedPropertiesForSVGTextPositioningElement(); 56} 57 58bool SVGTextPositioningElement::isSupportedAttribute(const QualifiedName& attrName) 59{ 60 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); 61 if (supportedAttributes.isEmpty()) { 62 supportedAttributes.add(SVGNames::xAttr); 63 supportedAttributes.add(SVGNames::yAttr); 64 supportedAttributes.add(SVGNames::dxAttr); 65 supportedAttributes.add(SVGNames::dyAttr); 66 supportedAttributes.add(SVGNames::rotateAttr); 67 } 68 return supportedAttributes.contains<QualifiedName, SVGAttributeHashTranslator>(attrName); 69} 70 71void SVGTextPositioningElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 72{ 73 if (!isSupportedAttribute(name)) { 74 SVGTextContentElement::parseAttribute(name, value); 75 return; 76 } 77 78 if (name == SVGNames::xAttr) { 79 SVGLengthList newList; 80 newList.parse(value, LengthModeWidth); 81 detachAnimatedXListWrappers(newList.size()); 82 setXBaseValue(newList); 83 return; 84 } 85 86 if (name == SVGNames::yAttr) { 87 SVGLengthList newList; 88 newList.parse(value, LengthModeHeight); 89 detachAnimatedYListWrappers(newList.size()); 90 setYBaseValue(newList); 91 return; 92 } 93 94 if (name == SVGNames::dxAttr) { 95 SVGLengthList newList; 96 newList.parse(value, LengthModeWidth); 97 detachAnimatedDxListWrappers(newList.size()); 98 setDxBaseValue(newList); 99 return; 100 } 101 102 if (name == SVGNames::dyAttr) { 103 SVGLengthList newList; 104 newList.parse(value, LengthModeHeight); 105 detachAnimatedDyListWrappers(newList.size()); 106 setDyBaseValue(newList); 107 return; 108 } 109 110 if (name == SVGNames::rotateAttr) { 111 SVGNumberList newList; 112 newList.parse(value); 113 detachAnimatedRotateListWrappers(newList.size()); 114 setRotateBaseValue(newList); 115 return; 116 } 117 118 ASSERT_NOT_REACHED(); 119} 120 121void SVGTextPositioningElement::svgAttributeChanged(const QualifiedName& attrName) 122{ 123 if (!isSupportedAttribute(attrName)) { 124 SVGTextContentElement::svgAttributeChanged(attrName); 125 return; 126 } 127 128 SVGElementInstance::InvalidationGuard invalidationGuard(this); 129 130 bool updateRelativeLengths = attrName == SVGNames::xAttr 131 || attrName == SVGNames::yAttr 132 || attrName == SVGNames::dxAttr 133 || attrName == SVGNames::dyAttr; 134 135 if (updateRelativeLengths) 136 updateRelativeLengthsInformation(); 137 138 RenderObject* renderer = this->renderer(); 139 if (!renderer) 140 return; 141 142 if (updateRelativeLengths || attrName == SVGNames::rotateAttr) { 143 if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(renderer)) 144 textRenderer->setNeedsPositioningValuesUpdate(); 145 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 146 return; 147 } 148 149 ASSERT_NOT_REACHED(); 150} 151 152SVGTextPositioningElement* SVGTextPositioningElement::elementFromRenderer(RenderObject* renderer) 153{ 154 if (!renderer) 155 return 0; 156 157 if (!renderer->isSVGText() && !renderer->isSVGInline()) 158 return 0; 159 160 Node* node = renderer->node(); 161 ASSERT(node); 162 ASSERT(node->isSVGElement()); 163 164 if (!node->hasTagName(SVGNames::textTag) 165 && !node->hasTagName(SVGNames::tspanTag) 166#if ENABLE(SVG_FONTS) 167 && !node->hasTagName(SVGNames::altGlyphTag) 168#endif 169 && !node->hasTagName(SVGNames::trefTag)) 170 return 0; 171 172 return static_cast<SVGTextPositioningElement*>(node); 173} 174 175} 176 177#endif // ENABLE(SVG) 178