blob: 3c6249096c39275f633bddaa0924e48f0f2b22a0 [file] [log] [blame]
darinb9481ed2006-03-20 02:57:59 +00001/*
zimmermann@webkit.org711245f2010-08-03 19:39:01 +00002 * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@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 */
darinb9481ed2006-03-20 02:57:59 +000020
21#include "config.h"
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +000022#include "SVGGraphicsElement.h"
weinig5fc44ff2006-10-24 21:57:42 +000023
krit@webkit.org2b95a9a2010-02-08 20:30:42 +000024#include "AffineTransform.h"
zimmermann@webkit.org42ab4a72010-12-03 11:14:32 +000025#include "Attribute.h"
andreas.kling@nokia.comecf49562010-10-07 07:33:33 +000026#include "RenderSVGPath.h"
paroga@webkit.org29952692011-03-04 17:38:24 +000027#include "RenderSVGResource.h"
zimmermann@webkit.orgefff7252011-05-21 06:15:40 +000028#include "SVGElementInstance.h"
zimmermann@webkit.org42ab4a72010-12-03 11:14:32 +000029#include "SVGNames.h"
zimmermann@webkit.orgc20d3422011-11-10 11:17:52 +000030#include "SVGPathData.h"
svillar@igalia.com55cc6d12014-05-08 10:59:17 +000031#include <wtf/NeverDestroyed.h>
darinb9481ed2006-03-20 02:57:59 +000032
rwlbuisdde95e22006-12-03 12:02:26 +000033namespace WebCore {
darinb9481ed2006-03-20 02:57:59 +000034
zimmermann@webkit.orgca9551e2010-12-01 15:41:53 +000035// Animated property definitions
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +000036DEFINE_ANIMATED_TRANSFORM_LIST(SVGGraphicsElement, SVGNames::transformAttr, Transform, transform)
zimmermann@webkit.orgca9551e2010-12-01 15:41:53 +000037
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +000038BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGGraphicsElement)
zimmermann@webkit.orga2857422011-07-09 11:26:10 +000039 REGISTER_LOCAL_ANIMATED_PROPERTY(transform)
ch.dumez@sisa.samsung.com7dd31bf2013-08-22 21:58:09 +000040 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +000041 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTests)
zimmermann@webkit.orga2857422011-07-09 11:26:10 +000042END_REGISTER_ANIMATED_PROPERTIES
43
weinig@apple.com52e786e2013-09-15 18:06:06 +000044SVGGraphicsElement::SVGGraphicsElement(const QualifiedName& tagName, Document& document)
ch.dumez@sisa.samsung.com7dd31bf2013-08-22 21:58:09 +000045 : SVGElement(tagName, document)
commit-queue@webkit.orgb668ca22014-02-18 17:10:37 +000046 , m_shouldIsolateBlending(false)
darinb9481ed2006-03-20 02:57:59 +000047{
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +000048 registerAnimatedPropertiesForSVGGraphicsElement();
darinb9481ed2006-03-20 02:57:59 +000049}
50
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +000051SVGGraphicsElement::~SVGGraphicsElement()
commit-queue@webkit.org7538c252010-10-09 02:00:07 +000052{
53}
54
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +000055AffineTransform SVGGraphicsElement::getCTM(StyleUpdateStrategy styleUpdateStrategy)
darinb9481ed2006-03-20 02:57:59 +000056{
simon.fraser@apple.com64487f92010-08-19 17:19:40 +000057 return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope, styleUpdateStrategy);
darinb9481ed2006-03-20 02:57:59 +000058}
59
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +000060AffineTransform SVGGraphicsElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy)
darinb9481ed2006-03-20 02:57:59 +000061{
simon.fraser@apple.com64487f92010-08-19 17:19:40 +000062 return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope, styleUpdateStrategy);
darinb9481ed2006-03-20 02:57:59 +000063}
64
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +000065AffineTransform SVGGraphicsElement::animatedLocalTransform() const
darinb9481ed2006-03-20 02:57:59 +000066{
zimmermann@webkit.orgbbd697c2010-11-11 11:20:11 +000067 AffineTransform matrix;
akling@apple.com827be9c2013-10-29 02:58:43 +000068 RenderStyle* style = renderer() ? &renderer()->style() : nullptr;
commit-queue@webkit.org0db57552011-11-23 11:34:37 +000069
commit-queue@webkit.org86984252012-03-13 02:45:38 +000070 // If CSS property was set, use that, otherwise fallback to attribute (if set).
commit-queue@webkit.org8282a1d2012-01-03 19:33:09 +000071 if (style && style->hasTransform()) {
commit-queue@webkit.org86984252012-03-13 02:45:38 +000072 // Note: objectBoundingBox is an emptyRect for elements like pattern or clipPath.
73 // See the "Object bounding box units" section of http://dev.w3.org/csswg/css3-transforms/
74 TransformationMatrix transform;
75 style->applyTransform(transform, renderer()->objectBoundingBox());
76
77 // Flatten any 3D transform.
78 matrix = transform.toAffineTransform();
cavalcantii@gmail.com4b5f7d72014-04-08 22:27:37 +000079 // CSS bakes the zoom factor into lengths, including translation components.
80 // In order to align CSS & SVG transforms, we need to invert this operation.
81 float zoom = style->effectiveZoom();
82 if (zoom != 1) {
83 matrix.setE(matrix.e() / zoom);
84 matrix.setF(matrix.f() / zoom);
85 }
86
commit-queue@webkit.org0db57552011-11-23 11:34:37 +000087 } else
88 transform().concatenate(matrix);
89
commit-queue@webkit.org17b17862011-01-19 20:10:07 +000090 if (m_supplementalTransform)
krit@webkit.org45b84e62011-09-06 08:18:23 +000091 return *m_supplementalTransform * matrix;
commit-queue@webkit.org17b17862011-01-19 20:10:07 +000092 return matrix;
antti@apple.comaf579272008-04-18 07:40:17 +000093}
zimmermann@webkit.orgbbd697c2010-11-11 11:20:11 +000094
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +000095AffineTransform* SVGGraphicsElement::supplementalTransform()
antti@apple.comaf579272008-04-18 07:40:17 +000096{
97 if (!m_supplementalTransform)
commit-queue@webkit.orgd6a51e82013-11-19 17:22:59 +000098 m_supplementalTransform = std::make_unique<AffineTransform>();
antti@apple.comaf579272008-04-18 07:40:17 +000099 return m_supplementalTransform.get();
darinb9481ed2006-03-20 02:57:59 +0000100}
101
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +0000102bool SVGGraphicsElement::isSupportedAttribute(const QualifiedName& attrName)
zimmermann@webkit.orgefff7252011-05-21 06:15:40 +0000103{
svillar@igalia.com55cc6d12014-05-08 10:59:17 +0000104 static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes;
105 if (supportedAttributes.get().isEmpty()) {
ch.dumez@sisa.samsung.com31038222013-07-03 08:03:53 +0000106 SVGTests::addSupportedAttributes(supportedAttributes);
svillar@igalia.com55cc6d12014-05-08 10:59:17 +0000107 supportedAttributes.get().add(SVGNames::transformAttr);
ch.dumez@sisa.samsung.com31038222013-07-03 08:03:53 +0000108 }
svillar@igalia.com55cc6d12014-05-08 10:59:17 +0000109 return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName);
zimmermann@webkit.orgefff7252011-05-21 06:15:40 +0000110}
111
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +0000112void SVGGraphicsElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
darinb9481ed2006-03-20 02:57:59 +0000113{
akling@apple.com43e9d042012-11-18 16:55:06 +0000114 if (!isSupportedAttribute(name)) {
ch.dumez@sisa.samsung.com7dd31bf2013-08-22 21:58:09 +0000115 SVGElement::parseAttribute(name, value);
zimmermann@webkit.orgefff7252011-05-21 06:15:40 +0000116 return;
117 }
118
akling@apple.com43e9d042012-11-18 16:55:06 +0000119 if (name == SVGNames::transformAttr) {
zimmermann@webkit.orgbbd697c2010-11-11 11:20:11 +0000120 SVGTransformList newList;
akling@apple.com43e9d042012-11-18 16:55:06 +0000121 newList.parse(value);
zimmermann@webkit.orgbbd697c2010-11-11 11:20:11 +0000122 detachAnimatedTransformListWrappers(newList.size());
zimmermann@webkit.orgad6ff5b2010-11-19 16:27:54 +0000123 setTransformBaseValue(newList);
zimmermann@webkit.orgefff7252011-05-21 06:15:40 +0000124 return;
125 }
126
ch.dumez@sisa.samsung.com31038222013-07-03 08:03:53 +0000127 if (SVGTests::parseAttribute(name, value))
128 return;
129
zimmermann@webkit.orgefff7252011-05-21 06:15:40 +0000130 ASSERT_NOT_REACHED();
darinb9481ed2006-03-20 02:57:59 +0000131}
132
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +0000133void SVGGraphicsElement::svgAttributeChanged(const QualifiedName& attrName)
paroga@webkit.org29952692011-03-04 17:38:24 +0000134{
zimmermann@webkit.orgefff7252011-05-21 06:15:40 +0000135 if (!isSupportedAttribute(attrName)) {
ch.dumez@sisa.samsung.com7dd31bf2013-08-22 21:58:09 +0000136 SVGElement::svgAttributeChanged(attrName);
paroga@webkit.org29952692011-03-04 17:38:24 +0000137 return;
zimmermann@webkit.orgefff7252011-05-21 06:15:40 +0000138 }
139
140 SVGElementInstance::InvalidationGuard invalidationGuard(this);
paroga@webkit.org29952692011-03-04 17:38:24 +0000141
ch.dumez@sisa.samsung.com31038222013-07-03 08:03:53 +0000142 if (SVGTests::handleAttributeChange(this, attrName))
143 return;
144
commit-queue@webkit.org48a92842013-12-16 19:23:24 +0000145 auto renderer = this->renderer();
146 if (!renderer)
paroga@webkit.org29952692011-03-04 17:38:24 +0000147 return;
148
zimmermann@webkit.orgefff7252011-05-21 06:15:40 +0000149 if (attrName == SVGNames::transformAttr) {
commit-queue@webkit.org48a92842013-12-16 19:23:24 +0000150 renderer->setNeedsTransformUpdate();
151 RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer);
zimmermann@webkit.orgefff7252011-05-21 06:15:40 +0000152 return;
153 }
154
155 ASSERT_NOT_REACHED();
paroga@webkit.org29952692011-03-04 17:38:24 +0000156}
157
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +0000158SVGElement* SVGGraphicsElement::nearestViewportElement() const
krit@webkit.orgb28ef572010-10-22 19:00:36 +0000159{
160 return SVGTransformable::nearestViewportElement(this);
161}
162
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +0000163SVGElement* SVGGraphicsElement::farthestViewportElement() const
krit@webkit.orgb28ef572010-10-22 19:00:36 +0000164{
165 return SVGTransformable::farthestViewportElement(this);
166}
167
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +0000168FloatRect SVGGraphicsElement::getBBox(StyleUpdateStrategy styleUpdateStrategy)
krit@webkit.orgb28ef572010-10-22 19:00:36 +0000169{
170 return SVGTransformable::getBBox(this, styleUpdateStrategy);
171}
172
akling@apple.com96526682013-12-31 14:05:28 +0000173RenderPtr<RenderElement> SVGGraphicsElement::createElementRenderer(PassRef<RenderStyle> style)
oliver09e98ea2007-10-12 15:38:34 +0000174{
175 // By default, any subclass is expected to do path-based drawing
akling@apple.com96526682013-12-31 14:05:28 +0000176 return createRenderer<RenderSVGPath>(*this, std::move(style));
oliver09e98ea2007-10-12 15:38:34 +0000177}
178
ch.dumez@sisa.samsung.coma47b6182013-06-28 15:58:03 +0000179void SVGGraphicsElement::toClipPath(Path& path)
rwlbuis@webkit.org8f675dd2008-09-16 11:12:52 +0000180{
zimmermann@webkit.orgc20d3422011-11-10 11:17:52 +0000181 updatePathFromGraphicsElement(this, path);
rwlbuis@webkit.org8f675dd2008-09-16 11:12:52 +0000182 // FIXME: How do we know the element has done a layout?
andreas.kling@nokia.com5a20f1c2010-10-11 19:19:05 +0000183 path.transform(animatedLocalTransform());
rwlbuis@webkit.org8f675dd2008-09-16 11:12:52 +0000184}
185
oliver666a58d2007-10-12 12:28:28 +0000186}