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 #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 
     32 namespace WebCore {
     33 
     34 // Animated property definitions
     35 DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::xAttr, X, x)
     36 DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::yAttr, Y, y)
     37 DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::dxAttr, Dx, dx)
     38 DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::dyAttr, Dy, dy)
     39 DEFINE_ANIMATED_NUMBER_LIST(SVGTextPositioningElement, SVGNames::rotateAttr, Rotate, rotate)
     40 
     41 BEGIN_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)
     48 END_REGISTER_ANIMATED_PROPERTIES
     49 
     50 SVGTextPositioningElement::SVGTextPositioningElement(const QualifiedName& tagName, Document* document)
     51     : SVGTextContentElement(tagName, document)
     52 {
     53     ScriptWrappable::init(this);
     54     registerAnimatedPropertiesForSVGTextPositioningElement();
     55 }
     56 
     57 bool 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 
     70 void 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 
    120 void 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 
    151 SVGTextPositioningElement* 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