Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann (at) kde.org>
      3  * Copyright (C) 2004, 2005, 2006, 2007 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/SVGLineElement.h"
     24 
     25 #include "core/rendering/svg/RenderSVGResource.h"
     26 #include "core/svg/SVGElementInstance.h"
     27 #include "core/svg/SVGLength.h"
     28 
     29 namespace WebCore {
     30 
     31 // Animated property definitions
     32 DEFINE_ANIMATED_LENGTH(SVGLineElement, SVGNames::x1Attr, X1, x1)
     33 DEFINE_ANIMATED_LENGTH(SVGLineElement, SVGNames::y1Attr, Y1, y1)
     34 DEFINE_ANIMATED_LENGTH(SVGLineElement, SVGNames::x2Attr, X2, x2)
     35 DEFINE_ANIMATED_LENGTH(SVGLineElement, SVGNames::y2Attr, Y2, y2)
     36 DEFINE_ANIMATED_BOOLEAN(SVGLineElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
     37 
     38 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGLineElement)
     39     REGISTER_LOCAL_ANIMATED_PROPERTY(x1)
     40     REGISTER_LOCAL_ANIMATED_PROPERTY(y1)
     41     REGISTER_LOCAL_ANIMATED_PROPERTY(x2)
     42     REGISTER_LOCAL_ANIMATED_PROPERTY(y2)
     43     REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
     44     REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
     45 END_REGISTER_ANIMATED_PROPERTIES
     46 
     47 inline SVGLineElement::SVGLineElement(Document& document)
     48     : SVGGeometryElement(SVGNames::lineTag, document)
     49     , m_x1(LengthModeWidth)
     50     , m_y1(LengthModeHeight)
     51     , m_x2(LengthModeWidth)
     52     , m_y2(LengthModeHeight)
     53 {
     54     ScriptWrappable::init(this);
     55     registerAnimatedPropertiesForSVGLineElement();
     56 }
     57 
     58 PassRefPtr<SVGLineElement> SVGLineElement::create(Document& document)
     59 {
     60     return adoptRef(new SVGLineElement(document));
     61 }
     62 
     63 bool SVGLineElement::isSupportedAttribute(const QualifiedName& attrName)
     64 {
     65     DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
     66     if (supportedAttributes.isEmpty()) {
     67         SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
     68         supportedAttributes.add(SVGNames::x1Attr);
     69         supportedAttributes.add(SVGNames::x2Attr);
     70         supportedAttributes.add(SVGNames::y1Attr);
     71         supportedAttributes.add(SVGNames::y2Attr);
     72     }
     73     return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
     74 }
     75 
     76 void SVGLineElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
     77 {
     78     SVGParsingError parseError = NoError;
     79 
     80     if (!isSupportedAttribute(name))
     81         SVGGeometryElement::parseAttribute(name, value);
     82     else if (name == SVGNames::x1Attr)
     83         setX1BaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
     84     else if (name == SVGNames::y1Attr)
     85         setY1BaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
     86     else if (name == SVGNames::x2Attr)
     87         setX2BaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
     88     else if (name == SVGNames::y2Attr)
     89         setY2BaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
     90     else if (SVGExternalResourcesRequired::parseAttribute(name, value)) {
     91     } else
     92         ASSERT_NOT_REACHED();
     93 
     94     reportAttributeParsingError(parseError, name, value);
     95 }
     96 
     97 void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName)
     98 {
     99     if (!isSupportedAttribute(attrName)) {
    100         SVGGeometryElement::svgAttributeChanged(attrName);
    101         return;
    102     }
    103 
    104     SVGElementInstance::InvalidationGuard invalidationGuard(this);
    105 
    106     bool isLengthAttribute = attrName == SVGNames::x1Attr
    107                           || attrName == SVGNames::y1Attr
    108                           || attrName == SVGNames::x2Attr
    109                           || attrName == SVGNames::y2Attr;
    110 
    111     if (isLengthAttribute)
    112         updateRelativeLengthsInformation();
    113 
    114     RenderSVGShape* renderer = toRenderSVGShape(this->renderer());
    115     if (!renderer)
    116         return;
    117 
    118     if (isLengthAttribute) {
    119         renderer->setNeedsShapeUpdate();
    120         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
    121         return;
    122     }
    123 
    124     if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
    125         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
    126         return;
    127     }
    128 
    129     ASSERT_NOT_REACHED();
    130 }
    131 
    132 bool SVGLineElement::selfHasRelativeLengths() const
    133 {
    134     return x1CurrentValue().isRelative()
    135         || y1CurrentValue().isRelative()
    136         || x2CurrentValue().isRelative()
    137         || y2CurrentValue().isRelative();
    138 }
    139 
    140 }
    141