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 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 "SVGStyledTransformableElement.h"
     25 
     26 #include "AffineTransform.h"
     27 #include "Attribute.h"
     28 #include "RenderSVGPath.h"
     29 #include "RenderSVGResource.h"
     30 #include "SVGNames.h"
     31 
     32 namespace WebCore {
     33 
     34 // Animated property definitions
     35 DEFINE_ANIMATED_TRANSFORM_LIST(SVGStyledTransformableElement, SVGNames::transformAttr, Transform, transform)
     36 
     37 SVGStyledTransformableElement::SVGStyledTransformableElement(const QualifiedName& tagName, Document* document)
     38     : SVGStyledLocatableElement(tagName, document)
     39 {
     40 }
     41 
     42 SVGStyledTransformableElement::~SVGStyledTransformableElement()
     43 {
     44 }
     45 
     46 AffineTransform SVGStyledTransformableElement::getCTM(StyleUpdateStrategy styleUpdateStrategy) const
     47 {
     48     return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope, styleUpdateStrategy);
     49 }
     50 
     51 AffineTransform SVGStyledTransformableElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy) const
     52 {
     53     return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope, styleUpdateStrategy);
     54 }
     55 
     56 AffineTransform SVGStyledTransformableElement::animatedLocalTransform() const
     57 {
     58     AffineTransform matrix;
     59     transform().concatenate(matrix);
     60     if (m_supplementalTransform)
     61         matrix *= *m_supplementalTransform;
     62     return matrix;
     63 }
     64 
     65 AffineTransform* SVGStyledTransformableElement::supplementalTransform()
     66 {
     67     if (!m_supplementalTransform)
     68         m_supplementalTransform.set(new AffineTransform());
     69     return m_supplementalTransform.get();
     70 }
     71 
     72 void SVGStyledTransformableElement::parseMappedAttribute(Attribute* attr)
     73 {
     74     if (SVGTransformable::isKnownAttribute(attr->name())) {
     75         SVGTransformList newList;
     76         if (!SVGTransformable::parseTransformAttribute(newList, attr->value()))
     77             newList.clear();
     78         detachAnimatedTransformListWrappers(newList.size());
     79         setTransformBaseValue(newList);
     80     } else
     81         SVGStyledLocatableElement::parseMappedAttribute(attr);
     82 }
     83 
     84 void SVGStyledTransformableElement::svgAttributeChanged(const QualifiedName& attrName)
     85 {
     86     SVGStyledLocatableElement::svgAttributeChanged(attrName);
     87 
     88     if (!SVGStyledTransformableElement::isKnownAttribute(attrName))
     89         return;
     90 
     91     RenderObject* object = renderer();
     92     if (!object)
     93         return;
     94 
     95     object->setNeedsTransformUpdate();
     96     RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
     97 }
     98 
     99 void SVGStyledTransformableElement::synchronizeProperty(const QualifiedName& attrName)
    100 {
    101     SVGStyledLocatableElement::synchronizeProperty(attrName);
    102 
    103     if (attrName == anyQName() || SVGTransformable::isKnownAttribute(attrName))
    104         synchronizeTransform();
    105 }
    106 
    107 bool SVGStyledTransformableElement::isKnownAttribute(const QualifiedName& attrName)
    108 {
    109     return SVGTransformable::isKnownAttribute(attrName) || SVGStyledLocatableElement::isKnownAttribute(attrName);
    110 }
    111 
    112 SVGElement* SVGStyledTransformableElement::nearestViewportElement() const
    113 {
    114     return SVGTransformable::nearestViewportElement(this);
    115 }
    116 
    117 SVGElement* SVGStyledTransformableElement::farthestViewportElement() const
    118 {
    119     return SVGTransformable::farthestViewportElement(this);
    120 }
    121 
    122 FloatRect SVGStyledTransformableElement::getBBox(StyleUpdateStrategy styleUpdateStrategy) const
    123 {
    124     return SVGTransformable::getBBox(this, styleUpdateStrategy);
    125 }
    126 
    127 RenderObject* SVGStyledTransformableElement::createRenderer(RenderArena* arena, RenderStyle*)
    128 {
    129     // By default, any subclass is expected to do path-based drawing
    130     return new (arena) RenderSVGPath(this);
    131 }
    132 
    133 void SVGStyledTransformableElement::fillPassedAttributeToPropertyTypeMap(AttributeToPropertyTypeMap& attributeToPropertyTypeMap)
    134 {
    135     SVGStyledElement::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap);
    136 
    137     attributeToPropertyTypeMap.set(SVGNames::transformAttr, AnimatedTransformList);
    138 }
    139 
    140 void SVGStyledTransformableElement::toClipPath(Path& path) const
    141 {
    142     toPathData(path);
    143     // FIXME: How do we know the element has done a layout?
    144     path.transform(animatedLocalTransform());
    145 }
    146 
    147 }
    148 
    149 #endif // ENABLE(SVG)
    150