From d8f2add1c49b6e60195ce040f1ac87ab5016691b Mon Sep 17 00:00:00 2001 From: Tom Klein Date: Tue, 22 Sep 2015 10:31:00 +0200 Subject: [PATCH] Bug 958160 - Compute bounds in transformed space instead of user space in GetCoveredRegion. r=longsonr --HG-- extra : rebase_source : 021b5fe58b234b83eb792d832296c79fe0160c48 --- dom/svg/test/bounds-helper.svg | 12 ++++++++++++ dom/svg/test/test_bounds.html | 22 ++++++++++++++++++++++ layout/svg/nsSVGPathGeometryFrame.cpp | 17 ++++++++++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/dom/svg/test/bounds-helper.svg b/dom/svg/test/bounds-helper.svg index 6fc33b1ecb3e..aaa87ee6862e 100644 --- a/dom/svg/test/bounds-helper.svg +++ b/dom/svg/test/bounds-helper.svg @@ -59,5 +59,17 @@ text { font: 20px monospace; } transform="rotate(45 280 15) scale(2 3)" stroke-width="10" stroke-linecap="butt" stroke="indigo" vector-effect="non-scaling-stroke" /> + + + + + + + diff --git a/dom/svg/test/test_bounds.html b/dom/svg/test/test_bounds.html index 30f5dc371dc2..4b7046bc7eba 100644 --- a/dom/svg/test/test_bounds.html +++ b/dom/svg/test/test_bounds.html @@ -261,6 +261,28 @@ function runTest() isWithAbsTolerance(nonScalingStrokedLine3Bounds.height, rect.height, 0.1, "nonScalingStrokedLine3.getBoundingClientRect().height"); + var shapeWithMarker1Bounds = + doc.getElementById("shapeWithMarker1").getBoundingClientRect(); + isWithAbsTolerance(shapeWithMarker1Bounds.left, 160, 0.1, + "shapeWithMarker1Bounds.left"); + isWithAbsTolerance(shapeWithMarker1Bounds.top, 120, 0.1, + "shapeWithMarker1Bounds.top"); + isWithAbsTolerance(shapeWithMarker1Bounds.width, 10 + Math.SQRT2 * 50, 0.1, + "shapeWithMarker1Bounds.width"); + isWithAbsTolerance(shapeWithMarker1Bounds.height, 20, 0.1, + "shapeWithMarker1Bounds.height"); + + var rotatedLine1Bounds = + doc.getElementById("rotatedLine1").getBoundingClientRect(); + isWithAbsTolerance(rotatedLine1Bounds.left, 160, 0.1, + "rotatedLine1Bounds.left"); + isWithAbsTolerance(rotatedLine1Bounds.top, 145, 0.1, + "rotatedLine1Bounds.top"); + isWithAbsTolerance(rotatedLine1Bounds.width, Math.SQRT2 * 20, 0.1, + "rotatedLine1Bounds.width"); + isWithAbsTolerance(rotatedLine1Bounds.height, 10, 0.1, + "rotatedLine1Bounds.height"); + SimpleTest.finish(); } diff --git a/layout/svg/nsSVGPathGeometryFrame.cpp b/layout/svg/nsSVGPathGeometryFrame.cpp index 1448ed236001..ab29d63be372 100644 --- a/layout/svg/nsSVGPathGeometryFrame.cpp +++ b/layout/svg/nsSVGPathGeometryFrame.cpp @@ -351,8 +351,23 @@ nsSVGPathGeometryFrame::GetFrameForPoint(const gfxPoint& aPoint) nsRect nsSVGPathGeometryFrame::GetCoveredRegion() { + gfxMatrix canvasTM = GetCanvasTM(); + if (canvasTM.PreservesAxisAlignedRectangles()) { + return nsSVGUtils::TransformFrameRectToOuterSVG( + mRect, canvasTM, PresContext()); + } + + // To get tight bounds we need to compute directly in outer SVG coordinates + uint32_t flags = nsSVGUtils::eBBoxIncludeFill | + nsSVGUtils::eBBoxIncludeStroke | + nsSVGUtils::eBBoxIncludeMarkers; + gfxRect extent = + GetBBoxContribution(ToMatrix(canvasTM), flags).ToThebesRect(); + nsRect region = nsLayoutUtils::RoundGfxRectToAppRect( + extent, PresContext()->AppUnitsPerCSSPixel()); + return nsSVGUtils::TransformFrameRectToOuterSVG( - mRect, GetCanvasTM(), PresContext()); + region, gfxMatrix(), PresContext()); } void