Skip to content

Commit

Permalink
Fix SVGGraphicsElement.getBBox() when width or height is negative
Browse files Browse the repository at this point in the history
- For <rect>, if one of width and height is negative, clamp the value
  to 0, but keep the valid value of the other instead of 0 in getBBox().
  Also keep valid x and y instead of 0.

- Similarly for <ellipse> when rx or ry is negative, and <circle> when
  r is negative.

- Fix negative sized getBBox() for <image> and <foreignObject>.

- For <image>, treat negative width/height as auto instead of 0
  directly when intrinsic size is available. This applies to <image>
  only because for other elements, auto is the same as 0.

Also use gfx::RectF for the bounding boxes in the layout classes for
the above elements.

The underlying C++ functions ObjectBoundingBox() are changed to follow
the rule. StrokeBoundingBox() is also changed in the same way, but we
don't think that will have an effect anywhere (we don't propagate the
bounds if the shape is empty).

Bug: 738465, 1264473
Change-Id: Id6afda3c7981c6151e2b8f36a41c18aac6e06d9e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3248891
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/main@{#936491}
  • Loading branch information
wangxianzhu authored and chromium-wpt-export-bot committed Oct 29, 2021
1 parent 06e36d9 commit 7e53f8d
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions svg/types/scripted/SVGGraphicsElement.getBBox-03.html
@@ -0,0 +1,50 @@
<!DOCTYPE html>
<title>SVGGraphicsElement.prototype.getBBox for elements with negative sizes</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>
<rect id="rect1" x="1" y="2" width="-10" height="20"/>
<rect id="rect2" x="1" y="2" width="10" height="-20"/>
<circle id="circle" cx="1" cy="2" r="-10"/>
<ellipse id="ellipse1" cx="1" cy="12" rx="-5" ry="10"/>
<ellipse id="ellipse2" cx="6" cy="2" rx="5" ry="-10"/>
<image id="image1" x="1" y="2" width="-10" height="20" href="/images/green-100x50.png"/>
<image id="image2" x="1" y="2" width="10" height="-20" href="/images/green-100x50.png"/>
<image id="image3" x="1" y="2" width="-10" height="20"/>
<image id="image4" x="1" y="2" width="10" height="-20"/>
<foreignObject id="foreign1" x="1" y="2" width="-10" height="20"/>
<foreignObject id="foreign2" x="1" y="2" width="10" height="-20"/>
</svg>
<script>
function assertBBox(id, x, y, width, height) {
var bbox = document.getElementById(id).getBBox();
assert_equals(bbox.x, x, id + ': x');
assert_equals(bbox.y, y, id + ': y');
assert_equals(bbox.width, width, id + ': width');
assert_equals(bbox.height, height, id + ': height');
}

function testBBox(id, x, y, width, height) {
test(() => { assertBBox(id, x, y, width, height) }, id);
}

testBBox('rect1', 1, 2, 0, 20);
testBBox('rect2', 1, 2, 10, 0);
testBBox('circle', 1, 2, 0, 0);
testBBox('ellipse1', 1, 2, 0, 20);
testBBox('ellipse2', 1, 2, 10, 0);
testBBox('image3', 1, 2, 0, 20);
testBBox('image4', 1, 2, 10, 0);
testBBox('foreign1', 1, 2, 0, 20);
testBBox('foreign2', 1, 2, 10, 0);

async_test(t => {
onload = t.step_func_done(() => {
assertBBox('image1', 1, 2, 40, 20);
assertBBox('image2', 1, 2, 10, 5);
}, 'image1 and image2');
});
</script>

0 comments on commit 7e53f8d

Please sign in to comment.