зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1541021 - Should take CSS transform into account when calculating getBoundingClientRect() r=longsonr
We should use nsLayoutUtils::GetTransformToAncestor instead of nsSVGUtils::GetUserToCanvasTM to get the transform matrix. Because the former will also take CSS transform into account while the latter won't. Differential Revision: https://phabricator.services.mozilla.com/D26441 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
fcff024573
Коммит
c0ca7d5cac
|
@ -3,6 +3,7 @@
|
|||
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
|
||||
<style type="text/css">
|
||||
text { font: 20px monospace; }
|
||||
#css-trans-rect-2 { transform: scaleX(2) }
|
||||
</style>
|
||||
|
||||
<g id="g">
|
||||
|
@ -71,5 +72,7 @@ text { font: 20px monospace; }
|
|||
<line id="rotatedLine1" x1="160" y1="150" x2="180" y2="170"
|
||||
stroke="darkmagenta" stroke-width="10"
|
||||
transform="rotate(-45 160 150)" />
|
||||
|
||||
<rect id="css-trans-rect-2" x="5" y="5" width="6" height="6"></rect>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
До Ширина: | Высота: | Размер: 3.6 KiB После Ширина: | Высота: | Размер: 3.7 KiB |
|
@ -7,6 +7,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=463934
|
|||
<title>Test for Bug 463934</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<style>
|
||||
#css-trans-rect-1 {
|
||||
transform: scaleX(2)
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=463934">Mozilla Bug 463934</a>
|
||||
|
@ -22,6 +27,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=463934
|
|||
<svg id="outer-4" xmlns="http://www.w3.org/2000/svg" width="30" height="30"
|
||||
style="border: 10px solid black; padding: 10px">
|
||||
</svg>
|
||||
<svg id="outer-5" xmlns="http://www.w3.org/2000/svg" width="30" height="30">
|
||||
<rect id="css-trans-rect-1" width="6" height="6"></rect>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<iframe id="svg" src="bounds-helper.svg"></iframe>
|
||||
|
@ -67,6 +75,10 @@ function runTest() {
|
|||
is(bounds.width, 70, "outer-svg 4 getBoundingClientRect().width");
|
||||
is(bounds.height, 70, "outer-svg 4 getBoundingClientRect().height");
|
||||
|
||||
bounds = document.getElementById("css-trans-rect-1").getBoundingClientRect();
|
||||
is(bounds.width, 12, "css-trans-rect getBoundingClientRect().width");
|
||||
is(bounds.height, 6, "css-trans-rect getBoundingClientRect().height");
|
||||
|
||||
var doc = $("svg").contentWindow.document;
|
||||
|
||||
var svg1Bounds = doc.getElementById("svg1").getBoundingClientRect();
|
||||
|
@ -279,6 +291,13 @@ function runTest() {
|
|||
isWithAbsTolerance(rotatedLine1Bounds.height, 10, 0.1,
|
||||
"rotatedLine1Bounds.height");
|
||||
|
||||
var cssTransRect2Bounds =
|
||||
doc.getElementById("css-trans-rect-2").getBoundingClientRect();
|
||||
is(cssTransRect2Bounds.left, 10, "cssTransRect2Bounds.left");
|
||||
is(cssTransRect2Bounds.top, 5, "cssTransRect2Bounds.top");
|
||||
is(cssTransRect2Bounds.width, 12, "cssTransRect2Bounds.width");
|
||||
is(cssTransRect2Bounds.height, 6, "cssTransRect2Bounds.height");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
|
|
@ -321,12 +321,34 @@ nsIFrame* nsSVGUtils::GetOuterSVGFrameAndCoveredRegion(nsIFrame* aFrame,
|
|||
uint32_t flags =
|
||||
nsSVGUtils::eForGetClientRects | nsSVGUtils::eBBoxIncludeFill |
|
||||
nsSVGUtils::eBBoxIncludeStroke | nsSVGUtils::eBBoxIncludeMarkers;
|
||||
gfxMatrix m = nsSVGUtils::GetUserToCanvasTM(aFrame);
|
||||
|
||||
auto ctm = nsLayoutUtils::GetTransformToAncestor(aFrame, outer);
|
||||
|
||||
float initPositionX = NSAppUnitsToFloatPixels(aFrame->GetPosition().x,
|
||||
AppUnitsPerCSSPixel()),
|
||||
initPositionY = NSAppUnitsToFloatPixels(aFrame->GetPosition().y,
|
||||
AppUnitsPerCSSPixel());
|
||||
|
||||
Matrix mm;
|
||||
ctm.ProjectTo2D();
|
||||
ctm.CanDraw2D(&mm);
|
||||
gfxMatrix m = ThebesMatrix(mm);
|
||||
|
||||
float appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
float devPixelPerCSSPixel =
|
||||
1.0 * AppUnitsPerCSSPixel() / appUnitsPerDevPixel;
|
||||
|
||||
// The matrix that GetBBox accepts should operate on "user space",
|
||||
// i.e. with CSS pixel unit.
|
||||
m = m.PreScale(devPixelPerCSSPixel, devPixelPerCSSPixel);
|
||||
|
||||
// Both nsSVGUtils::GetBBox and nsLayoutUtils::GetTransformToAncestor
|
||||
// will count this displacement, we should remove it here to avoid
|
||||
// double-counting.
|
||||
m = m.PreTranslate(-initPositionX, -initPositionY);
|
||||
|
||||
SVGBBox bbox = nsSVGUtils::GetBBox(aFrame, flags, &m);
|
||||
nsRect bounds = nsLayoutUtils::RoundGfxRectToAppRect(
|
||||
bbox, aFrame->PresContext()->AppUnitsPerDevPixel());
|
||||
nsMargin bp = outer->GetUsedBorderAndPadding();
|
||||
*aRect = bounds + nsPoint(bp.left, bp.top);
|
||||
*aRect = nsLayoutUtils::RoundGfxRectToAppRect(bbox, appUnitsPerDevPixel);
|
||||
}
|
||||
|
||||
return outer;
|
||||
|
|
Загрузка…
Ссылка в новой задаче