Diff
Modified: trunk/LayoutTests/ChangeLog (281735 => 281736)
--- trunk/LayoutTests/ChangeLog 2021-08-28 16:48:16 UTC (rev 281735)
+++ trunk/LayoutTests/ChangeLog 2021-08-29 01:31:55 UTC (rev 281736)
@@ -1,3 +1,20 @@
+2021-08-28 Simon Fraser <[email protected]>
+
+ Zooming browser does not properly scale SVG clip paths
+ https://bugs.webkit.org/show_bug.cgi?id=224795
+
+ Reviewed by Tim Horton.
+
+ Tests for various clipping configurations which use the 'zoom' property which
+ has the same impact as Command+ zooming.
+
+ * css3/masking/clip-path-reference-painted-mask-zoom-expected.html: Added.
+ * css3/masking/clip-path-reference-painted-mask-zoom.html: Added.
+ * css3/masking/clip-path-reference-zoom-expected.html: Added.
+ * css3/masking/clip-path-reference-zoom-objectBoundingBox-expected.html: Added.
+ * css3/masking/clip-path-reference-zoom-objectBoundingBox.html: Added.
+ * css3/masking/clip-path-reference-zoom.html: Added.
+
2021-08-28 Alan Bujtas <[email protected]>
[LFC][IFC] Move content builder functionality to a dedicated class
Added: trunk/LayoutTests/css3/masking/clip-path-reference-painted-mask-zoom-expected.html (0 => 281736)
--- trunk/LayoutTests/css3/masking/clip-path-reference-painted-mask-zoom-expected.html (rev 0)
+++ trunk/LayoutTests/css3/masking/clip-path-reference-painted-mask-zoom-expected.html 2021-08-29 01:31:55 UTC (rev 281736)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<style>
+#d {
+ position: absolute;
+ top: 40px;
+ left: 40px;
+ width: 360px;
+ height: 360px;
+ background-color: blue;
+ box-sizing: border-box;
+}
+
+#clip {
+ width: 64px;
+ height: 64px;
+ margin: 150px;
+ background-color: green;
+}
+</style>
+</head>
+<body>
+<div id="d"><div id="clip"></div></div>
+</body>
+</html>
Added: trunk/LayoutTests/css3/masking/clip-path-reference-painted-mask-zoom.html (0 => 281736)
--- trunk/LayoutTests/css3/masking/clip-path-reference-painted-mask-zoom.html (rev 0)
+++ trunk/LayoutTests/css3/masking/clip-path-reference-painted-mask-zoom.html 2021-08-29 01:31:55 UTC (rev 281736)
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<style>
+#d {
+ position: absolute;
+ top: 20px;
+ left: 20px;
+ width: 180px;
+ height: 180px;
+ background-color: blue;
+ box-sizing: border-box;
+ zoom: 2;
+}
+
+#clip {
+ width: 160px;
+ height: 160px;
+ margin: 10px;
+ background-color: green;
+ clip-path: url(#c2);
+}
+</style>
+</head>
+<body>
+<svg height="100" width="100">
+<clipPath id="c2">
+ <rect x="65" y="65" width="32" height="18"/>
+ <rect x="65" y="81" width="32" height="16"/>
+</clipPath>
+</svg>
+
+<div id="d"><div id="clip"></div></div>
+</body>
+</html>
Added: trunk/LayoutTests/css3/masking/clip-path-reference-zoom-expected.html (0 => 281736)
--- trunk/LayoutTests/css3/masking/clip-path-reference-zoom-expected.html (rev 0)
+++ trunk/LayoutTests/css3/masking/clip-path-reference-zoom-expected.html 2021-08-29 01:31:55 UTC (rev 281736)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<style>
+#d {
+ position: absolute;
+ top: 40px;
+ left: 40px;
+ width: 360px;
+ height: 360px;
+ background-color: blue;
+ box-sizing: border-box;
+}
+
+#clip {
+ width: 64px;
+ height: 64px;
+ margin: 150px;
+ background-color: green;
+}
+</style>
+</head>
+<body>
+<div id="d"><div id="clip"></div></div>
+</body>
+</html>
Added: trunk/LayoutTests/css3/masking/clip-path-reference-zoom-objectBoundingBox-expected.html (0 => 281736)
--- trunk/LayoutTests/css3/masking/clip-path-reference-zoom-objectBoundingBox-expected.html (rev 0)
+++ trunk/LayoutTests/css3/masking/clip-path-reference-zoom-objectBoundingBox-expected.html 2021-08-29 01:31:55 UTC (rev 281736)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<style>
+#d {
+ position: absolute;
+ top: 40px;
+ left: 40px;
+ width: 360px;
+ height: 360px;
+ background-color: blue;
+ box-sizing: border-box;
+}
+
+#clip {
+ width: 160px;
+ height: 160px;
+ margin: 100px;
+ background-color: green;
+}
+</style>
+</head>
+<body>
+<div id="d"><div id="clip"></div></div>
+</body>
+</html>
Added: trunk/LayoutTests/css3/masking/clip-path-reference-zoom-objectBoundingBox.html (0 => 281736)
--- trunk/LayoutTests/css3/masking/clip-path-reference-zoom-objectBoundingBox.html (rev 0)
+++ trunk/LayoutTests/css3/masking/clip-path-reference-zoom-objectBoundingBox.html 2021-08-29 01:31:55 UTC (rev 281736)
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<style>
+#d {
+ position: absolute;
+ top: 20px;
+ left: 20px;
+ width: 180px;
+ height: 180px;
+ background-color: blue;
+ box-sizing: border-box;
+ zoom: 2;
+}
+
+#clip {
+ width: 160px;
+ height: 160px;
+ margin: 10px;
+ background-color: green;
+ clip-path: url(#c2);
+}
+</style>
+</head>
+<body>
+<svg height="100" width="100">
+<clipPath id="c2" clipPathUnits="objectBoundingBox">
+ <rect x="0.25" y="0.25" width="0.5" height="0.5"/>
+</clipPath>
+</svg>
+
+<div id="d"><div id="clip"></div></div>
+</body>
+</html>
Added: trunk/LayoutTests/css3/masking/clip-path-reference-zoom.html (0 => 281736)
--- trunk/LayoutTests/css3/masking/clip-path-reference-zoom.html (rev 0)
+++ trunk/LayoutTests/css3/masking/clip-path-reference-zoom.html 2021-08-29 01:31:55 UTC (rev 281736)
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<style>
+#d {
+ position: absolute;
+ top: 20px;
+ left: 20px;
+ width: 180px;
+ height: 180px;
+ background-color: blue;
+ box-sizing: border-box;
+ zoom: 2;
+}
+
+#clip {
+ width: 160px;
+ height: 160px;
+ margin: 10px;
+ background-color: green;
+ clip-path: url(#c2);
+}
+</style>
+</head>
+<body>
+<svg height="100" width="100">
+<clipPath id="c2">
+ <rect x="65" y="65" width="32" height="32"/>
+</clipPath>
+</svg>
+
+<div id="d"><div id="clip"></div></div>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (281735 => 281736)
--- trunk/Source/WebCore/ChangeLog 2021-08-28 16:48:16 UTC (rev 281735)
+++ trunk/Source/WebCore/ChangeLog 2021-08-29 01:31:55 UTC (rev 281736)
@@ -1,3 +1,34 @@
+2021-08-28 Simon Fraser <[email protected]>
+
+ Zooming browser does not properly scale SVG clip paths
+ https://bugs.webkit.org/show_bug.cgi?id=224795
+
+ Reviewed by Tim Horton.
+
+ Clip-path and Command+ zooming were fixed in r268138, but that change didn't address
+ reference clip paths.
+
+ Fix by having effectiveZoom scale the clip in the two codepaths; the "clip via a path"
+ path, and the "clip by painting a mask" path that we fall into for more complex clips.
+
+ We only need to fix the userSpaceOnUse code path, since with objectBoundingBox clips
+ the input bounds has already been scaled.
+
+ Tests use the non-standard "zoom" property, so can't be WPT tests.
+
+ Tests: css3/masking/clip-path-reference-painted-mask-zoom.html
+ css3/masking/clip-path-reference-zoom-objectBoundingBox.html
+ css3/masking/clip-path-reference-zoom.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::setupClipPath):
+ * rendering/svg/RenderSVGResourceClipper.cpp:
+ (WebCore::RenderSVGResourceClipper::applyResource):
+ (WebCore::RenderSVGResourceClipper::pathOnlyClipping):
+ (WebCore::RenderSVGResourceClipper::applyClippingToContext):
+ (WebCore::RenderSVGResourceClipper::drawContentIntoMaskImage):
+ * rendering/svg/RenderSVGResourceClipper.h:
+
2021-08-28 Alan Bujtas <[email protected]>
[LFC][IFC] Move content builder functionality to a dedicated class
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (281735 => 281736)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2021-08-28 16:48:16 UTC (rev 281735)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2021-08-29 01:31:55 UTC (rev 281736)
@@ -3194,7 +3194,7 @@
auto offset = referenceBox.location();
context.translate(offset);
FloatRect svgReferenceBox { {}, referenceBox.size() };
- downcast<RenderSVGResourceClipper>(*element->renderer()).applyClippingToContext(renderer(), svgReferenceBox, context);
+ downcast<RenderSVGResourceClipper>(*element->renderer()).applyClippingToContext(context, renderer(), svgReferenceBox, renderer().style().effectiveZoom());
context.translate(-offset);
return true;
}
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp (281735 => 281736)
--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp 2021-08-28 16:48:16 UTC (rev 281735)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp 2021-08-29 01:31:55 UTC (rev 281736)
@@ -76,10 +76,10 @@
if (repaintRect.isEmpty())
return true;
- return applyClippingToContext(renderer, renderer.objectBoundingBox(), *context);
+ return applyClippingToContext(*context, renderer, renderer.objectBoundingBox());
}
-bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext& context, const AffineTransform& animatedLocalTransform, const FloatRect& objectBoundingBox)
+bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext& context, const AffineTransform& animatedLocalTransform, const FloatRect& objectBoundingBox, float effectiveZoom)
{
// If the current clip-path gets clipped itself, we have to fall back to masking.
if (style().clipPath())
@@ -120,6 +120,10 @@
transform.translate(objectBoundingBox.location());
transform.scale(objectBoundingBox.size());
clipPath.transform(transform);
+ } else if (effectiveZoom != 1) {
+ AffineTransform transform;
+ transform.scale(effectiveZoom);
+ clipPath.transform(transform);
}
// Transform path by animatedLocalTransform.
@@ -132,7 +136,7 @@
return true;
}
-bool RenderSVGResourceClipper::applyClippingToContext(RenderElement& renderer, const FloatRect& objectBoundingBox, GraphicsContext& context)
+bool RenderSVGResourceClipper::applyClippingToContext(GraphicsContext& context, RenderElement& renderer, const FloatRect& objectBoundingBox, float effectiveZoom)
{
ClipperData& clipperData = addRendererToClipper(renderer);
@@ -140,7 +144,7 @@
AffineTransform animatedLocalTransform = clipPathElement().animatedLocalTransform();
- if (!clipperData.imageBuffer && pathOnlyClipping(context, animatedLocalTransform, objectBoundingBox))
+ if (!clipperData.imageBuffer && pathOnlyClipping(context, animatedLocalTransform, objectBoundingBox, effectiveZoom))
return true;
AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
@@ -162,13 +166,13 @@
if (resources && (clipper = resources->clipper())) {
GraphicsContextStateSaver stateSaver(maskContext);
- if (!clipper->applyClippingToContext(*this, objectBoundingBox, maskContext))
+ if (!clipper->applyClippingToContext(maskContext, *this, objectBoundingBox))
return false;
- succeeded = drawContentIntoMaskImage(*clipperData.imageBuffer, objectBoundingBox);
+ succeeded = drawContentIntoMaskImage(*clipperData.imageBuffer, objectBoundingBox, effectiveZoom);
// The context restore applies the clipping on non-CG platforms.
} else
- succeeded = drawContentIntoMaskImage(*clipperData.imageBuffer, objectBoundingBox);
+ succeeded = drawContentIntoMaskImage(*clipperData.imageBuffer, objectBoundingBox, effectiveZoom);
if (!succeeded)
clipperData = { };
@@ -181,7 +185,7 @@
return true;
}
-bool RenderSVGResourceClipper::drawContentIntoMaskImage(ImageBuffer& maskImageBuffer, const FloatRect& objectBoundingBox)
+bool RenderSVGResourceClipper::drawContentIntoMaskImage(ImageBuffer& maskImageBuffer, const FloatRect& objectBoundingBox, float effectiveZoom)
{
GraphicsContext& maskContext = maskImageBuffer.context();
@@ -190,6 +194,9 @@
maskContentTransformation.translate(objectBoundingBox.location());
maskContentTransformation.scale(objectBoundingBox.size());
maskContext.concatCTM(maskContentTransformation);
+ } else if (effectiveZoom != 1) {
+ maskContentTransformation.scale(effectiveZoom);
+ maskContext.concatCTM(maskContentTransformation);
}
// Switch to a paint behavior where all children of this <clipPath> will be rendered using special constraints:
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h (281735 => 281736)
--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h 2021-08-28 16:48:16 UTC (rev 281735)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h 2021-08-29 01:31:55 UTC (rev 281736)
@@ -45,7 +45,7 @@
// clipPath can be clipped too, but don't have a boundingBox or repaintRect. So we can't call
// applyResource directly and use the rects from the object, since they are empty for RenderSVGResources
// FIXME: We made applyClippingToContext public because we cannot call applyResource on HTML elements (it asserts on RenderObject::objectBoundingBox)
- bool applyClippingToContext(RenderElement&, const FloatRect&, GraphicsContext&);
+ bool applyClippingToContext(GraphicsContext&, RenderElement&, const FloatRect&, float effectiveZoom = 1);
FloatRect resourceBoundingBox(const RenderObject&) override;
RenderSVGResourceType resourceType() const override { return ClipperResourceType; }
@@ -81,8 +81,8 @@
const char* renderName() const override { return "RenderSVGResourceClipper"; }
bool isSVGResourceClipper() const override { return true; }
- bool pathOnlyClipping(GraphicsContext&, const AffineTransform&, const FloatRect&);
- bool drawContentIntoMaskImage(ImageBuffer&, const FloatRect& objectBoundingBox);
+ bool pathOnlyClipping(GraphicsContext&, const AffineTransform&, const FloatRect&, float effectiveZoom);
+ bool drawContentIntoMaskImage(ImageBuffer&, const FloatRect& objectBoundingBox, float effectiveZoom);
void calculateClipContentRepaintRect();
ClipperData& addRendererToClipper(const RenderObject&);