15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> 4d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * Copyright (C) 2014 Google, Inc. 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 24591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/svg/SVGGraphicsElement.h" 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/SVGNames.h" 2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/RenderSVGPath.h" 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/RenderSVGResource.h" 2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/SVGPathData.h" 301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/transforms/AffineTransform.h" 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 32c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 348abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)SVGGraphicsElement::SVGGraphicsElement(const QualifiedName& tagName, Document& document, ConstructionType constructionType) 35f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) : SVGElement(tagName, document, constructionType) 3609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) , SVGTests(this) 37d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) , m_transform(SVGAnimatedTransformList::create(this, SVGNames::transformAttr, SVGTransformList::create())) 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 39d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) addToPropertyMap(m_transform); 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 42591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochSVGGraphicsElement::~SVGGraphicsElement() 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 46d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PassRefPtr<SVGMatrixTearOff> SVGGraphicsElement::getTransformToElement(SVGElement* target, ExceptionState& exceptionState) 4751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){ 4851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) AffineTransform ctm = getCTM(AllowStyleUpdate); 4951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 5051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (target && target->isSVGGraphicsElement()) { 5151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) AffineTransform targetCTM = toSVGGraphicsElement(target)->getCTM(AllowStyleUpdate); 5251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (!targetCTM.isInvertible()) { 5309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) exceptionState.throwDOMException(InvalidStateError, "The target transformation is not invertable."); 54d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 5551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 5651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) ctm = targetCTM.inverse() * ctm; 5751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 5851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 59d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return SVGMatrixTearOff::create(ctm); 60d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 61d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 62d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static bool isViewportElement(const Element& element) 63d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 64d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return (isSVGSVGElement(element) 65d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGSymbolElement(element) 66d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGForeignObjectElement(element) 67d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || isSVGImageElement(element)); 6851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} 6951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 70d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)AffineTransform SVGGraphicsElement::computeCTM(SVGElement::CTMScope mode, 71d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) SVGGraphicsElement::StyleUpdateStrategy styleUpdateStrategy, const SVGGraphicsElement* ancestor) const 7251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){ 73d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (styleUpdateStrategy == AllowStyleUpdate) 74d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) document().updateLayoutIgnorePendingStylesheets(); 7551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 7651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) AffineTransform ctm; 77d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) bool done = false; 7851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 79d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) for (const Element* currentElement = this; currentElement && !done; 80d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) currentElement = currentElement->parentOrShadowHostElement()) { 8151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (!currentElement->isSVGElement()) 8251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) break; 8351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 8451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) ctm = toSVGElement(currentElement)->localCoordinateSpaceTransform(mode).multiply(ctm); 8551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 86d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) switch (mode) { 87d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) case NearestViewportScope: 88d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Stop at the nearest viewport ancestor. 89d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) done = currentElement != this && isViewportElement(*currentElement); 9051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) break; 91d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) case AncestorScope: 92d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Stop at the designated ancestor. 93d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) done = currentElement == ancestor; 94d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) break; 95d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) default: 96d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT(mode == ScreenScope); 97d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) break; 98d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 9951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 10051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 10151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return ctm; 10251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} 10351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 104591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochAffineTransform SVGGraphicsElement::getCTM(StyleUpdateStrategy styleUpdateStrategy) 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 106d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return computeCTM(NearestViewportScope, styleUpdateStrategy); 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 109591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochAffineTransform SVGGraphicsElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 111d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return computeCTM(ScreenScope, styleUpdateStrategy); 112d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 113d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 114d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PassRefPtr<SVGMatrixTearOff> SVGGraphicsElement::getCTMFromJavascript() 115d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 116d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return SVGMatrixTearOff::create(getCTM()); 117d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 118d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 119d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PassRefPtr<SVGMatrixTearOff> SVGGraphicsElement::getScreenCTMFromJavascript() 120d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 121d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return SVGMatrixTearOff::create(getScreenCTM()); 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 124591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochAffineTransform SVGGraphicsElement::animatedLocalTransform() const 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform matrix; 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderStyle* style = renderer() ? renderer()->style() : 0; 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If CSS property was set, use that, otherwise fallback to attribute (if set). 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style && style->hasTransform()) { 131d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) TransformationMatrix transform; 132d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) float zoom = style->effectiveZoom(); 133d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 134d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // CSS transforms operate with pre-scaled lengths. To make this work with SVG 135d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // (which applies the zoom factor globally, at the root level) we 136d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // 137d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // * pre-scale the bounding box (to bring it into the same space as the other CSS values) 138d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // * invert the zoom factor (to effectively compute the CSS transform under a 1.0 zoom) 139d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note: objectBoundingBox is an emptyRect for elements like pattern or clipPath. 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // See the "Object bounding box units" section of http://dev.w3.org/csswg/css3-transforms/ 142d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) if (zoom != 1) { 143d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) FloatRect scaledBBox = renderer()->objectBoundingBox(); 144d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) scaledBBox.scale(zoom); 145d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) transform.scale(1 / zoom); 146d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) style->applyTransform(transform, scaledBBox); 147d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) transform.scale(zoom); 148d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } else { 149d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) style->applyTransform(transform, renderer()->objectBoundingBox()); 150d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) } 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Flatten any 3D transform. 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) matrix = transform.toAffineTransform(); 154591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } else { 155d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_transform->currentValue()->concatenate(matrix); 156591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_supplementalTransform) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return *m_supplementalTransform * matrix; 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return matrix; 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 163591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochAffineTransform* SVGGraphicsElement::supplementalTransform() 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_supplementalTransform) 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_supplementalTransform = adoptPtr(new AffineTransform); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_supplementalTransform.get(); 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 170591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochbool SVGGraphicsElement::isSupportedAttribute(const QualifiedName& attrName) 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); 173591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (supportedAttributes.isEmpty()) { 174591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch SVGTests::addSupportedAttributes(supportedAttributes); 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) supportedAttributes.add(SVGNames::transformAttr); 176591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 177591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 180591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid SVGGraphicsElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 182c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) parseAttributeNew(name, value); 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 185591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid SVGGraphicsElement::svgAttributeChanged(const QualifiedName& attrName) 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isSupportedAttribute(attrName)) { 188f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) SVGElement::svgAttributeChanged(attrName); 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 192323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) SVGElement::InvalidationGuard invalidationGuard(this); 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 194f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) // Reattach so the isValid() check will be run again during renderer creation. 195f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) if (SVGTests::isKnownAttribute(attrName)) { 196f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) lazyReattachIfAttached(); 197591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return; 198f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) } 199591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* object = renderer(); 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!object) 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (attrName == SVGNames::transformAttr) { 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) object->setNeedsTransformUpdate(); 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderSVGResource::markForLayoutAndParentResourceInvalidation(object); 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 213591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochSVGElement* SVGGraphicsElement::nearestViewportElement() const 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 21551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) for (Element* current = parentOrShadowHostElement(); current; current = current->parentOrShadowHostElement()) { 216d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isViewportElement(*current)) 21751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return toSVGElement(current); 21851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 21951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 22051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return 0; 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 223591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochSVGElement* SVGGraphicsElement::farthestViewportElement() const 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 22551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) SVGElement* farthest = 0; 22651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) for (Element* current = parentOrShadowHostElement(); current; current = current->parentOrShadowHostElement()) { 227d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isViewportElement(*current)) 22851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) farthest = toSVGElement(current); 22951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 23051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return farthest; 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 23309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)FloatRect SVGGraphicsElement::getBBox() 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 235f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) document().updateLayoutIgnorePendingStylesheets(); 236f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 237f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) // FIXME: Eventually we should support getBBox for detached elements. 238f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) if (!renderer()) 23909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return FloatRect(); 240f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 241f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) return renderer()->objectBoundingBox(); 242f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)} 243f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 24409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)PassRefPtr<SVGRectTearOff> SVGGraphicsElement::getBBoxFromJavascript() 245f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){ 24609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return SVGRectTearOff::create(SVGRect::create(getBBox()), 0, PropertyIsNotAnimVal); 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 249591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochRenderObject* SVGGraphicsElement::createRenderer(RenderStyle*) 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // By default, any subclass is expected to do path-based drawing 252f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return new RenderSVGPath(this); 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 255591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid SVGGraphicsElement::toClipPath(Path& path) 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updatePathFromGraphicsElement(this, path); 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: How do we know the element has done a layout? 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) path.transform(animatedLocalTransform()); 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 263