darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 1 | /* |
zimmermann@webkit.org | 711245f | 2010-08-03 19:39:01 +0000 | [diff] [blame] | 2 | * 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 | */ |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 20 | |
| 21 | #include "config.h" |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 22 | #include "SVGGraphicsElement.h" |
weinig | 5fc44ff | 2006-10-24 21:57:42 +0000 | [diff] [blame] | 23 | |
krit@webkit.org | 2b95a9a | 2010-02-08 20:30:42 +0000 | [diff] [blame] | 24 | #include "AffineTransform.h" |
zimmermann@webkit.org | 42ab4a7 | 2010-12-03 11:14:32 +0000 | [diff] [blame] | 25 | #include "Attribute.h" |
andreas.kling@nokia.com | ecf4956 | 2010-10-07 07:33:33 +0000 | [diff] [blame] | 26 | #include "RenderSVGPath.h" |
paroga@webkit.org | 2995269 | 2011-03-04 17:38:24 +0000 | [diff] [blame] | 27 | #include "RenderSVGResource.h" |
zimmermann@webkit.org | efff725 | 2011-05-21 06:15:40 +0000 | [diff] [blame] | 28 | #include "SVGElementInstance.h" |
zimmermann@webkit.org | 42ab4a7 | 2010-12-03 11:14:32 +0000 | [diff] [blame] | 29 | #include "SVGNames.h" |
zimmermann@webkit.org | c20d342 | 2011-11-10 11:17:52 +0000 | [diff] [blame] | 30 | #include "SVGPathData.h" |
svillar@igalia.com | 55cc6d1 | 2014-05-08 10:59:17 +0000 | [diff] [blame] | 31 | #include <wtf/NeverDestroyed.h> |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 32 | |
rwlbuis | dde95e2 | 2006-12-03 12:02:26 +0000 | [diff] [blame] | 33 | namespace WebCore { |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 34 | |
zimmermann@webkit.org | ca9551e | 2010-12-01 15:41:53 +0000 | [diff] [blame] | 35 | // Animated property definitions |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 36 | DEFINE_ANIMATED_TRANSFORM_LIST(SVGGraphicsElement, SVGNames::transformAttr, Transform, transform) |
zimmermann@webkit.org | ca9551e | 2010-12-01 15:41:53 +0000 | [diff] [blame] | 37 | |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 38 | BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGGraphicsElement) |
zimmermann@webkit.org | a285742 | 2011-07-09 11:26:10 +0000 | [diff] [blame] | 39 | REGISTER_LOCAL_ANIMATED_PROPERTY(transform) |
ch.dumez@sisa.samsung.com | 7dd31bf | 2013-08-22 21:58:09 +0000 | [diff] [blame] | 40 | REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement) |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 41 | REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTests) |
zimmermann@webkit.org | a285742 | 2011-07-09 11:26:10 +0000 | [diff] [blame] | 42 | END_REGISTER_ANIMATED_PROPERTIES |
| 43 | |
weinig@apple.com | 52e786e | 2013-09-15 18:06:06 +0000 | [diff] [blame] | 44 | SVGGraphicsElement::SVGGraphicsElement(const QualifiedName& tagName, Document& document) |
ch.dumez@sisa.samsung.com | 7dd31bf | 2013-08-22 21:58:09 +0000 | [diff] [blame] | 45 | : SVGElement(tagName, document) |
commit-queue@webkit.org | b668ca2 | 2014-02-18 17:10:37 +0000 | [diff] [blame] | 46 | , m_shouldIsolateBlending(false) |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 47 | { |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 48 | registerAnimatedPropertiesForSVGGraphicsElement(); |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 49 | } |
| 50 | |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 51 | SVGGraphicsElement::~SVGGraphicsElement() |
commit-queue@webkit.org | 7538c25 | 2010-10-09 02:00:07 +0000 | [diff] [blame] | 52 | { |
| 53 | } |
| 54 | |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 55 | AffineTransform SVGGraphicsElement::getCTM(StyleUpdateStrategy styleUpdateStrategy) |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 56 | { |
simon.fraser@apple.com | 64487f9 | 2010-08-19 17:19:40 +0000 | [diff] [blame] | 57 | return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope, styleUpdateStrategy); |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 58 | } |
| 59 | |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 60 | AffineTransform SVGGraphicsElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy) |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 61 | { |
simon.fraser@apple.com | 64487f9 | 2010-08-19 17:19:40 +0000 | [diff] [blame] | 62 | return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope, styleUpdateStrategy); |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 63 | } |
| 64 | |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 65 | AffineTransform SVGGraphicsElement::animatedLocalTransform() const |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 66 | { |
zimmermann@webkit.org | bbd697c | 2010-11-11 11:20:11 +0000 | [diff] [blame] | 67 | AffineTransform matrix; |
akling@apple.com | 827be9c | 2013-10-29 02:58:43 +0000 | [diff] [blame] | 68 | RenderStyle* style = renderer() ? &renderer()->style() : nullptr; |
commit-queue@webkit.org | 0db5755 | 2011-11-23 11:34:37 +0000 | [diff] [blame] | 69 | |
commit-queue@webkit.org | 8698425 | 2012-03-13 02:45:38 +0000 | [diff] [blame] | 70 | // If CSS property was set, use that, otherwise fallback to attribute (if set). |
commit-queue@webkit.org | 8282a1d | 2012-01-03 19:33:09 +0000 | [diff] [blame] | 71 | if (style && style->hasTransform()) { |
commit-queue@webkit.org | 8698425 | 2012-03-13 02:45:38 +0000 | [diff] [blame] | 72 | // 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.com | 4b5f7d7 | 2014-04-08 22:27:37 +0000 | [diff] [blame] | 79 | // 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.org | 0db5755 | 2011-11-23 11:34:37 +0000 | [diff] [blame] | 87 | } else |
| 88 | transform().concatenate(matrix); |
| 89 | |
commit-queue@webkit.org | 17b1786 | 2011-01-19 20:10:07 +0000 | [diff] [blame] | 90 | if (m_supplementalTransform) |
krit@webkit.org | 45b84e6 | 2011-09-06 08:18:23 +0000 | [diff] [blame] | 91 | return *m_supplementalTransform * matrix; |
commit-queue@webkit.org | 17b1786 | 2011-01-19 20:10:07 +0000 | [diff] [blame] | 92 | return matrix; |
antti@apple.com | af57927 | 2008-04-18 07:40:17 +0000 | [diff] [blame] | 93 | } |
zimmermann@webkit.org | bbd697c | 2010-11-11 11:20:11 +0000 | [diff] [blame] | 94 | |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 95 | AffineTransform* SVGGraphicsElement::supplementalTransform() |
antti@apple.com | af57927 | 2008-04-18 07:40:17 +0000 | [diff] [blame] | 96 | { |
| 97 | if (!m_supplementalTransform) |
commit-queue@webkit.org | d6a51e8 | 2013-11-19 17:22:59 +0000 | [diff] [blame] | 98 | m_supplementalTransform = std::make_unique<AffineTransform>(); |
antti@apple.com | af57927 | 2008-04-18 07:40:17 +0000 | [diff] [blame] | 99 | return m_supplementalTransform.get(); |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 100 | } |
| 101 | |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 102 | bool SVGGraphicsElement::isSupportedAttribute(const QualifiedName& attrName) |
zimmermann@webkit.org | efff725 | 2011-05-21 06:15:40 +0000 | [diff] [blame] | 103 | { |
svillar@igalia.com | 55cc6d1 | 2014-05-08 10:59:17 +0000 | [diff] [blame] | 104 | static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; |
| 105 | if (supportedAttributes.get().isEmpty()) { |
ch.dumez@sisa.samsung.com | 3103822 | 2013-07-03 08:03:53 +0000 | [diff] [blame] | 106 | SVGTests::addSupportedAttributes(supportedAttributes); |
svillar@igalia.com | 55cc6d1 | 2014-05-08 10:59:17 +0000 | [diff] [blame] | 107 | supportedAttributes.get().add(SVGNames::transformAttr); |
ch.dumez@sisa.samsung.com | 3103822 | 2013-07-03 08:03:53 +0000 | [diff] [blame] | 108 | } |
svillar@igalia.com | 55cc6d1 | 2014-05-08 10:59:17 +0000 | [diff] [blame] | 109 | return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); |
zimmermann@webkit.org | efff725 | 2011-05-21 06:15:40 +0000 | [diff] [blame] | 110 | } |
| 111 | |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 112 | void SVGGraphicsElement::parseAttribute(const QualifiedName& name, const AtomicString& value) |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 113 | { |
akling@apple.com | 43e9d04 | 2012-11-18 16:55:06 +0000 | [diff] [blame] | 114 | if (!isSupportedAttribute(name)) { |
ch.dumez@sisa.samsung.com | 7dd31bf | 2013-08-22 21:58:09 +0000 | [diff] [blame] | 115 | SVGElement::parseAttribute(name, value); |
zimmermann@webkit.org | efff725 | 2011-05-21 06:15:40 +0000 | [diff] [blame] | 116 | return; |
| 117 | } |
| 118 | |
akling@apple.com | 43e9d04 | 2012-11-18 16:55:06 +0000 | [diff] [blame] | 119 | if (name == SVGNames::transformAttr) { |
zimmermann@webkit.org | bbd697c | 2010-11-11 11:20:11 +0000 | [diff] [blame] | 120 | SVGTransformList newList; |
akling@apple.com | 43e9d04 | 2012-11-18 16:55:06 +0000 | [diff] [blame] | 121 | newList.parse(value); |
zimmermann@webkit.org | bbd697c | 2010-11-11 11:20:11 +0000 | [diff] [blame] | 122 | detachAnimatedTransformListWrappers(newList.size()); |
zimmermann@webkit.org | ad6ff5b | 2010-11-19 16:27:54 +0000 | [diff] [blame] | 123 | setTransformBaseValue(newList); |
zimmermann@webkit.org | efff725 | 2011-05-21 06:15:40 +0000 | [diff] [blame] | 124 | return; |
| 125 | } |
| 126 | |
ch.dumez@sisa.samsung.com | 3103822 | 2013-07-03 08:03:53 +0000 | [diff] [blame] | 127 | if (SVGTests::parseAttribute(name, value)) |
| 128 | return; |
| 129 | |
zimmermann@webkit.org | efff725 | 2011-05-21 06:15:40 +0000 | [diff] [blame] | 130 | ASSERT_NOT_REACHED(); |
darin | b9481ed | 2006-03-20 02:57:59 +0000 | [diff] [blame] | 131 | } |
| 132 | |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 133 | void SVGGraphicsElement::svgAttributeChanged(const QualifiedName& attrName) |
paroga@webkit.org | 2995269 | 2011-03-04 17:38:24 +0000 | [diff] [blame] | 134 | { |
zimmermann@webkit.org | efff725 | 2011-05-21 06:15:40 +0000 | [diff] [blame] | 135 | if (!isSupportedAttribute(attrName)) { |
ch.dumez@sisa.samsung.com | 7dd31bf | 2013-08-22 21:58:09 +0000 | [diff] [blame] | 136 | SVGElement::svgAttributeChanged(attrName); |
paroga@webkit.org | 2995269 | 2011-03-04 17:38:24 +0000 | [diff] [blame] | 137 | return; |
zimmermann@webkit.org | efff725 | 2011-05-21 06:15:40 +0000 | [diff] [blame] | 138 | } |
| 139 | |
| 140 | SVGElementInstance::InvalidationGuard invalidationGuard(this); |
paroga@webkit.org | 2995269 | 2011-03-04 17:38:24 +0000 | [diff] [blame] | 141 | |
ch.dumez@sisa.samsung.com | 3103822 | 2013-07-03 08:03:53 +0000 | [diff] [blame] | 142 | if (SVGTests::handleAttributeChange(this, attrName)) |
| 143 | return; |
| 144 | |
commit-queue@webkit.org | 48a9284 | 2013-12-16 19:23:24 +0000 | [diff] [blame] | 145 | auto renderer = this->renderer(); |
| 146 | if (!renderer) |
paroga@webkit.org | 2995269 | 2011-03-04 17:38:24 +0000 | [diff] [blame] | 147 | return; |
| 148 | |
zimmermann@webkit.org | efff725 | 2011-05-21 06:15:40 +0000 | [diff] [blame] | 149 | if (attrName == SVGNames::transformAttr) { |
commit-queue@webkit.org | 48a9284 | 2013-12-16 19:23:24 +0000 | [diff] [blame] | 150 | renderer->setNeedsTransformUpdate(); |
| 151 | RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); |
zimmermann@webkit.org | efff725 | 2011-05-21 06:15:40 +0000 | [diff] [blame] | 152 | return; |
| 153 | } |
| 154 | |
| 155 | ASSERT_NOT_REACHED(); |
paroga@webkit.org | 2995269 | 2011-03-04 17:38:24 +0000 | [diff] [blame] | 156 | } |
| 157 | |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 158 | SVGElement* SVGGraphicsElement::nearestViewportElement() const |
krit@webkit.org | b28ef57 | 2010-10-22 19:00:36 +0000 | [diff] [blame] | 159 | { |
| 160 | return SVGTransformable::nearestViewportElement(this); |
| 161 | } |
| 162 | |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 163 | SVGElement* SVGGraphicsElement::farthestViewportElement() const |
krit@webkit.org | b28ef57 | 2010-10-22 19:00:36 +0000 | [diff] [blame] | 164 | { |
| 165 | return SVGTransformable::farthestViewportElement(this); |
| 166 | } |
| 167 | |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 168 | FloatRect SVGGraphicsElement::getBBox(StyleUpdateStrategy styleUpdateStrategy) |
krit@webkit.org | b28ef57 | 2010-10-22 19:00:36 +0000 | [diff] [blame] | 169 | { |
| 170 | return SVGTransformable::getBBox(this, styleUpdateStrategy); |
| 171 | } |
| 172 | |
akling@apple.com | 9652668 | 2013-12-31 14:05:28 +0000 | [diff] [blame] | 173 | RenderPtr<RenderElement> SVGGraphicsElement::createElementRenderer(PassRef<RenderStyle> style) |
oliver | 09e98ea | 2007-10-12 15:38:34 +0000 | [diff] [blame] | 174 | { |
| 175 | // By default, any subclass is expected to do path-based drawing |
akling@apple.com | 9652668 | 2013-12-31 14:05:28 +0000 | [diff] [blame] | 176 | return createRenderer<RenderSVGPath>(*this, std::move(style)); |
oliver | 09e98ea | 2007-10-12 15:38:34 +0000 | [diff] [blame] | 177 | } |
| 178 | |
ch.dumez@sisa.samsung.com | a47b618 | 2013-06-28 15:58:03 +0000 | [diff] [blame] | 179 | void SVGGraphicsElement::toClipPath(Path& path) |
rwlbuis@webkit.org | 8f675dd | 2008-09-16 11:12:52 +0000 | [diff] [blame] | 180 | { |
zimmermann@webkit.org | c20d342 | 2011-11-10 11:17:52 +0000 | [diff] [blame] | 181 | updatePathFromGraphicsElement(this, path); |
rwlbuis@webkit.org | 8f675dd | 2008-09-16 11:12:52 +0000 | [diff] [blame] | 182 | // FIXME: How do we know the element has done a layout? |
andreas.kling@nokia.com | 5a20f1c | 2010-10-11 19:19:05 +0000 | [diff] [blame] | 183 | path.transform(animatedLocalTransform()); |
rwlbuis@webkit.org | 8f675dd | 2008-09-16 11:12:52 +0000 | [diff] [blame] | 184 | } |
| 185 | |
oliver | 666a58d | 2007-10-12 12:28:28 +0000 | [diff] [blame] | 186 | } |