summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/svg
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/svg')
-rw-r--r--testing/web-platform/tests/svg/linking/reftests/url-processing-invalid-base.svg15
-rw-r--r--testing/web-platform/tests/svg/linking/scripted/testcommon.js8
-rw-r--r--testing/web-platform/tests/svg/painting/reftests/paint-context-006-ref.svg21
-rw-r--r--testing/web-platform/tests/svg/painting/reftests/paint-context-006.svg36
-rw-r--r--testing/web-platform/tests/svg/types/scripted/SVGGraphicsElement.getScreenCTM.html245
5 files changed, 307 insertions, 18 deletions
diff --git a/testing/web-platform/tests/svg/linking/reftests/url-processing-invalid-base.svg b/testing/web-platform/tests/svg/linking/reftests/url-processing-invalid-base.svg
deleted file mode 100644
index fc5d7c6b06..0000000000
--- a/testing/web-platform/tests/svg/linking/reftests/url-processing-invalid-base.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg"
- xmlns:html="http://www.w3.org/1999/xhtml">
- <title>An invalid base URL makes all internal references invalid</title>
- <html:link rel="help" href="https://svgwg.org/svg2-draft/linking.html#processingURL"/>
- <html:link rel="help" href="https://svgwg.org/svg2-draft/painting.html#SpecifyingPaint"/>
- <html:link rel="help" href="https://svgwg.org/svg2-draft/pservers.html#PaintServerTemplates"/>
- <html:link rel="match" href="reference/green-100x100.svg"/>
- <html:base href="invalid:"/>
- <linearGradient id="p2">
- <stop stop-color="orange"/>
- </linearGradient>
- <linearGradient id="p" href="#p2"/>
- <rect width="100" height="100" fill="red"/>
- <rect width="100" height="100" fill="url(#p) green"/>
-</svg>
diff --git a/testing/web-platform/tests/svg/linking/scripted/testcommon.js b/testing/web-platform/tests/svg/linking/scripted/testcommon.js
index 7d87923f59..7177dd801f 100644
--- a/testing/web-platform/tests/svg/linking/scripted/testcommon.js
+++ b/testing/web-platform/tests/svg/linking/scripted/testcommon.js
@@ -23,9 +23,11 @@ function createSVGElement(test, tag, parent, attrs) {
}
}
parent.appendChild(elem);
- test.add_cleanup(function() {
- elem.remove();
- });
+ if (test) {
+ test.add_cleanup(function() {
+ elem.remove();
+ });
+ }
return elem;
}
diff --git a/testing/web-platform/tests/svg/painting/reftests/paint-context-006-ref.svg b/testing/web-platform/tests/svg/painting/reftests/paint-context-006-ref.svg
new file mode 100644
index 0000000000..6aa42374c5
--- /dev/null
+++ b/testing/web-platform/tests/svg/painting/reftests/paint-context-006-ref.svg
@@ -0,0 +1,21 @@
+<svg id="svg-root" viewBox="0 0 800 600"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:html="http://www.w3.org/1999/xhtml">
+ <g id="testmeta">
+ <title>Paint: 'context-fill' for markers with gradient</title>
+ <html:link rel="author"
+ title="Stefan Zager"
+ href="mailto:szager@chromium.org"/>
+ </g>
+
+ <defs>
+ <linearGradient id="lg" x1="10%">
+ <stop offset="0" stop-color="red"/>
+ <stop offset="1" stop-color="blue"/>
+ </linearGradient>
+ </defs>
+
+ <path id="test-reference" fill="url(#lg)"
+ d="M 90 75 h 400 v 50 h 200 v 400 h -540 v -350 h -60 Z"/>
+ <text x="290" y="105" style="font-size:96px" stroke="black" fill="none" rotate="45">A</text>
+</svg>
diff --git a/testing/web-platform/tests/svg/painting/reftests/paint-context-006.svg b/testing/web-platform/tests/svg/painting/reftests/paint-context-006.svg
new file mode 100644
index 0000000000..95bd2740fa
--- /dev/null
+++ b/testing/web-platform/tests/svg/painting/reftests/paint-context-006.svg
@@ -0,0 +1,36 @@
+<svg id="svg-root" viewBox="0 0 800 600"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:html="http://www.w3.org/1999/xhtml">
+ <g id="testmeta">
+ <title>Paint: 'context-fill' for markers with gradient</title>
+ <html:link rel="author"
+ title="Stefan Zager"
+ href="mailto:szager@chromium.org"/>
+ <html:link rel="help"
+ href="https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint"/>
+ <html:link rel="match" href="paint-context-006-ref.svg" />
+ </g>
+
+ <defs>
+ <linearGradient id="lg">
+ <stop offset="0" stop-color="red"/>
+ <stop offset="1" stop-color="blue"/>
+ </linearGradient>
+
+ <marker id="inner-marker" refX="50" refY="20" markerWidth="100" markerHeight="50">
+ <rect width="100" height="50" fill="context-fill"/>
+ </marker>
+
+ <marker id="marker" refX="50" refY="340" markerWidth="100" markerHeight="400" orient="0.25turn">
+ <g fill="context-fill">
+ <rect y="40" width="100" height="360"/>
+ <text x="30" y="200" style="font-size:96px" stroke="black" rotate="-45">A</text>
+ <path d="M 50 40 v -20" marker-end="url(#inner-marker)"/>
+ </g>
+ </marker>
+ </defs>
+
+ <path id="test-body-content" fill="url(#lg)"
+ d="M 150 125 h 540 v 400 h -540 Z"
+ marker-start="url(#marker)"/>
+</svg>
diff --git a/testing/web-platform/tests/svg/types/scripted/SVGGraphicsElement.getScreenCTM.html b/testing/web-platform/tests/svg/types/scripted/SVGGraphicsElement.getScreenCTM.html
new file mode 100644
index 0000000000..7e5dfc649f
--- /dev/null
+++ b/testing/web-platform/tests/svg/types/scripted/SVGGraphicsElement.getScreenCTM.html
@@ -0,0 +1,245 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>SVGGraphicsElement.getScreenCTM</title>
+ <metadata>
+ <link rel="help" href="https://svgwg.org/svg2-draft/types.html#InterfaceSVGGraphicsElement"/>
+ </metadata>
+ <script src="../../linking/scripted/testcommon.js"></script>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<style>
+ body {
+ margin: 8px;
+ }
+ .absPosAtTopLeft {
+ position: absolute;
+ top: 0;
+ left: 0;
+ }
+ .absPosMegaOffset {
+ position: absolute;
+ left: 1px;
+ top: 2px;
+ margin-left: 3px;
+ margin-top: 4px;
+ padding-left: 5px;
+ padding-top: 6px;
+ }
+ .svgMegaOffset {
+ margin-left: 7px;
+ margin-top: 8px;
+ padding-left: 9px;
+ padding-top: 10px;
+ }
+</style>
+<div style="transform: translate(50px, 50px)">
+ <svg id="svg1" width="150" height="150">
+ <rect id="rect1" fill="lime" x="50" y="50" width="100" height="100"/>
+ </svg>
+</div>
+<script>
+/* Utility function to append an unstyled div to the body, with the
+ * div containing a 200x120 SVG element. */
+function make_subtree() {
+ let container = document.createElement("div");
+ // Pass in "null" for test param, since we don't want this <svg> element
+ // to get autoremoved at cleanup time. (It's easier to debug test failures
+ // if we leave it in the DOM, for manual inspection in devtools.)
+ let svg = createSVGElement(null, "svg", container,
+ {width: 200, height: 120});
+ document.body.appendChild(container);
+ return container;
+}
+
+/* Utility function for checking a CTM matrix's components: */
+function assert_ctm_equals(actualCTM, expectedCTM) {
+ // Check every component for which an expected value was provided:
+ for (let key in expectedCTM) {
+ let actualVal = actualCTM[key];
+ let expectedVal = expectedCTM[key];
+
+ // Special-case: browsers sometimes get `-0` in CTMs which
+ // is ~fine since it's numerically equivalent; but assert_equals
+ // treats it as different, which is why it needs special handling here
+ // (pretending the -0 was in fact 0), to avoid a spurious test-failure.
+ if (Object.is(expectedVal, 0) && Object.is(actualVal, -0)) {
+ actualVal = 0;
+ }
+ assert_equals(actualVal, expectedVal, `CTM component ${key}`);
+ }
+}
+
+test(function() {
+ let pt = DOMPoint.fromPoint({x: 58, y: 58});
+ let screenCTM = svg1.getScreenCTM();
+ assert_ctm_equals(screenCTM, { a: 1, b: 0,
+ c: 0, d: 1,
+ e: 58, f: 58 });
+
+ let transformedPoint = pt.matrixTransform(screenCTM.inverse());
+ assert_equals(transformedPoint.x, 0);
+ assert_equals(transformedPoint.y, 0);
+}, "<svg> should give correct screen CTM for transform:translate(...) on " +
+ "ancestor elem, combined with margin on <body>");
+
+test(function() {
+ let screenCTM = document.getElementById("rect1").getScreenCTM();
+ assert_ctm_equals(screenCTM, { a: 1, b: 0,
+ c: 0, d: 1,
+ e: 58, f: 58 });
+}, "<rect> should give correct screen CTM for transform:translate(...) on " +
+ "ancestor elem, combined with margin on <body>");
+
+test(function() {
+ let container = make_subtree();
+ let svg = container.firstChild;
+ container.style.transform = "scale(2,1)";
+
+ // First four CTM components should encode the scaleX=2 and scaleY=1.
+ // (The other two depend on where the SVG ended up on the page and
+ // are dependent on its in-flow position, so we're not bothering to
+ // check them here, but we will in the next part.)
+ let screenCTM = svg.getScreenCTM();
+ assert_ctm_equals(screenCTM, { a: 2, b: 0,
+ c: 0, d: 1 });
+
+ // Now we make the container abspos so that we can reliably predict the
+ // position:
+ container.classList.add("absPosAtTopLeft");
+
+ // First four CTM components should still encode those same scale factors.
+ // The last two components should now encode a -100px translateX, since
+ // (starting with the SVG positioned at the screen's origin) we've scaled up
+ // the container by 2x in the horizontal axis, about its own center point,
+ // which shifts half of its original width (100px) off the left side of the
+ // screen.
+ screenCTM = svg.getScreenCTM();
+ assert_ctm_equals(screenCTM, { a: 2, b: 0,
+ c: 0, d: 1,
+ e: -100, f: 0 });
+}, "<svg> should give correct screen CTM for transform:scale(2,1) on ancestor");
+
+test(function() {
+ let container = make_subtree();
+ let svg = container.firstChild;
+
+ container.classList.add("absPosAtTopLeft");
+ svg.style.transform = "scale(0.5)";
+
+ // First four CTM components should encode the scale(0.5). The last two
+ // components should encode a translation inwards by 1/4 of the <svg>'s
+ // size in each axis, since we're shrinking by 1/2 about the center point.
+ // (1/4 of the 200px width is 50px, and 1/4 of the 120px height is 30px)
+ let screenCTM = svg.getScreenCTM();
+ assert_ctm_equals(screenCTM, { a: 0.5, b: 0,
+ c: 0, d: 0.5,
+ e: 50, f: 30 });
+}, "<svg> should give correct screen CTM for transform:scale(0.5) on self");
+
+test(function() {
+ let container = make_subtree();
+ let svg = container.firstChild;
+
+ container.classList.add("absPosMegaOffset");
+ container.style.transform = "translate(20px, 30px)";
+ svg.classList.add("svgMegaOffset");
+ svg.style.transform = "translate(40px, 50px)";
+
+ // Expecting CTM to have:
+ // * identity matrix for scale components
+ // * translateX component of 1+3+5+7+9+20+40 = 85
+ // * translateY component of 2+4+6+8+10+30+50 = 110
+ let screenCTM = svg.getScreenCTM();
+ assert_ctm_equals(screenCTM, { a: 1, b: 0,
+ c: 0, d: 1,
+ e: 85, f: 110 });
+}, "<svg> should give correct screen CTM with many forms of offsets on " +
+ "ancestor and self");
+
+test(function() {
+ let container = make_subtree();
+ let svg = container.firstChild;
+ // Note: in cases where the SVG is rotated, we have to override
+ // the default 'vertical-align:baseline' to avoid having our flipped
+ // y-position be influenced by baseline-related offsets that come from
+ // the line box.
+ svg.style.verticalAlign = "top";
+ container.classList.add("absPosAtTopLeft");
+
+ container.style.transform = "rotate(90deg)";
+ svg.style.transform = "rotate(270deg)";
+ let screenCTM = svg.getScreenCTM();
+ assert_ctm_equals(screenCTM, { a: 1, b: 0,
+ c: 0, d: 1,
+ e: 0, f: 0 });
+
+ container.style.transform = "rotate(270deg)";
+ svg.style.transform = "rotate(90deg)";
+ screenCTM = svg.getScreenCTM();
+ assert_ctm_equals(screenCTM, { a: 1, b: 0,
+ c: 0, d: 1,
+ e: 0, f: 0 });
+
+ container.style.transform = "rotate(180deg)";
+ svg.style.transform = "rotate(180deg)";
+ screenCTM = svg.getScreenCTM();
+ assert_ctm_equals(screenCTM, { a: 1, b: 0,
+ c: 0, d: 1,
+ e: 0, f: 0 });
+}, "<svg> should give identity screen CTM with friendly rotations on " +
+ "ancestor and self that add up to 360deg");
+
+test(function() {
+ let container = make_subtree();
+ let svg = container.firstChild;
+ container.classList.add("absPosAtTopLeft");
+ svg.classList.add("svgMegaOffset");
+ container.style.transform = "rotate(180deg)";
+ svg.style.verticalAlign = "top";
+
+ // Expecting CTM to have:
+ // * "flip" matrix for scale components (-1 instead of 1)
+ // * translateX component of 200px, which comes from our 200px width.
+ // * translateY component of 70px, which comes from our 120px height.
+ // Note that our "svgMegaOffset" offsets have no effect on our CTM, because
+ // they end up on the right side when the SVG rotates about its border-box's
+ // center point, so they don't influence where the SVG geometry actually ends
+ // up in the screen's coordinate space and are hence irrelevant to the CTM.
+ let screenCTM = svg.getScreenCTM();
+ assert_ctm_equals(screenCTM, { a: -1, b: 0,
+ c: 0, d: -1,
+ e: 200, f: 120 });
+}, "<svg> should give correct screen CTM with many forms of offsets on " +
+ "self, and rotated self");
+
+test(function() {
+ let container = make_subtree();
+ let svg = container.firstChild;
+ container.classList.add("absPosAtTopLeft");
+ container.style.transform = "rotate(180deg)";
+ svg.classList.add("svgMegaOffset");
+ svg.style.transform = "translate(40px, 50px)";
+ svg.style.verticalAlign = "top";
+
+ // Expecting CTM to have:
+ // * "flip" matrix for scale components (-1 instead of 1)
+ // * translateX component of 160px, which comes from the 40px in our
+ // "translate(40px,50px), taken as a reduction from our 200px width.
+ // * translateY component of 70px, which comes from the 50px in our
+ // "translate(40px,50px), taken as a reduction from our 120px height.
+ // Note that our "svgMegaOffset" offsets have no effect on our CTM, because
+ // they end up on the right side when our ancestor rotates about its center
+ // point, so they end up irrelevant to our CTM.
+ let screenCTM = svg.getScreenCTM();
+ assert_ctm_equals(screenCTM, { a: -1, b: 0,
+ c: 0, d: -1,
+ e: 160, f: 70 });
+}, "<svg> should give correct screen CTM with many forms of offsets on " +
+ "self, and rotated ancestor");
+
+</script>
+</body>
+</html>