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#include "core/svg/SVGTextPositioningElement.h" 24 25#include "SVGNames.h" 26#include "core/rendering/svg/RenderSVGResource.h" 27#include "core/rendering/svg/RenderSVGText.h" 28#include "core/svg/SVGElementInstance.h" 29#include "core/svg/SVGLengthList.h" 30#include "core/svg/SVGNumberList.h" 31 32namespace WebCore { 33 34// Animated property definitions 35DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::xAttr, X, x) 36DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::yAttr, Y, y) 37DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::dxAttr, Dx, dx) 38DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::dyAttr, Dy, dy) 39DEFINE_ANIMATED_NUMBER_LIST(SVGTextPositioningElement, SVGNames::rotateAttr, Rotate, rotate) 40 41BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGTextPositioningElement) 42 REGISTER_LOCAL_ANIMATED_PROPERTY(x) 43 REGISTER_LOCAL_ANIMATED_PROPERTY(y) 44 REGISTER_LOCAL_ANIMATED_PROPERTY(dx) 45 REGISTER_LOCAL_ANIMATED_PROPERTY(dy) 46 REGISTER_LOCAL_ANIMATED_PROPERTY(rotate) 47 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTextContentElement) 48END_REGISTER_ANIMATED_PROPERTIES 49 50SVGTextPositioningElement::SVGTextPositioningElement(const QualifiedName& tagName, Document* document) 51 : SVGTextContentElement(tagName, document) 52{ 53 ScriptWrappable::init(this); 54 registerAnimatedPropertiesForSVGTextPositioningElement(); 55} 56 57bool SVGTextPositioningElement::isSupportedAttribute(const QualifiedName& attrName) 58{ 59 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); 60 if (supportedAttributes.isEmpty()) { 61 supportedAttributes.add(SVGNames::xAttr); 62 supportedAttributes.add(SVGNames::yAttr); 63 supportedAttributes.add(SVGNames::dxAttr); 64 supportedAttributes.add(SVGNames::dyAttr); 65 supportedAttributes.add(SVGNames::rotateAttr); 66 } 67 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); 68} 69 70void SVGTextPositioningElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 71{ 72 if (!isSupportedAttribute(name)) { 73 SVGTextContentElement::parseAttribute(name, value); 74 return; 75 } 76 77 if (name == SVGNames::xAttr) { 78 SVGLengthList newList; 79 newList.parse(value, LengthModeWidth); 80 detachAnimatedXListWrappers(newList.size()); 81 setXBaseValue(newList); 82 return; 83 } 84 85 if (name == SVGNames::yAttr) { 86 SVGLengthList newList; 87 newList.parse(value, LengthModeHeight); 88 detachAnimatedYListWrappers(newList.size()); 89 setYBaseValue(newList); 90 return; 91 } 92 93 if (name == SVGNames::dxAttr) { 94 SVGLengthList newList; 95 newList.parse(value, LengthModeWidth); 96 detachAnimatedDxListWrappers(newList.size()); 97 setDxBaseValue(newList); 98 return; 99 } 100 101 if (name == SVGNames::dyAttr) { 102 SVGLengthList newList; 103 newList.parse(value, LengthModeHeight); 104 detachAnimatedDyListWrappers(newList.size()); 105 setDyBaseValue(newList); 106 return; 107 } 108 109 if (name == SVGNames::rotateAttr) { 110 SVGNumberList newList; 111 newList.parse(value); 112 detachAnimatedRotateListWrappers(newList.size()); 113 setRotateBaseValue(newList); 114 return; 115 } 116 117 ASSERT_NOT_REACHED(); 118} 119 120void SVGTextPositioningElement::svgAttributeChanged(const QualifiedName& attrName) 121{ 122 if (!isSupportedAttribute(attrName)) { 123 SVGTextContentElement::svgAttributeChanged(attrName); 124 return; 125 } 126 127 SVGElementInstance::InvalidationGuard invalidationGuard(this); 128 129 bool updateRelativeLengths = attrName == SVGNames::xAttr 130 || attrName == SVGNames::yAttr 131 || attrName == SVGNames::dxAttr 132 || attrName == SVGNames::dyAttr; 133 134 if (updateRelativeLengths) 135 updateRelativeLengthsInformation(); 136 137 RenderObject* renderer = this->renderer(); 138 if (!renderer) 139 return; 140 141 if (updateRelativeLengths || attrName == SVGNames::rotateAttr) { 142 if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(renderer)) 143 textRenderer->setNeedsPositioningValuesUpdate(); 144 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); 145 return; 146 } 147 148 ASSERT_NOT_REACHED(); 149} 150 151SVGTextPositioningElement* SVGTextPositioningElement::elementFromRenderer(RenderObject* renderer) 152{ 153 if (!renderer) 154 return 0; 155 156 if (!renderer->isSVGText() && !renderer->isSVGInline()) 157 return 0; 158 159 Node* node = renderer->node(); 160 ASSERT(node); 161 ASSERT(node->isSVGElement()); 162 163 if (!node->hasTagName(SVGNames::textTag) 164 && !node->hasTagName(SVGNames::tspanTag) 165#if ENABLE(SVG_FONTS) 166 && !node->hasTagName(SVGNames::altGlyphTag) 167#endif 168 && !node->hasTagName(SVGNames::trefTag)) 169 return 0; 170 171 return static_cast<SVGTextPositioningElement*>(node); 172} 173 174} 175