• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SVGLengthList.h"
30 #include "SVGNames.h"
31 #include "SVGNumberList.h"
32 
33 namespace WebCore {
34 
35 // Animated property definitions
DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement,SVGNames::xAttr,X,x)36 DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::xAttr, X, x)
37 DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::yAttr, Y, y)
38 DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::dxAttr, Dx, dx)
39 DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::dyAttr, Dy, dy)
40 DEFINE_ANIMATED_NUMBER_LIST(SVGTextPositioningElement, SVGNames::rotateAttr, Rotate, rotate)
41 
42 SVGTextPositioningElement::SVGTextPositioningElement(const QualifiedName& tagName, Document* document)
43     : SVGTextContentElement(tagName, document)
44 {
45 }
46 
parseMappedAttribute(Attribute * attr)47 void SVGTextPositioningElement::parseMappedAttribute(Attribute* attr)
48 {
49     if (attr->name() == SVGNames::xAttr) {
50         SVGLengthList newList;
51         newList.parse(attr->value(), LengthModeWidth);
52         detachAnimatedXListWrappers(newList.size());
53         setXBaseValue(newList);
54     } else if (attr->name() == SVGNames::yAttr) {
55         SVGLengthList newList;
56         newList.parse(attr->value(), LengthModeHeight);
57         detachAnimatedYListWrappers(newList.size());
58         setYBaseValue(newList);
59     } else if (attr->name() == SVGNames::dxAttr) {
60         SVGLengthList newList;
61         newList.parse(attr->value(), LengthModeWidth);
62         detachAnimatedDxListWrappers(newList.size());
63         setDxBaseValue(newList);
64     } else if (attr->name() == SVGNames::dyAttr) {
65         SVGLengthList newList;
66         newList.parse(attr->value(), LengthModeHeight);
67         detachAnimatedDyListWrappers(newList.size());
68         setDyBaseValue(newList);
69     } else if (attr->name() == SVGNames::rotateAttr) {
70         SVGNumberList newList;
71         newList.parse(attr->value());
72         detachAnimatedRotateListWrappers(newList.size());
73         setRotateBaseValue(newList);
74     } else
75         SVGTextContentElement::parseMappedAttribute(attr);
76 }
77 
updatePositioningValuesInRenderer(RenderObject * renderer)78 static inline void updatePositioningValuesInRenderer(RenderObject* renderer)
79 {
80     RenderSVGText* textRenderer = 0;
81 
82     if (renderer->isSVGText())
83         textRenderer = toRenderSVGText(renderer);
84     else {
85         // Locate RenderSVGText parent renderer.
86         RenderObject* parent = renderer->parent();
87         while (parent && !parent->isSVGText())
88             parent = parent->parent();
89 
90         if (parent) {
91             ASSERT(parent->isSVGText());
92             textRenderer = toRenderSVGText(parent);
93         }
94     }
95 
96     if (!textRenderer)
97         return;
98 
99     textRenderer->setNeedsPositioningValuesUpdate();
100 }
101 
svgAttributeChanged(const QualifiedName & attrName)102 void SVGTextPositioningElement::svgAttributeChanged(const QualifiedName& attrName)
103 {
104     SVGTextContentElement::svgAttributeChanged(attrName);
105 
106     bool updateRelativeLengths = attrName == SVGNames::xAttr
107                               || attrName == SVGNames::yAttr
108                               || attrName == SVGNames::dxAttr
109                               || attrName == SVGNames::dyAttr;
110 
111     if (updateRelativeLengths)
112         updateRelativeLengthsInformation();
113 
114     RenderObject* renderer = this->renderer();
115     if (!renderer)
116         return;
117 
118     if (updateRelativeLengths || attrName == SVGNames::rotateAttr) {
119         updatePositioningValuesInRenderer(renderer);
120         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
121         return;
122     }
123 }
124 
childrenChanged(bool changedByParser,Node * beforeChange,Node * afterChange,int childCountDelta)125 void SVGTextPositioningElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
126 {
127     SVGTextContentElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
128 
129     if (changedByParser)
130         return;
131 
132     if (RenderObject* object = renderer())
133         updatePositioningValuesInRenderer(object);
134 }
135 
synchronizeProperty(const QualifiedName & attrName)136 void SVGTextPositioningElement::synchronizeProperty(const QualifiedName& attrName)
137 {
138     SVGTextContentElement::synchronizeProperty(attrName);
139 
140     if (attrName == anyQName()) {
141         synchronizeX();
142         synchronizeY();
143         synchronizeDx();
144         synchronizeDy();
145         synchronizeRotate();
146         return;
147     }
148 
149     if (attrName == SVGNames::xAttr)
150         synchronizeX();
151     else if (attrName == SVGNames::yAttr)
152         synchronizeY();
153     else if (attrName == SVGNames::dxAttr)
154         synchronizeDx();
155     else if (attrName == SVGNames::dyAttr)
156         synchronizeDy();
157     else if (attrName == SVGNames::rotateAttr)
158         synchronizeRotate();
159 }
160 
fillPassedAttributeToPropertyTypeMap(AttributeToPropertyTypeMap & attributeToPropertyTypeMap)161 void SVGTextPositioningElement::fillPassedAttributeToPropertyTypeMap(AttributeToPropertyTypeMap& attributeToPropertyTypeMap)
162 {
163     SVGTextContentElement::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap);
164 
165     attributeToPropertyTypeMap.set(SVGNames::xAttr, AnimatedNumberList);
166     attributeToPropertyTypeMap.set(SVGNames::yAttr, AnimatedNumberList);
167     attributeToPropertyTypeMap.set(SVGNames::dxAttr, AnimatedNumberList);
168     attributeToPropertyTypeMap.set(SVGNames::dyAttr, AnimatedNumberList);
169     attributeToPropertyTypeMap.set(SVGNames::rotateAttr, AnimatedNumberList);
170 }
171 
elementFromRenderer(RenderObject * renderer)172 SVGTextPositioningElement* SVGTextPositioningElement::elementFromRenderer(RenderObject* renderer)
173 {
174     if (!renderer)
175         return 0;
176 
177     if (!renderer->isSVGText() && !renderer->isSVGInline())
178         return 0;
179 
180     Node* node = renderer->node();
181     ASSERT(node);
182     ASSERT(node->isSVGElement());
183 
184     if (!node->hasTagName(SVGNames::textTag)
185         && !node->hasTagName(SVGNames::tspanTag)
186 #if ENABLE(SVG_FONTS)
187         && !node->hasTagName(SVGNames::altGlyphTag)
188 #endif
189         && !node->hasTagName(SVGNames::trefTag))
190         return 0;
191 
192     return static_cast<SVGTextPositioningElement*>(node);
193 }
194 
195 }
196 
197 #endif // ENABLE(SVG)
198