summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2023-10-22 09:33:22 +0200
committerMoonchild <moonchild@palemoon.org>2023-10-22 09:33:22 +0200
commit6df4c1874704597159f84e7a8cedca6157f25ef8 (patch)
treedeeaf6d50fe17a0f2aad41388804ba99be983058
parentd5231ca7e78bf66a06133c2aa651d6e24306442a (diff)
downloaduxp-6df4c1874704597159f84e7a8cedca6157f25ef8.tar.gz
Issue #2355 - Apply self-transforms to the frame of top level <svg>
We previously didn't do this because we relied on our anonymous wrapper to perform transforms. However, that resulted in only the children transforming, and the frame's cliprect wouldn't be updated, giving the impression of the z-ordering being wrong. Also adds reftests from the relevant BZ bug found later. Resolves #2355
-rw-r--r--layout/reftests/svg/fragmentIdentifier-01.xhtml21
-rw-r--r--layout/reftests/svg/reftest.list1
-rw-r--r--layout/reftests/svg/svg-integration/reftest.list2
-rw-r--r--layout/reftests/svg/svg-integration/transform-outer-svg-01-ref.xhtml18
-rw-r--r--layout/reftests/svg/svg-integration/transform-outer-svg-01.xhtml18
-rw-r--r--layout/reftests/svg/transform-outer-svg-01-ref.svg9
-rw-r--r--layout/reftests/svg/transform-outer-svg-01.svg10
-rw-r--r--layout/svg/nsSVGOuterSVGFrame.cpp26
-rw-r--r--layout/svg/nsSVGOuterSVGFrame.h10
9 files changed, 100 insertions, 15 deletions
diff --git a/layout/reftests/svg/fragmentIdentifier-01.xhtml b/layout/reftests/svg/fragmentIdentifier-01.xhtml
index 9173f62fd5..a071bc2d6a 100644
--- a/layout/reftests/svg/fragmentIdentifier-01.xhtml
+++ b/layout/reftests/svg/fragmentIdentifier-01.xhtml
@@ -1,22 +1,27 @@
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
<head>
<title>Testcases for SVG fragment identifiers</title>
+ <style>
+ iframe {
+ border: none;
+ }
+ </style>
</head>
<body style="background-color: lime;">
<div>
- <object type="image/svg+xml" width="100" height="100" data="fragmentIdentifier-rect-01.svg#limeView" />
- <object type="image/svg+xml" width="100" height="100" data="fragmentIdentifier-rect-01.svg#svgView(viewBox(0,200,100,100))" />
- <object type="image/svg+xml" width="100" height="100" data="fragmentIdentifier-rect-01.svg#view" />
+ <iframe scrolling="no" type="image/svg+xml" width="100" height="100" src="fragmentIdentifier-rect-01.svg#limeView" />
+ <iframe scrolling="no" type="image/svg+xml" width="100" height="100" src="fragmentIdentifier-rect-01.svg#svgView(viewBox(0,200,100,100))" />
+ <iframe scrolling="no" type="image/svg+xml" width="100" height="100" src="fragmentIdentifier-rect-01.svg#view" />
</div>
<div>
- <object type="image/svg+xml" width="100" height="100" data="fragmentIdentifier-rect-01.svg#svgView(viewBox(0,0,100,100);transform(translate(0,200)))" />
- <object id="replace" type="image/svg+xml" width="100" height="100" data="fragmentIdentifier-rect-01.svg#svgView(viewBox(0,0,100,100);transform(translate(0,0))" />
- <object id="remove" type="image/svg+xml" width="100" height="100" data="fragmentIdentifier-rect-01.svg#svgView(viewBox(0,200,100,100);transform(translate(0,200)))" />
+ <iframe scrolling="no" type="image/svg+xml" width="100" height="100" src="fragmentIdentifier-rect-01.svg#svgView(viewBox(0,0,100,100);transform(translate(0,200)))" />
+ <iframe scrolling="no" id="replace" type="image/svg+xml" width="100" height="100" src="fragmentIdentifier-rect-01.svg#svgView(viewBox(0,0,100,100);transform(translate(0,0))" />
+ <iframe scrolling="no" id="remove" type="image/svg+xml" width="100" height="100" src="fragmentIdentifier-rect-01.svg#svgView(viewBox(0,200,100,100);transform(translate(0,200)))" />
</div>
<script type="text/javascript">
window.onload = function() {
- document.getElementById("replace").setAttribute("data","fragmentIdentifier-rect-01.svg#svgView(viewBox(0,0,100,100);transform(translate(0,200)))");
- document.getElementById("remove").setAttribute("data","fragmentIdentifier-rect-01.svg#svgView(viewBox(0,200,100,100))");
+ document.getElementById("replace").setAttribute("src","fragmentIdentifier-rect-01.svg#svgView(viewBox(0,0,100,100);transform(translate(0,200)))");
+ document.getElementById("remove").setAttribute("src","fragmentIdentifier-rect-01.svg#svgView(viewBox(0,200,100,100))");
document.documentElement.removeAttribute("class");
}
</script>
diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list
index 304753eb7d..4784800d28 100644
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -372,6 +372,7 @@ fuzzy-if(skiaContent,1,610) == textPath-03.svg pass.svg
== text-white-space-01.svg text-white-space-01-ref.svg
== thin-stroke-01.svg pass.svg
== zero-stroke-01.svg pass.svg
+== transform-outer-svg-01.svg transform-outer-svg-01-ref.svg
== css-transform-svg.html css-transform-svg-ref.html
== tspan-dxdy-01.svg tspan-dxdy-ref.svg
== tspan-dxdy-02.svg tspan-dxdy-ref.svg
diff --git a/layout/reftests/svg/svg-integration/reftest.list b/layout/reftests/svg/svg-integration/reftest.list
index da491b6079..93238eac66 100644
--- a/layout/reftests/svg/svg-integration/reftest.list
+++ b/layout/reftests/svg/svg-integration/reftest.list
@@ -42,3 +42,5 @@ fuzzy(1,5000) == mask-clipPath-opacity-01b.xhtml mask-clipPath-opacity-01-ref.xh
fuzzy(1,5000) == mask-clipPath-opacity-01c.xhtml mask-clipPath-opacity-01-ref.xhtml
fuzzy(1,5000) == mask-clipPath-opacity-01d.xhtml mask-clipPath-opacity-01-ref.xhtml
fuzzy(1,5000) == mask-clipPath-opacity-01e.xhtml mask-clipPath-opacity-01-ref.xhtml
+
+== transform-outer-svg-01.xhtml transform-outer-svg-01-ref.xhtml
diff --git a/layout/reftests/svg/svg-integration/transform-outer-svg-01-ref.xhtml b/layout/reftests/svg/svg-integration/transform-outer-svg-01-ref.xhtml
new file mode 100644
index 0000000000..3fa609a94b
--- /dev/null
+++ b/layout/reftests/svg/svg-integration/transform-outer-svg-01-ref.xhtml
@@ -0,0 +1,18 @@
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Test that the 'transform' attribute transforms our border too</title>
+ <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=1353697 -->
+</head>
+<body>
+
+ <svg xmlns="http://www.w3.org/2000/svg" width="250" height="250">
+ <rect x="75" y="75" width="150" height="150" fill="none" stroke="black" stroke-width="50"/>
+ <rect x="125" y="125" width="50" height="50" fill="blue"/>
+ </svg>
+
+</body>
+</html>
diff --git a/layout/reftests/svg/svg-integration/transform-outer-svg-01.xhtml b/layout/reftests/svg/svg-integration/transform-outer-svg-01.xhtml
new file mode 100644
index 0000000000..10484fbb97
--- /dev/null
+++ b/layout/reftests/svg/svg-integration/transform-outer-svg-01.xhtml
@@ -0,0 +1,18 @@
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Test that the 'transform' attribute transforms our border too</title>
+ <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=1353697 -->
+</head>
+<body>
+
+ <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"
+ style="border: 50px solid black;" transform="translate(50,50)">
+ <rect x="25" y="25" width="50" height="50" fill="blue"/>
+ </svg>
+
+</body>
+</html>
diff --git a/layout/reftests/svg/transform-outer-svg-01-ref.svg b/layout/reftests/svg/transform-outer-svg-01-ref.svg
new file mode 100644
index 0000000000..e6cc4b49a2
--- /dev/null
+++ b/layout/reftests/svg/transform-outer-svg-01-ref.svg
@@ -0,0 +1,9 @@
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250">
+ <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=1353697 -->
+ <rect x="75" y="75" width="150" height="150" fill="none" stroke="black" stroke-width="50"/>
+ <rect x="125" y="125" width="50" height="50" fill="blue"/>
+</svg>
diff --git a/layout/reftests/svg/transform-outer-svg-01.svg b/layout/reftests/svg/transform-outer-svg-01.svg
new file mode 100644
index 0000000000..c4b26c6378
--- /dev/null
+++ b/layout/reftests/svg/transform-outer-svg-01.svg
@@ -0,0 +1,10 @@
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"
+ style="border: 50px solid black;" transform="translate(50,50)">
+ <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=1353697 -->
+ <title>Test that the 'transform' attribute transforms our border too</title>
+ <rect x="25" y="25" width="50" height="50" fill="blue"/>
+</svg>
diff --git a/layout/svg/nsSVGOuterSVGFrame.cpp b/layout/svg/nsSVGOuterSVGFrame.cpp
index 3f68245e22..b3841f9a72 100644
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -721,6 +721,32 @@ nsSVGOuterSVGFrame::AttributeChanged(int32_t aNameSpaceID,
return NS_OK;
}
+bool
+nsSVGOuterSVGFrame::IsSVGTransformed(Matrix* aOwnTransform,
+ Matrix* aFromParentTransform) const
+{
+ // The HasChildrenOnlyTransform() implementation of our anonymous child makes sure
+ // our transforms are applied to our children as-appropriate. So, we only care
+ // about self-transforms on our own frame, here.
+
+ bool hasTransform = false;
+
+ SVGSVGElement* content = static_cast<SVGSVGElement*>(mContent);
+ nsSVGAnimatedTransformList* animatedTransformList = content->GetAnimatedTransformList();
+ if ((animatedTransformList && animatedTransformList->HasTransform()) ||
+ content->GetAnimateMotionTransform()) {
+ if (aOwnTransform) {
+ // Apply transform
+ *aOwnTransform = gfx::ToMatrix(
+ content->PrependLocalTransformsTo(
+ gfxMatrix(), eUserSpaceToParent));
+ }
+ hasTransform = true;
+ }
+
+ return hasTransform;
+}
+
//----------------------------------------------------------------------
// painting
diff --git a/layout/svg/nsSVGOuterSVGFrame.h b/layout/svg/nsSVGOuterSVGFrame.h
index 4705b6ebe7..f33b7cbf63 100644
--- a/layout/svg/nsSVGOuterSVGFrame.h
+++ b/layout/svg/nsSVGOuterSVGFrame.h
@@ -101,13 +101,9 @@ public:
return PrincipalChildList().FirstChild()->GetContentInsertionFrame();
}
- virtual bool IsSVGTransformed(Matrix *aOwnTransform,
- Matrix *aFromParentTransform) const override {
- // Our anonymous wrapper performs the transforms. We simply
- // return whether we are transformed here but don't apply the transforms
- // themselves.
- return PrincipalChildList().FirstChild()->IsSVGTransformed();
- }
+ // Applies only to our own frame, see implementation note.
+ bool IsSVGTransformed(Matrix* aOwnTransform,
+ Matrix* aFromParentTransform) const override;
// nsISVGSVGFrame interface:
virtual void NotifyViewportOrTransformChanged(uint32_t aFlags) override;