Changeset 285481 in webkit
- Timestamp:
- Nov 8, 2021, 11:39:20 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 9 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/fast/shadow-dom/svg-feimage-href-in-shadow-tree.html (modified) (1 diff)
-
LayoutTests/svg/filters/feImage-change-target-id-expected.txt (modified) (1 diff)
-
LayoutTests/svg/filters/feImage-element-primitive-subregion-expected.svg (added)
-
LayoutTests/svg/filters/feImage-element-primitive-subregion.svg (added)
-
LayoutTests/svg/filters/feImage-image-primitive-subregion-expected.svg (added)
-
LayoutTests/svg/filters/feImage-image-primitive-subregion.svg (added)
-
LayoutTests/svg/filters/feImage-remove-target-expected.txt (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/svg/SVGFEImageElement.cpp (modified) (3 diffs)
-
Source/WebCore/svg/SVGFEImageElement.h (modified) (2 diffs)
-
Source/WebCore/svg/graphics/filters/SVGFEImage.cpp (modified) (3 diffs)
-
Source/WebCore/svg/graphics/filters/SVGFEImage.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r285478 r285481 1 2021-11-08 Said Abou-Hallawa <said@apple.com> 2 3 [GPU Process] Remove non-platform code form the FEImage class 4 https://bugs.webkit.org/show_bug.cgi?id=232369 5 rdar://84966765 6 7 Reviewed by Simon Fraser. 8 9 * fast/shadow-dom/svg-feimage-href-in-shadow-tree.html: 10 The default primitive subregion of <feImage> is { -10%, -10%, 120%, 120% } 11 of the bounding box. So the filter result will be shifted (-10, -10) of 12 this test case if we do not specify the 'x' and then 'y' attributes. 13 Unlike the Image based feImage, the default behavior is to display the 14 ImageBuffer of the element with its logical size otherwise the drawing 15 will be pixelated if we try to fill the whole primitive subregion. To 16 make this test page matches its expected page, we need to specify the 'x' 17 and the 'y' attributes of the <feImage> to be zeros. 18 19 With and without specifying the 'x' and the 'y' attributes, the drawing 20 with this patch matches the drawing of this test page in other browsers. 21 22 * svg/filters/feImage-change-target-id-expected.txt: 23 * svg/filters/feImage-element-primitive-subregion-expected.svg: Added. 24 * svg/filters/feImage-element-primitive-subregion.svg: Added. 25 * svg/filters/feImage-image-primitive-subregion-expected.svg: Added. 26 * svg/filters/feImage-image-primitive-subregion.svg: Added. 27 * svg/filters/feImage-remove-target-expected.txt: 28 1 29 2021-11-08 Patrick Griffis <pgriffis@igalia.com> 2 30 -
trunk/LayoutTests/fast/shadow-dom/svg-feimage-href-in-shadow-tree.html
r238524 r285481 14 14 <rect id="rect" width="100" height="100" fill="green" /> 15 15 <filter id="image"> 16 <feImage href="#rect" />16 <feImage x="0" y="0" href="#rect" /> 17 17 </filter> 18 18 </defs> -
trunk/LayoutTests/svg/filters/feImage-change-target-id-expected.txt
r166582 r285481 6 6 RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00] 7 7 RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse] 8 [feImage image-size="0.00x0.00"]9 8 RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00] 10 9 [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120 -
trunk/LayoutTests/svg/filters/feImage-remove-target-expected.txt
r166582 r285481 5 5 RenderSVGHiddenContainer {defs} at (0,0) size 0x0 6 6 RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse] 7 [feImage image-size="0.00x0.00"]8 7 RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00] 9 8 [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120 -
trunk/Source/WebCore/ChangeLog
r285478 r285481 1 2021-11-08 Said Abou-Hallawa <said@apple.com> 2 3 [GPU Process] Remove non-platform code form the FEImage class 4 https://bugs.webkit.org/show_bug.cgi?id=232369 5 rdar://84966765 6 7 Reviewed by Simon Fraser. 8 9 SVGFEImageElement should create the FEImage with either an Image or an 10 ImageBuffer based on whether the 'href' attribute points to a resource 11 image or an SVG element. For the SVG element, an ImageBuffer will be 12 created and the renderer of this element will be drawn to it. 13 14 Instead of holding a TreeScope and Image, FEImage can hold a variant of 15 Image and ImageBuffer. 16 17 Tests: svg/filters/feImage-element-primitive-subregion-expected.svg 18 svg/filters/feImage-element-primitive-subregion.svg 19 svg/filters/feImage-image-primitive-subregion-expected.svg 20 svg/filters/feImage-image-primitive-subregion.svg 21 22 * svg/SVGFEImageElement.cpp: 23 (WebCore::SVGFEImageElement::imageBufferForEffect const): 24 (WebCore::SVGFEImageElement::build const): 25 * svg/SVGFEImageElement.h: 26 * svg/graphics/filters/SVGFEImage.cpp: 27 (WebCore::FEImage::create): 28 (WebCore::FEImage::FEImage): 29 (WebCore::FEImage::determineAbsolutePaintRect): 30 (WebCore::FEImage::platformApplySoftware): 31 (WebCore::FEImage::externalRepresentation const): 32 (WebCore::FEImage::createWithImage): Deleted. 33 (WebCore::FEImage::createWithIRIReference): Deleted. 34 (WebCore::FEImage::referencedRenderer const): Deleted. 35 * svg/graphics/filters/SVGFEImage.h: 36 1 37 2021-11-08 Patrick Griffis <pgriffis@igalia.com> 2 38 -
trunk/Source/WebCore/svg/SVGFEImageElement.cpp
r285186 r285481 3 3 * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> 4 4 * Copyright (C) 2010 Dirk Schulze <krit@webkit.org> 5 * Copyright (C) 2018 Apple Inc. All rights reserved.5 * Copyright (C) 2018-2021 Apple Inc. All rights reserved. 6 6 * 7 7 * This library is free software; you can redistribute it and/or … … 34 34 #include "SVGNames.h" 35 35 #include "SVGPreserveAspectRatioValue.h" 36 #include "SVGRenderingContext.h" 36 37 #include <wtf/IsoMallocInlines.h> 37 38 … … 176 177 } 177 178 179 std::tuple<RefPtr<ImageBuffer>, FloatRect> SVGFEImageElement::imageBufferForEffect() const 180 { 181 auto target = SVGURIReference::targetElementFromIRIString(href(), treeScope()); 182 if (!is<SVGElement>(target.element)) 183 return { }; 184 185 if (isDescendantOrShadowDescendantOf(target.element.get())) 186 return { }; 187 188 auto contextNode = static_pointer_cast<SVGElement>(target.element); 189 auto renderer = contextNode->renderer(); 190 if (!renderer) 191 return { }; 192 193 auto absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(*renderer); 194 if (!absoluteTransform.isInvertible()) 195 return { }; 196 197 auto shearFreeAbsoluteTransform = AffineTransform(absoluteTransform.xScale(), 0, 0, absoluteTransform.yScale(), 0, 0); 198 199 auto imageRect = renderer->repaintRectInLocalCoordinates(); 200 201 auto imageBuffer = SVGRenderingContext::createImageBuffer(imageRect, shearFreeAbsoluteTransform, DestinationColorSpace::SRGB(), RenderingMode::Unaccelerated); 202 if (!imageBuffer) 203 return { }; 204 205 auto& context = imageBuffer->context(); 206 SVGRenderingContext::renderSubtreeToContext(context, *renderer, AffineTransform()); 207 208 return { imageBuffer, imageRect }; 209 } 210 178 211 RefPtr<FilterEffect> SVGFEImageElement::build(SVGFilterBuilder*, Filter& filter) const 179 212 { 180 213 if (m_cachedImage) 181 return FEImage::create WithImage(filter, m_cachedImage->imageForRenderer(renderer()), preserveAspectRatio());182 183 auto target = SVGURIReference::targetElementFromIRIString(href(), treeScope());184 if ( isDescendantOrShadowDescendantOf(target.element.get()))214 return FEImage::create(filter, Ref<Image> { *m_cachedImage->imageForRenderer(renderer()) }, preserveAspectRatio()); 215 216 auto [imageBuffer, imageRect] = imageBufferForEffect(); 217 if (!imageBuffer) 185 218 return nullptr; 186 219 187 return FEImage::create WithIRIReference(filter, treeScope(), href(), preserveAspectRatio());220 return FEImage::create(filter, imageBuffer.releaseNonNull(), imageRect, preserveAspectRatio()); 188 221 } 189 222 -
trunk/Source/WebCore/svg/SVGFEImageElement.h
r261597 r285481 2 2 * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> 3 3 * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> 4 * Copyright (C) 2018-20 19Apple Inc. All rights reserved.4 * Copyright (C) 2018-2021 Apple Inc. All rights reserved. 5 5 * 6 6 * This library is free software; you can redistribute it and/or … … 56 56 void didFinishInsertingNode() override; 57 57 58 std::tuple<RefPtr<ImageBuffer>, FloatRect> imageBufferForEffect() const; 59 58 60 RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) const override; 59 61 -
trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp
r282799 r285481 4 4 * Copyright (C) 2005 Eric Seidel <eric@webkit.org> 5 5 * Copyright (C) 2010 Dirk Schulze <krit@webkit.org> 6 * Copyright (C) 2021 Apple Inc. All rights reserved. 6 7 * 7 8 * This library is free software; you can redistribute it and/or … … 24 25 #include "SVGFEImage.h" 25 26 26 #include "AffineTransform.h"27 27 #include "Filter.h" 28 28 #include "GraphicsContext.h" 29 #include "RenderElement.h"30 #include "RenderTreeAsText.h"31 #include "SVGElement.h"32 #include "SVGRenderingContext.h"33 #include "SVGURIReference.h"34 29 #include <wtf/text/TextStream.h> 35 30 36 31 namespace WebCore { 37 32 38 FEImage::FEImage(Filter& filter, RefPtr<Image> image, const SVGPreserveAspectRatioValue& preserveAspectRatio) 33 Ref<FEImage> FEImage::create(Filter& filter, Ref<Image>&& image, const SVGPreserveAspectRatioValue& preserveAspectRatio) 34 { 35 auto imageRect = FloatRect { { }, image->size() }; 36 return create(filter, WTFMove(image), imageRect, preserveAspectRatio); 37 } 38 39 Ref<FEImage> FEImage::create(Filter& filter, SourceImage&& sourceImage, const FloatRect& sourceImageRect, const SVGPreserveAspectRatioValue& preserveAspectRatio) 40 { 41 return adoptRef(*new FEImage(filter, WTFMove(sourceImage), sourceImageRect, preserveAspectRatio)); 42 } 43 44 FEImage::FEImage(Filter& filter, SourceImage&& sourceImage, const FloatRect& sourceImageRect, const SVGPreserveAspectRatioValue& preserveAspectRatio) 39 45 : FilterEffect(filter, Type::Image) 40 , m_image(image) 46 , m_sourceImage(WTFMove(sourceImage)) 47 , m_sourceImageRect(sourceImageRect) 41 48 , m_preserveAspectRatio(preserveAspectRatio) 42 49 { 43 50 } 44 51 45 FEImage::FEImage(Filter& filter, TreeScope& treeScope, const String& href, const SVGPreserveAspectRatioValue& preserveAspectRatio)46 : FilterEffect(filter, Type::Image)47 , m_treeScope(&treeScope)48 , m_href(href)49 , m_preserveAspectRatio(preserveAspectRatio)50 {51 }52 53 Ref<FEImage> FEImage::createWithImage(Filter& filter, RefPtr<Image> image, const SVGPreserveAspectRatioValue& preserveAspectRatio)54 {55 return adoptRef(*new FEImage(filter, image, preserveAspectRatio));56 }57 58 Ref<FEImage> FEImage::createWithIRIReference(Filter& filter, TreeScope& treeScope, const String& href, const SVGPreserveAspectRatioValue& preserveAspectRatio)59 {60 return adoptRef(*new FEImage(filter, treeScope, href, preserveAspectRatio));61 }62 63 52 void FEImage::determineAbsolutePaintRect() 64 53 { 65 FloatRect paintRect = filter().absoluteTransform().mapRect(filterPrimitiveSubregion()); 66 FloatRect srcRect; 67 if (m_image) { 68 srcRect.setSize(m_image->size()); 69 m_preserveAspectRatio.transformRect(paintRect, srcRect); 70 } else if (RenderElement* renderer = referencedRenderer()) 71 srcRect = filter().absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates()); 54 auto primitiveSubregion = filterPrimitiveSubregion(); 55 56 auto imageRect = WTF::switchOn(m_sourceImage, 57 [&] (const Ref<Image>&) { 58 auto imageRect = primitiveSubregion; 59 auto srcRect = m_sourceImageRect; 60 m_preserveAspectRatio.transformRect(imageRect, srcRect); 61 return imageRect; 62 }, 63 [&] (const Ref<ImageBuffer>&) { 64 return primitiveSubregion; 65 } 66 ); 67 68 imageRect = filter().absoluteTransform().mapRect(imageRect); 72 69 73 70 if (clipsToBounds()) 74 paintRect.intersect(maxEffectRect());71 imageRect.intersect(maxEffectRect()); 75 72 else 76 paintRect.unite(maxEffectRect()); 77 setAbsolutePaintRect(enclosingIntRect(paintRect)); 78 } 79 80 RenderElement* FEImage::referencedRenderer() const 81 { 82 if (!m_treeScope) 83 return nullptr; 84 auto target = SVGURIReference::targetElementFromIRIString(m_href, *m_treeScope); 85 if (!is<SVGElement>(target.element)) 86 return nullptr; 87 return target.element->renderer(); 73 imageRect.unite(maxEffectRect()); 74 setAbsolutePaintRect(enclosingIntRect(imageRect)); 88 75 } 89 76 90 77 void FEImage::platformApplySoftware() 91 78 { 92 RenderElement* renderer = referencedRenderer();93 if (!m_image && !renderer)94 return;95 96 79 // FEImage results are always in DestinationColorSpace::SRGB() 97 80 setResultColorSpace(DestinationColorSpace::SRGB()); … … 101 84 return; 102 85 103 FloatRect destRect = filter().absoluteTransform().mapRect(filterPrimitiveSubregion()); 104 105 FloatRect srcRect; 106 if (renderer) 107 srcRect = filter().absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates()); 108 else { 109 srcRect = FloatRect(FloatPoint(), m_image->size()); 110 m_preserveAspectRatio.transformRect(destRect, srcRect); 111 } 112 113 IntPoint paintLocation = absolutePaintRect().location(); 114 destRect.move(-paintLocation.x(), -paintLocation.y()); 115 86 auto primitiveSubregion = filterPrimitiveSubregion(); 116 87 auto& context = resultImage->context(); 117 88 118 if (renderer) { 119 const AffineTransform& absoluteTransform = filter().absoluteTransform(); 120 context.concatCTM(absoluteTransform); 121 122 RefPtr contextNode = downcast<SVGElement>(renderer->element()); 123 if (contextNode->hasRelativeLengths()) { 124 SVGLengthContext lengthContext(contextNode.get()); 125 FloatSize viewportSize; 126 127 // If we're referencing an element with percentage units, eg. <rect with="30%"> those values were resolved against the viewport. 128 // Build up a transformation that maps from the viewport space to the filter primitive subregion. 129 if (lengthContext.determineViewport(viewportSize)) 130 context.concatCTM(makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), destRect)); 89 WTF::switchOn(m_sourceImage, 90 [&] (const Ref<Image>& image) { 91 auto imageRect = primitiveSubregion; 92 auto srcRect = m_sourceImageRect; 93 m_preserveAspectRatio.transformRect(imageRect, srcRect); 94 imageRect = filter().absoluteTransform().mapRect(imageRect); 95 imageRect = drawingRegionOfInputImage(IntRect(imageRect)); 96 context.drawImage(image, imageRect, srcRect); 97 }, 98 [&] (const Ref<ImageBuffer>& imageBuffer) { 99 auto imageRect = primitiveSubregion; 100 imageRect.moveBy(m_sourceImageRect.location()); 101 imageRect = filter().absoluteTransform().mapRect(imageRect); 102 imageRect = drawingRegionOfInputImage(IntRect(imageRect)); 103 context.drawImageBuffer(imageBuffer, imageRect.location()); 131 104 } 132 133 AffineTransform contentTransformation; 134 SVGRenderingContext::renderSubtreeToContext(context, *renderer, contentTransformation); 135 return; 136 } 137 138 context.drawImage(*m_image, destRect, srcRect); 105 ); 139 106 } 140 107 141 108 TextStream& FEImage::externalRepresentation(TextStream& ts, RepresentationType representation) const 142 109 { 143 FloatSize imageSize;144 if (m_image)145 imageSize = m_image->size();146 else if (RenderObject* renderer = referencedRenderer())147 imageSize = enclosingIntRect(renderer->repaintRectInLocalCoordinates()).size();148 110 ts << indent << "[feImage"; 149 111 FilterEffect::externalRepresentation(ts, representation); 150 ts << " image-size=\"" << imageSize.width() << "x" << imageSize.height() << "\"]\n";112 ts << " image-size=\"" << m_sourceImageRect.width() << "x" << m_sourceImageRect.height() << "\"]\n"; 151 113 // FIXME: should this dump also object returned by SVGFEImage::image() ? 152 114 return ts; -
trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.h
r243259 r285481 4 4 * Copyright (C) 2005 Eric Seidel <eric@webkit.org> 5 5 * Copyright (C) 2010 Dirk Schulze <krit@webkit.org> 6 * Copyright (C) 2021 Apple Inc. All rights reserved. 6 7 * 7 8 * This library is free software; you can redistribute it and/or … … 24 25 25 26 #include "FilterEffect.h" 27 #include "RenderingResourceIdentifier.h" 26 28 #include "SVGPreserveAspectRatioValue.h" 27 29 28 30 namespace WebCore { 29 31 30 class Document;31 32 class Image; 32 class RenderElement; 33 class TreeScope; 33 class ImageBuffer; 34 34 35 35 class FEImage final : public FilterEffect { 36 36 public: 37 static Ref<FEImage> createWithImage(Filter&, RefPtr<Image>, const SVGPreserveAspectRatioValue&); 38 static Ref<FEImage> createWithIRIReference(Filter&, TreeScope&, const String&, const SVGPreserveAspectRatioValue&); 37 using SourceImage = std::variant< 38 Ref<Image>, 39 Ref<ImageBuffer> 40 >; 41 42 static Ref<FEImage> create(Filter&, Ref<Image>&&, const SVGPreserveAspectRatioValue&); 43 static Ref<FEImage> create(Filter&, SourceImage&&, const FloatRect& sourceImageRect, const SVGPreserveAspectRatioValue&); 44 45 SourceImage& sourceImage() { return m_sourceImage; } 46 void setImageSource(SourceImage&& sourceImage) { m_sourceImage = WTFMove(sourceImage); } 39 47 40 48 private: 41 virtual ~FEImage() = default; 42 FEImage(Filter&, RefPtr<Image>, const SVGPreserveAspectRatioValue&); 43 FEImage(Filter&, TreeScope&, const String&, const SVGPreserveAspectRatioValue&); 49 FEImage(Filter&, SourceImage&&, const FloatRect& sourceImageRect, const SVGPreserveAspectRatioValue&); 44 50 45 51 const char* filterName() const final { return "FEImage"; } 46 47 FilterEffectType filterEffectType() const final { return FilterEffectTypeImage; }48 49 RenderElement* referencedRenderer() const;50 52 51 53 void platformApplySoftware() final; … … 53 55 WTF::TextStream& externalRepresentation(WTF::TextStream&, RepresentationType) const final; 54 56 55 RefPtr<Image> m_image; 56 57 // m_treeScope will never be a dangling reference. See https://bugs.webkit.org/show_bug.cgi?id=99243 58 TreeScope* m_treeScope { nullptr }; 59 String m_href; 57 SourceImage m_sourceImage; 58 FloatRect m_sourceImageRect; 60 59 SVGPreserveAspectRatioValue m_preserveAspectRatio; 61 60 };
Note:
See TracChangeset
for help on using the changeset viewer.