Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann (at) kde.org>
      3  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Rob Buis <buis (at) 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
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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