Bug 1914345 Part 1 - create a pref to allow using moz2d to determine stroke bounds r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D220060
This commit is contained in:
longsonr 2024-08-27 16:20:35 +00:00
Родитель b8e14c3fca
Коммит d0a85b9aaa
10 изменённых файлов: 270 добавлений и 298 удалений

Просмотреть файл

@ -14,7 +14,6 @@ support-files = [
"bounds-helper.svg",
"dataTypes-helper.svg",
"fragments-helper.svg",
"getBBox-options-helper.svg",
"getCTM-helper.svg",
"getSubStringLength-helper.svg",
"matrixUtils.js",
@ -81,8 +80,6 @@ support-files = [
["test_fragments.html"]
["test_getBBox-options.html"]
["test_getCTM.html"]
["test_getElementById.xhtml"]

Просмотреть файл

@ -1,244 +0,0 @@
<!DOCTYPE HTML>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=999964
-->
<head>
<meta charset="utf-8"/>
<title>Test case for Bug 999964</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=999964">Mozilla Bug 999964</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<iframe id="svg" src="getBBox-options-helper.svg"></iframe>
<pre id="test">
<script class="testbody" type="application/javascript">
/** Test case for Bug 999964 **/
SimpleTest.waitForExplicitFinish();
function run() {
SpecialPowers.pushPrefEnv({'set': [['svg.new-getBBox.enabled', true]]}, runTests);
}
function runTests() {
var doc = $("svg").contentDocument;
function getBBox(id, opt) {
return doc.getElementById(id).getBBox(opt);
}
function checkBBox(id, opt, x, y, width, height, epsilon) {
if (epsilon == undefined) {
epsilon = 0.1;
}
var bbox = getBBox(id, opt);
isfuzzy(bbox.x, x, epsilon, id + ".getBBox().x " + JSON.stringify(opt));
isfuzzy(bbox.y, y, epsilon, id + ".getBBox().y " + JSON.stringify(opt));
isfuzzy(bbox.width, width, epsilon, id + ".getBBox().width " + JSON.stringify(opt));
isfuzzy(bbox.height, height, epsilon, id + ".getBBox().height " + JSON.stringify(opt));
}
function compareBBox1(id1, id2) {
var bbox1 = getBBox(id1);
var bbox2 = getBBox(id2);
is(bbox1.x, bbox2.x, id1 + ".getBBox().x");
is(bbox1.y, bbox2.y, id1 + ".getBBox().y");
isfuzzy(bbox1.width, bbox2.width, 0.0002, id1 + ".getBBox().width");
isfuzzy(bbox1.height, bbox2.height, 0.0001, id1 + ".getBBox().height");
}
function compareBBox2(id1, id2) {
// without 'x'
var bbox1 = getBBox(id1);
var bbox2 = getBBox(id2);
is(bbox1.y, bbox2.y, id1 + ".getBBox().y");
isfuzzy(bbox1.width, bbox2.width, 0.0002, id1 + ".getBBox().width");
isfuzzy(bbox1.height, bbox2.height, 0.0001, id1 + ".getBBox().height");
}
var opt = { fill: true, stroke: true, markers: true, clipped: true };
// <text>
// fill
opt = { fill: true, stroke: false, markers: false, clipped: false };
compareBBox1("text1", "text3");
compareBBox1("text2", "text4");
compareBBox1("text5", "text6");
// all
opt = { fill: true, stroke: true, markers: true, clipped: true };
compareBBox2("text1", "text3");
compareBBox2("text2", "text4");
compareBBox2("text5", "text6");
// clipped
opt = { fill: false, stroke: false, markers: false, clipped: true };
compareBBox2("text1", "text3");
compareBBox2("text2", "text4");
compareBBox2("text5", "text6");
// <image>
opt = { fill: true, stroke: true, markers: true, clipped: true };
checkBBox("image1", opt, 160, 160, 80, 80);
checkBBox("image2", opt, 53, 53, 149, 149);
checkBBox("image3", opt, 205, 53, 148, 149);
checkBBox("image4", opt, 53, 205, 149, 148);
checkBBox("image5", opt, 205, 205, 148, 148);
checkBBox("image6", opt, 52, 52, 100, 100);
checkBBox("image7", opt, 255, 52, 100, 100);
checkBBox("image8", opt, 52, 255, 100, 100);
checkBBox("image9", opt, 255, 255, 100, 100);
checkBBox("image10", opt, 200, 200, 200, 200);
checkBBox("image11", opt, 0, 0, 0, 0);
checkBBox("image12", opt, 43, 43, 714, 660);
checkBBox("image13", opt, 50, 50, 300, 300);
checkBBox("image14", opt, 0, 0, 0, 0);
opt = { fill: true, stroke: false, markers: false, clipped: false };
checkBBox("image1", opt, 150, 150, 200, 200);
checkBBox("image2", opt, 2, 2, 200, 200);
checkBBox("image3", opt, 205, 2, 200, 200);
checkBBox("image4", opt, 2, 205, 200, 200);
checkBBox("image5", opt, 205, 205, 200, 200);
checkBBox("image6", opt, 2, 2, 200, 200);
checkBBox("image7", opt, 205, 2, 200, 200);
checkBBox("image8", opt, 2, 205, 200, 200);
checkBBox("image9", opt, 205, 205, 200, 200);
checkBBox("image10", opt, 0, 0, 400, 400);
checkBBox("image11", opt, 0, 0, 400, 400);
checkBBox("image12", opt, 25, 43, 768, 768);
checkBBox("image13", opt, 0, 0, 400, 400);
// <path>
opt = { fill: true, stroke: true, markers: true, clipped: true };
checkBBox("path1", opt, 6.2, 20.8, 115.8, 91.2, 2);
checkBBox("path2", opt, 156.2, 20.8, 115.8, 91.2, 2);
checkBBox("path3", opt, 6.2, 120.7, 115.8, 91.2, 2);
checkBBox("path4", opt, 6.2, 20.8, 93.8, 79.2, 2);
checkBBox("path5", opt, 156.2, 20.8, 43.8, 79.2, 2);
checkBBox("path6", opt, 6.2, 150, 93.8, 62, 2);
checkBBox("path7", opt, 6.2, 20.8, 93.8, 79.2, 2);
checkBBox("path8", opt, 156.2, 20.8, 93.8, 79.2, 2);
checkBBox("path9", opt, 6.2, 120.8, 93.8, 79.2, 2);
checkBBox("path10", opt, 10, 25, 100, 75);
checkBBox("path11", opt, 160, 25, 100, 75);
checkBBox("path12", opt, 10, 125, 100, 75);
opt = { fill: true, stroke: false, markers: false, clipped: true };
checkBBox("path1", opt, 10, 25, 100, 75);
checkBBox("path2", opt, 160, 25, 100, 75);
checkBBox("path3", opt, 10, 125, 100, 75);
checkBBox("path4", opt, 10, 25, 90, 75);
checkBBox("path5", opt, 160, 25, 40, 75);
checkBBox("path6", opt, 10, 150, 90, 50);
checkBBox("path7", opt, 10, 25, 90, 75);
checkBBox("path8", opt, 160, 25, 90, 75);
checkBBox("path9", opt, 10, 125, 90, 75);
checkBBox("path10", opt, 10, 25, 100, 75);
checkBBox("path11", opt, 160, 25, 100, 75);
checkBBox("path12", opt, 10, 125, 100, 75);
opt = { fill: true, stroke: false, markers: false, clipped: false };
checkBBox("path1", opt, 10, 25, 100, 75);
checkBBox("path2", opt, 160, 25, 100, 75);
checkBBox("path3", opt, 10, 125, 100, 75);
checkBBox("path4", opt, 10, 25, 100, 75);
checkBBox("path5", opt, 160, 25, 100, 75);
checkBBox("path6", opt, 10, 125, 100, 75);
checkBBox("path7", opt, 10, 25, 100, 75);
checkBBox("path8", opt, 160, 25, 100, 75);
checkBBox("path9", opt, 10, 125, 100, 75);
checkBBox("path10", opt, 10, 25, 100, 75);
checkBBox("path11", opt, 160, 25, 100, 75);
checkBBox("path12", opt, 10, 125, 100, 75);
checkBBox("path13", opt, 0, 0, 100, 100);
opt = { fill: false, stroke: true, markers: false, clipped: false };
checkBBox("path1", opt, 6.2, 20.8, 107.8, 83.2, 4);
checkBBox("path2", opt, 156.2, 20.8, 107.8, 83.2, 4);
checkBBox("path3", opt, 6.2, 120.8, 107.8, 83.2, 4);
checkBBox("path4", opt, 6.2, 20.8, 107.8, 83.2, 4);
checkBBox("path5", opt, 156.2, 20.8, 107.8, 83.2, 4);
checkBBox("path6", opt, 6.2, 120.8, 107.8, 83.2, 4);
checkBBox("path7", opt, 6.2, 20.8, 107.8, 83.2, 4);
checkBBox("path8", opt, 156.2, 20.8, 107.8, 83.2, 4);
checkBBox("path9", opt, 6.2, 120.8, 107.8, 83.2, 4);
checkBBox("path10", opt, 6.2, 20.8, 107.8, 83.2, 4);
checkBBox("path11", opt, 156.2, 20.8, 107.8, 83.2, 4);
checkBBox("path12", opt, 6.2, 120.8, 107.8, 83.2, 4);
opt = { fill: false, stroke: false, markers: true, clipped: false };
checkBBox("path1", opt, 10, 25, 112, 87);
checkBBox("path2", opt, 160, 25, 112, 87);
checkBBox("path3", opt, 10, 125, 112, 87);
checkBBox("path4", opt, 10, 25, 112, 87);
checkBBox("path5", opt, 160, 25, 112, 87);
checkBBox("path6", opt, 10, 125, 112, 87);
checkBBox("path7", opt, 10, 25, 112, 87);
checkBBox("path8", opt, 160, 25, 112, 87);
checkBBox("path9", opt, 10, 125, 112, 87);
checkBBox("path10", opt, 10, 25, 112, 87);
checkBBox("path11", opt, 160, 25, 112, 87);
checkBBox("path12", opt, 10, 125, 112, 87);
// <use>
opt = { fill: true, stroke: false, markers: false, clipped: false };
checkBBox("use1", opt, 70, 70, 180, 180);
checkBBox("use2", opt, 250, 70, 180, 180);
checkBBox("use3", opt, 70, 250, 180, 180);
checkBBox("use4", opt, 22, 22, 180, 180);
checkBBox("use5", opt, 225, 22, 180, 180);
checkBBox("use6", opt, 22, 225, 180, 180);
checkBBox("use7", opt, 225, 225, 180, 180);
opt = { fill: true, stroke: true, markers: true, clipped: true };
checkBBox("use1", opt, 70, 66, 180, 94);
checkBBox("use2", opt, 250, 70, 180, 90);
checkBBox("use3", opt, 70, 250, 180, 90);
checkBBox("use4", opt, 18, 18, 134, 134);
checkBBox("use5", opt, 221, 18, 134, 134);
checkBBox("use6", opt, 18, 221, 134, 134);
checkBBox("use7", opt, 221, 221, 134, 134);
checkBBox("use8", opt, 0, 0, 0, 0);
// <foreignObject>
opt = { fill: true, stroke: false, markers: false, clipped: false };
checkBBox("fo1", opt, 2, 2, 200, 200);
checkBBox("fo2", opt, 205, 2, 200, 200);
checkBBox("fo3", opt, 2, 205, 200, 200);
checkBBox("fo4", opt, 205, 205, 200, 200);
checkBBox("fo5", opt, 250, 250, 200, 200);
checkBBox("fo6", opt, 0, 0, 200, 200);
checkBBox("fo7", opt, 0, 0, 200, 200);
opt = { fill: true, stroke: true, markers: true, clipped: true };
checkBBox("fo1", opt, 53, 53, 51, 51);
checkBBox("fo2", opt, 205, 53, 148, 149);
checkBBox("fo3", opt, 53, 205, 149, 148);
checkBBox("fo4", opt, 207, 207, 100, 100);
checkBBox("fo5", opt, 0, 0, 0, 0);
checkBBox("fo6", opt, 100, 100, 100, 100);
checkBBox("fo7", opt, 10, 10, 180, 180);
checkBBox("fo8", opt, 0, 0, 0, 0);
// from http://www.w3.org/Graphics/SVG/Test/20110816/harness/htmlObjectApproved/masking-path-07-b.html
opt = { fill: true, stroke: true, markers: true, clipped: true };
checkBBox("rect-1", opt, 10, 10, 140, 140);
checkBBox("rect-2", opt, 50, 30, 25, 100);
checkBBox("rect-3", opt, 50, 50, 100, 100);
checkBBox("g1", opt, 50, 50, 100, 100);
SimpleTest.finish();
}
window.addEventListener("load", run);
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -25,7 +25,7 @@ fuzzy-if(!useDrawSnapshot,14-14,44-95) == 1524353.html 1524353-ref.html
== 1523080.html 1523080-ref.html
== 1616444-same-color-different-paths.html 1616444-same-color-different-paths-ref.html
skip-if(useDrawSnapshot||Android) fuzzy-if(winWidget,54-94,2713-3419) fuzzy-if(cocoaWidget,24-24,1190-1200) pref(apz.allow_zooming,true) == picture-caching-on-async-zoom.html picture-caching-on-async-zoom.html?ref
pref(apz.allow_zooming,true) fails-if(useDrawSnapshot) == 1662062-1-no-blurry.html 1662062-1-ref.html
pref(apz.allow_zooming,true) fails-if(useDrawSnapshot) fuzzy-if(!useDrawSnapshot,0-244,0-4111) == 1662062-1-no-blurry.html 1662062-1-ref.html
# Bug 1715676: nsBulletFrame has been removed and the new rendering does not use PushRoundedRect that this test is for:
# == 1681610.html 1681610-ref.html
skip-if(geckoview) fuzzy-if(!useDrawSnapshot,0-255,0-1050) fuzzy-if(useDrawSnapshot,0-255,0-3617) == 1687157-1.html 1687157-1-ref.html

Просмотреть файл

@ -350,7 +350,7 @@ fuzzy(0-1,0-10000) == opacity-and-transform-01.svg opacity-and-transform-01-ref.
fuzzy-if(Android,0-8,0-200) == outer-svg-border-and-padding-01.svg outer-svg-border-and-padding-01-ref.svg
fuzzy(0-7,0-214) == outline.html outline-ref.html # Bug 1503525
fuzzy(0-255,0-214) == outline.html outline-ref.html # Bug 1503525
== overflow-on-outer-svg-01.svg overflow-on-outer-svg-01-ref.svg
== overflow-on-outer-svg-02a.xhtml overflow-on-outer-svg-02-ref.xhtml

Просмотреть файл

@ -150,7 +150,7 @@ fails == translate-rounding-3.html translate-rounding-viewport-ref.html # bug 13
== invalidate-svg-scale-1.html invalidate-svg-scale-1-ref.html
# Bug 1526847
== animate-layer-scale-inherit-4.html animate-layer-scale-inherit-4-ref.html
fuzzy-if(winWidget,0-1,0-1000) == 1569215-1.html 1569215-1-ref.html
fuzzy(0-128,0-1000) == 1569215-1.html 1569215-1-ref.html
== transform-anon-block-1.html transform-anon-block-1-ref.html
test-pref(layout.animation.prerender.partial.jank,true) test-pref(layout.animation.prerender.partial,true) == partial-prerender-expansion-translate.html partial-prerender-expansion-ref.html

Просмотреть файл

@ -19,6 +19,7 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/PresShell.h"
#include "mozilla/RefPtr.h"
#include "mozilla/StaticPrefs_svg.h"
#include "mozilla/SVGContextPaint.h"
#include "mozilla/SVGContentUtils.h"
#include "mozilla/SVGObserverUtils.h"
@ -466,51 +467,33 @@ SVGBBox SVGGeometryFrame::GetBBoxContribution(const Matrix& aToBBoxUserspace,
// Account for stroke:
if (getStroke) {
#if 0
// This disabled code is how we would calculate the stroke bounds using
// Moz2D Path::GetStrokedBounds(). Unfortunately at the time of writing
// it there are two problems that prevent us from using it.
//
// First, it seems that some of the Moz2D backends are really dumb. Not
// only do some GetStrokeOptions() implementations sometimes
// significantly overestimate the stroke bounds, but if an argument is
// passed for the aTransform parameter then they just return bounds-of-
// transformed-bounds. These two things combined can lead the bounds to
// be unacceptably oversized, leading to massive over-invalidation.
//
// Second, the way we account for non-scaling-stroke by transforming the
// path using the transform to the outer-<svg> element is not compatible
// with the way that SVGGeometryFrame::Reflow() inserts a scale
// into aToBBoxUserspace and then scales the bounds that we return.
SVGContentUtils::AutoStrokeOptions strokeOptions;
SVGContentUtils::GetStrokeOptions(&strokeOptions, element,
Style(), nullptr,
SVGContentUtils::eIgnoreStrokeDashing);
Rect strokeBBoxExtents;
gfxMatrix userToOuterSVG;
if (SVGUtils::GetNonScalingStrokeTransform(this, &userToOuterSVG)) {
Matrix outerSVGToUser = ToMatrix(userToOuterSVG);
outerSVGToUser.Invert();
Matrix outerSVGToBBox = aToBBoxUserspace * outerSVGToUser;
RefPtr<PathBuilder> builder =
pathInUserSpace->TransformedCopyToBuilder(ToMatrix(userToOuterSVG));
RefPtr<Path> pathInOuterSVGSpace = builder->Finish();
strokeBBoxExtents =
pathInOuterSVGSpace->GetStrokedBounds(strokeOptions, outerSVGToBBox);
if (StaticPrefs::svg_Moz2D_strokeBounds_enabled()) {
SVGContentUtils::AutoStrokeOptions strokeOptions;
SVGContentUtils::GetStrokeOptions(
&strokeOptions, element, Style(), nullptr,
SVGContentUtils::eIgnoreStrokeDashing);
gfxMatrix userToOuterSVG;
if (SVGUtils::GetNonScalingStrokeTransform(this, &userToOuterSVG)) {
Matrix outerSVGToUser = ToMatrix(userToOuterSVG);
outerSVGToUser.Invert();
Matrix outerSVGToBBox = aToBBoxUserspace * outerSVGToUser;
RefPtr<PathBuilder> builder =
pathInUserSpace->TransformedCopyToBuilder(
ToMatrix(userToOuterSVG));
RefPtr<Path> pathInOuterSVGSpace = builder->Finish();
strokeBBoxExtents = pathInOuterSVGSpace->GetStrokedBounds(
strokeOptions, outerSVGToBBox);
} else {
strokeBBoxExtents = pathInUserSpace->GetStrokedBounds(
strokeOptions, aToBBoxUserspace);
}
} else {
strokeBBoxExtents =
pathInUserSpace->GetStrokedBounds(strokeOptions, aToBBoxUserspace);
strokeBBoxExtents = ToRect(SVGUtils::PathExtentsToMaxStrokeExtents(
ThebesRect(pathBBoxExtents), this, ThebesMatrix(aToBBoxUserspace)));
}
MOZ_ASSERT(strokeBBoxExtents.IsFinite(), "bbox is about to go bad");
bbox.UnionEdges(strokeBBoxExtents);
#else
// For now we just use SVGUtils::PathExtentsToMaxStrokeExtents:
gfxRect strokeBBoxExtents = SVGUtils::PathExtentsToMaxStrokeExtents(
ThebesRect(pathBBoxExtents), this, ThebesMatrix(aToBBoxUserspace));
MOZ_ASSERT(ToRect(strokeBBoxExtents).IsFinite(),
"bbox is about to go bad");
bbox.UnionEdges(strokeBBoxExtents);
#endif
}
}

Просмотреть файл

@ -15780,6 +15780,12 @@
value: @IS_NIGHTLY_BUILD@
mirror: always
# Whether we use Moz2D Path::GetStrokedBounds to get the stroke bounds.
- name: svg.Moz2D.strokeBounds.enabled
type: bool
value: false
mirror: always
# Whether SVGGraphicsElement.nearestViewportElement and SVGGraphicsElement.farthestViewportElement are enabled.
- name: svg.nearestAndFarthestViewportElement.enabled
type: bool

Просмотреть файл

@ -1,2 +1,2 @@
[paint-order-002.svg]
expected: FAIL
prefs: [svg.Moz2D.strokeBounds.enabled:true]

Просмотреть файл

@ -0,0 +1,2 @@
[SVGGraphicsElement.getBBox-05.html]
prefs: [svg.new-getBBox.enabled:true, svg.Moz2D.strokeBounds.enabled:true]

Просмотреть файл

@ -1,4 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<title>SVGGraphicsElement.prototype.getBBox for SVGBoundingBoxOptions options</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="help" href="https://svgwg.org/svg2-draft/geometry.html#Sizing">
<link rel="help" href="https://svgwg.org/svg2-draft/types.html#__svg__SVGGraphicsElement__getBBox">
<link rel="help" href="https://svgwg.org/svg2-draft/coords.html#BoundingBoxes">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 500 500" width="500px" height="500px">
<defs>
@ -107,8 +113,8 @@
<path id="p1" d="M10 10l100 0 0 100 -100 0ZM50 50l40 0 0 40 -40 0Z" clip-rule="evenodd"/>
</clipPath>
<!-- "If a valid 'clip-path' reference is placed on one of the children of a 'clipPath' element,
then the given child element is clipped by the referenced clipping path before OR'ing the
<!-- "If a valid 'clip-path' reference is placed on one of the children of a 'clipPath' element,
then the given child element is clipped by the referenced clipping path before OR'ing the
silhouette of the child element with the silhouettes of the other child elements." -->
<clipPath id="clipRects1">
@ -149,7 +155,7 @@
<!-- image -->
<image id="image1" x="150" y="150" width="200" height="200" preserveApectRatio="none" clip="rect(10px,90px,90px,10px)"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
<image id="image2" x="2" y="2" width="200" height="200" clip-path="url('#circle1')" preserveApectRatio="none"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKXRFWHRDcmVhdGlvbiBUaW1lAJCFIDMwIDQgMjAxNCAwOToyODo0MyArMDkwMH73aTcAAAAHdElNRQfeBB4AHhEfV06+AAAACXBIWXMAAB7BAAAewQHDaVRTAAAABGdBTUEAALGPC/xhBQAAABlJREFUeNpjZPj/n4EUwESS6lENoxqGlAYASU8CHux7qQ4AAAAASUVORK5CYII="/>
@ -193,7 +199,7 @@
<path id="path1" d="M10,50 L25,100 H110 V50 Q60,0 10,50" stroke="black" stroke-width="8" stroke-miterlimit="1" stroke-linejoin="miter" fill="lightcyan" marker-mid="url(#m_atr)"/>
<path id="path2" d="M160,50 L175,100 H260 V50 Q210,0 160,50" stroke="black" stroke-width="8" stroke-linejoin="bevel" fill="lightcyan" marker-mid="url(#m_atr)"/>
<path id="path3" d="M10,150 L25,200 H110 V150 Q60,100 10,150" stroke="black" stroke-width="8" stroke-linejoin="round" fill="lightcyan" marker-mid="url(#m_atr)"/>
<path id="path4" d="M10,50 L25,100 H110 V50 Q60,0 10,50" stroke="black" stroke-width="8" stroke-miterlimit="1" stroke-linejoin="miter" fill="lightcyan"
marker-mid="url(#m_atr)" clip-path="url(#circle4)"/>
@ -237,7 +243,7 @@
<use id="use1" xlink:href="#rect-10" x="50" y="50" clip-path="url('#circle8')"/>
<use id="use2" xlink:href="#rect-11" x="50" y="50" clip-path="url('#circle9')"/>
<use id="use3" xlink:href="#rect-12" x="50" y="50" clip-path="url('#circle10')"/>
<use id="use4" xlink:href="#rect-10" x="2" y="2" width="200" height="200" clip-path="url('#circle11')"/>
<use id="use5" xlink:href="#rect-10" x="205" y="2" width="200" height="200" clip-path="url('#circle11')"/>
<use id="use6" xlink:href="#rect-10" x="2" y="205" width="200" height="200" clip-path="url('#circle11')"/>
@ -266,7 +272,7 @@ There are issues of dynamic loading required for tiling. According to 'postpone'
There are issues of dynamic loading required for tiling. According to 'postpone' attribute of Resource Priorities, the dynamic loading is controlled by positional relation with bounding box of embedded contents and container's viewport. However, each bounding boxes of embedded contents should be whole earth basically when this method is used. (green part on Example) Tiling is impossible unless this situation is changed.
</div>
</foreignObject>
<foreignObject id="fo5" x="250" y="250" width="200" height="200" clip-path="url('#rect8')">
<div xmlns="http://www.w3.org/1999/xhtml" style="background-color:pink;width:100%;height:100%;">
There are issues of dynamic loading required for tiling. According to 'postpone' attribute of Resource Priorities, the dynamic loading is controlled by positional relation with bounding box of embedded contents and container's viewport. However, each bounding boxes of embedded contents should be whole earth basically when this method is used. (green part on Example) Tiling is impossible unless this situation is changed.
@ -302,3 +308,225 @@ There are issues of dynamic loading required for tiling. According to 'postpone'
</g>
</svg>
<script>
function assert_bbox(id, opt, x, y, width, height, epsilon) {
if (epsilon == undefined) {
epsilon = 0.1;
}
let bbox = document.getElementById(id).getBBox(opt);
assert_approx_equals(bbox.x, x, epsilon, id + ".getBBox().x " + JSON.stringify(opt));
assert_approx_equals(bbox.y, y, epsilon, id + ".getBBox().y " + JSON.stringify(opt));
assert_approx_equals(bbox.width, width, epsilon, id + ".getBBox().width " + JSON.stringify(opt));
assert_approx_equals(bbox.height, height, epsilon, id + ".getBBox().height " + JSON.stringify(opt));
}
function compare_bbox(id1, id2, opt) {
let bbox1 = document.getElementById(id1).getBBox(opt);
let bbox2 = document.getElementById(id2).getBBox(opt);
assert_equals(bbox1.x, bbox2.x, id1 + ".getBBox().x");
assert_equals(bbox1.y, bbox2.y, id1 + ".getBBox().y");
assert_approx_equals(bbox1.width, bbox2.width, 0.0002, id1 + ".getBBox().width");
assert_approx_equals(bbox1.height, bbox2.height, 0.0001, id1 + ".getBBox().height");
}
function compare_bbox_without_x(id1, id2, opt) {
let bbox1 = document.getElementById(id1).getBBox(opt);
let bbox2 = document.getElementById(id2).getBBox(opt);
assert_equals(bbox1.y, bbox2.y, id1 + ".getBBox().y");
assert_approx_equals(bbox1.width, bbox2.width, 0.0002, id1 + ".getBBox().width");
assert_approx_equals(bbox1.height, bbox2.height, 0.0001, id1 + ".getBBox().height");
}
test(t => {
let opt = { fill: true, stroke: false, markers: false, clipped: false };
compare_bbox("text1", "text3", opt);
compare_bbox("text2", "text4", opt);
compare_bbox("text5", "text6", opt);
}, "text with fill");
test(t => {
let opt = { fill: true, stroke: true, markers: true, clipped: true };
compare_bbox_without_x("text1", "text3", opt);
compare_bbox_without_x("text2", "text4", opt);
compare_bbox_without_x("text5", "text6", opt);
}, "text with fill, stroke, markers and clipping");
test(t => {
let opt = { fill: false, stroke: false, markers: false, clipped: true };
compare_bbox_without_x("text1", "text3", opt);
compare_bbox_without_x("text2", "text4", opt);
compare_bbox_without_x("text5", "text6", opt);
}, "text with clipping");
test(t => {
let opt = { fill: true, stroke: true, markers: true, clipped: true };
assert_bbox("image1", opt, 160, 160, 80, 80);
assert_bbox("image2", opt, 53, 53, 149, 149);
assert_bbox("image3", opt, 205, 53, 148, 149);
assert_bbox("image4", opt, 53, 205, 149, 148);
assert_bbox("image5", opt, 205, 205, 148, 148);
assert_bbox("image6", opt, 52, 52, 100, 100);
assert_bbox("image7", opt, 255, 52, 100, 100);
assert_bbox("image8", opt, 52, 255, 100, 100);
assert_bbox("image9", opt, 255, 255, 100, 100);
assert_bbox("image10", opt, 200, 200, 200, 200);
assert_bbox("image11", opt, 0, 0, 0, 0);
assert_bbox("image12", opt, 43, 43, 714, 660);
assert_bbox("image13", opt, 50, 50, 300, 300);
assert_bbox("image14", opt, 0, 0, 0, 0);
}, "image with fill, stroke, markers and clipping");
test(t => {
let opt = { fill: true, stroke: false, markers: false, clipped: false };
assert_bbox("image1", opt, 150, 150, 200, 200);
assert_bbox("image2", opt, 2, 2, 200, 200);
assert_bbox("image3", opt, 205, 2, 200, 200);
assert_bbox("image4", opt, 2, 205, 200, 200);
assert_bbox("image5", opt, 205, 205, 200, 200);
assert_bbox("image6", opt, 2, 2, 200, 200);
assert_bbox("image7", opt, 205, 2, 200, 200);
assert_bbox("image8", opt, 2, 205, 200, 200);
assert_bbox("image9", opt, 205, 205, 200, 200);
assert_bbox("image10", opt, 0, 0, 400, 400);
assert_bbox("image11", opt, 0, 0, 400, 400);
assert_bbox("image12", opt, 25, 43, 768, 768);
assert_bbox("image13", opt, 0, 0, 400, 400);
}, "image with fill");
test(t => {
let opt = { fill: true, stroke: true, markers: true, clipped: true };
assert_bbox("path1", opt, 6.2, 20.8, 115.8, 91.2, 0.1);
assert_bbox("path2", opt, 156.2, 20.8, 115.8, 91.2, 0.1);
assert_bbox("path3", opt, 6.2, 120.7, 115.8, 91.2, 0.1);
assert_bbox("path4", opt, 6.2, 20.8, 93.8, 79.2, 0.1);
assert_bbox("path5", opt, 156.2, 20.8, 43.8, 79.2, 0.1);
assert_bbox("path6", opt, 6.2, 150, 93.8, 62, 0.1);
assert_bbox("path7", opt, 6.2, 20.8, 93.8, 79.2, 0.1);
assert_bbox("path8", opt, 156.2, 20.8, 93.8, 79.2, 0.1);
assert_bbox("path9", opt, 6.2, 120.8, 93.8, 79.2, 0.1);
assert_bbox("path10", opt, 10, 25, 100, 75);
assert_bbox("path11", opt, 160, 25, 100, 75);
assert_bbox("path12", opt, 10, 125, 100, 75);
}, "path with fill, stroke, markers and clipping");
test(t => {
let opt = { fill: true, stroke: false, markers: false, clipped: true };
assert_bbox("path1", opt, 10, 25, 100, 75);
assert_bbox("path2", opt, 160, 25, 100, 75);
assert_bbox("path3", opt, 10, 125, 100, 75);
assert_bbox("path4", opt, 10, 25, 90, 75);
assert_bbox("path5", opt, 160, 25, 40, 75);
assert_bbox("path6", opt, 10, 150, 90, 50);
assert_bbox("path7", opt, 10, 25, 90, 75);
assert_bbox("path8", opt, 160, 25, 90, 75);
assert_bbox("path9", opt, 10, 125, 90, 75);
assert_bbox("path10", opt, 10, 25, 100, 75);
assert_bbox("path11", opt, 160, 25, 100, 75);
assert_bbox("path12", opt, 10, 125, 100, 75);
}, "path with fill and clipping");
test(t => {
let opt = { fill: true, stroke: false, markers: false, clipped: false };
assert_bbox("path1", opt, 10, 25, 100, 75);
assert_bbox("path2", opt, 160, 25, 100, 75);
assert_bbox("path3", opt, 10, 125, 100, 75);
assert_bbox("path4", opt, 10, 25, 100, 75);
assert_bbox("path5", opt, 160, 25, 100, 75);
assert_bbox("path6", opt, 10, 125, 100, 75);
assert_bbox("path7", opt, 10, 25, 100, 75);
assert_bbox("path8", opt, 160, 25, 100, 75);
assert_bbox("path9", opt, 10, 125, 100, 75);
assert_bbox("path10", opt, 10, 25, 100, 75);
assert_bbox("path11", opt, 160, 25, 100, 75);
assert_bbox("path12", opt, 10, 125, 100, 75);
assert_bbox("path13", opt, 0, 0, 100, 100);
}, "path with fill");
test(t => {
let opt = { fill: false, stroke: true, markers: false, clipped: false };
assert_bbox("path1", opt, 6.2, 20.8, 107.8, 83.2, 0.1);
assert_bbox("path2", opt, 156.2, 20.8, 107.8, 83.2, 0.1);
assert_bbox("path3", opt, 6.2, 120.8, 107.8, 83.2, 0.1);
assert_bbox("path4", opt, 6.2, 20.8, 107.8, 83.2, 0.1);
assert_bbox("path5", opt, 156.2, 20.8, 107.8, 83.2, 0.1);
assert_bbox("path6", opt, 6.2, 120.8, 107.8, 83.2, 0.1);
assert_bbox("path7", opt, 6.2, 20.8, 107.8, 83.2, 0.1);
assert_bbox("path8", opt, 156.2, 20.8, 107.8, 83.2, 0.1);
assert_bbox("path9", opt, 6.2, 120.8, 107.8, 83.2, 0.1);
assert_bbox("path10", opt, 6.2, 20.8, 107.8, 83.2, 0.1);
assert_bbox("path11", opt, 156.2, 20.8, 107.8, 83.2, 0.1);
assert_bbox("path12", opt, 6.2, 120.8, 107.8, 83.2, 0.1);
}, "path with stroke");
test(t => {
let opt = { fill: false, stroke: false, markers: true, clipped: false };
assert_bbox("path1", opt, 10, 25, 112, 87);
assert_bbox("path2", opt, 160, 25, 112, 87);
assert_bbox("path3", opt, 10, 125, 112, 87);
assert_bbox("path4", opt, 10, 25, 112, 87);
assert_bbox("path5", opt, 160, 25, 112, 87);
assert_bbox("path6", opt, 10, 125, 112, 87);
assert_bbox("path7", opt, 10, 25, 112, 87);
assert_bbox("path8", opt, 160, 25, 112, 87);
assert_bbox("path9", opt, 10, 125, 112, 87);
assert_bbox("path10", opt, 10, 25, 112, 87);
assert_bbox("path11", opt, 160, 25, 112, 87);
assert_bbox("path12", opt, 10, 125, 112, 87);
}, "path with markers");
test(t => {
let opt = { fill: true, stroke: false, markers: false, clipped: false };
assert_bbox("use1", opt, 70, 70, 180, 180);
assert_bbox("use2", opt, 250, 70, 180, 180);
assert_bbox("use3", opt, 70, 250, 180, 180);
assert_bbox("use4", opt, 22, 22, 180, 180);
assert_bbox("use5", opt, 225, 22, 180, 180);
assert_bbox("use6", opt, 22, 225, 180, 180);
assert_bbox("use7", opt, 225, 225, 180, 180);
}, "use with fill");
test(t => {
let opt = { fill: true, stroke: true, markers: true, clipped: true };
assert_bbox("use1", opt, 70, 66, 180, 94);
assert_bbox("use2", opt, 250, 70, 180, 90);
assert_bbox("use3", opt, 70, 250, 180, 90);
assert_bbox("use4", opt, 18, 18, 134, 134);
assert_bbox("use5", opt, 221, 18, 134, 134);
assert_bbox("use6", opt, 18, 221, 134, 134);
assert_bbox("use7", opt, 221, 221, 134, 134);
assert_bbox("use8", opt, 0, 0, 0, 0);
}, "use with fill, stroke, markers and clipping");
test(t => {
let opt = { fill: true, stroke: false, markers: false, clipped: false };
assert_bbox("fo1", opt, 2, 2, 200, 200);
assert_bbox("fo2", opt, 205, 2, 200, 200);
assert_bbox("fo3", opt, 2, 205, 200, 200);
assert_bbox("fo4", opt, 205, 205, 200, 200);
assert_bbox("fo5", opt, 250, 250, 200, 200);
assert_bbox("fo6", opt, 0, 0, 200, 200);
assert_bbox("fo7", opt, 0, 0, 200, 200);
}, "foreignObject with fill");
test(t => {
let opt = { fill: true, stroke: true, markers: true, clipped: true };
assert_bbox("fo1", opt, 53, 53, 51, 51);
assert_bbox("fo2", opt, 205, 53, 148, 149);
assert_bbox("fo3", opt, 53, 205, 149, 148);
assert_bbox("fo4", opt, 207, 207, 100, 100);
assert_bbox("fo5", opt, 0, 0, 0, 0);
assert_bbox("fo6", opt, 100, 100, 100, 100);
assert_bbox("fo7", opt, 10, 10, 180, 180);
assert_bbox("fo8", opt, 0, 0, 0, 0);
}, "foreignObject with fill, stroke, markers and clipping");
// from http://www.w3.org/Graphics/SVG/Test/20110816/harness/htmlObjectApproved/masking-path-07-b.html
test(t => {
let opt = { fill: true, stroke: true, markers: true, clipped: true };
assert_bbox("rect-1", opt, 10, 10, 140, 140);
assert_bbox("rect-2", opt, 50, 30, 25, 100);
assert_bbox("rect-3", opt, 50, 50, 100, 100);
assert_bbox("g1", opt, 50, 50, 100, 100);
}, "masking-path-07-b.html with fill, stroke, markers and clipping");
</script>

До

Ширина:  |  Высота:  |  Размер: 20 KiB

После

Ширина:  |  Высота:  |  Размер: 30 KiB