зеркало из https://github.com/mozilla/gecko-dev.git
Bug 972041 - getCTM should account for CSS transform r=longsonr
We use nsSVGUtils::GetTransformMatrixInUserSpace to support CSS transform in getCTM. Differential Revision: https://phabricator.services.mozilla.com/D28969 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
6cfa928fe9
Коммит
92d63fc969
|
@ -19,11 +19,13 @@
|
|||
#include "mozilla/SVGContextPaint.h"
|
||||
#include "mozilla/TextUtils.h"
|
||||
#include "nsComputedDOMStyle.h"
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsFontMetrics.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsMathUtils.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsWhitespaceTokenizer.h"
|
||||
#include "SVGAnimationElement.h"
|
||||
#include "SVGAnimatedPreserveAspectRatio.h"
|
||||
|
@ -466,15 +468,37 @@ SVGViewportElement* SVGContentUtils::GetNearestViewportElement(
|
|||
|
||||
static gfx::Matrix GetCTMInternal(SVGElement* aElement, bool aScreenCTM,
|
||||
bool aHaveRecursed) {
|
||||
gfxMatrix matrix = aElement->PrependLocalTransformsTo(
|
||||
gfxMatrix(), aHaveRecursed ? eAllTransforms : eUserSpaceToParent);
|
||||
auto getLocalTransformHelper =
|
||||
[](SVGElement const* e, bool shouldIncludeChildToUserSpace) -> gfxMatrix {
|
||||
gfxMatrix ret;
|
||||
|
||||
if (auto* f = e->GetPrimaryFrame()) {
|
||||
ret = nsSVGUtils::GetTransformMatrixInUserSpace(f, f->GetParent());
|
||||
} else {
|
||||
// FIXME: Ideally we should also return the correct matrix
|
||||
// for display:none, but currently transform related code relies
|
||||
// heavily on the present of a frame.
|
||||
// For now we just fall back to |PrependLocalTransformsTo| which
|
||||
// doesn't account for CSS transform.
|
||||
ret = e->PrependLocalTransformsTo({}, eUserSpaceToParent);
|
||||
}
|
||||
|
||||
if (shouldIncludeChildToUserSpace) {
|
||||
ret = e->PrependLocalTransformsTo({}, eChildToUserSpace) * ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
gfxMatrix matrix = getLocalTransformHelper(aElement, aHaveRecursed);
|
||||
|
||||
SVGElement* element = aElement;
|
||||
nsIContent* ancestor = aElement->GetFlattenedTreeParent();
|
||||
|
||||
while (ancestor && ancestor->IsSVGElement() &&
|
||||
!ancestor->IsSVGElement(nsGkAtoms::foreignObject)) {
|
||||
element = static_cast<SVGElement*>(ancestor);
|
||||
matrix *= element->PrependLocalTransformsTo(gfxMatrix()); // i.e. *A*ppend
|
||||
matrix *= getLocalTransformHelper(element, true);
|
||||
if (!aScreenCTM && SVGContentUtils::EstablishesViewport(element)) {
|
||||
if (!element->NodeInfo()->Equals(nsGkAtoms::svg, kNameSpaceID_SVG) &&
|
||||
!element->NodeInfo()->Equals(nsGkAtoms::symbol, kNameSpaceID_SVG)) {
|
||||
|
@ -501,7 +525,7 @@ static gfx::Matrix GetCTMInternal(SVGElement* aElement, bool aScreenCTM,
|
|||
// transforms in this case since that's what we've been doing for
|
||||
// a while, and it keeps us consistent with WebKit and Opera (if not
|
||||
// really with the ambiguous spec).
|
||||
matrix = aElement->PrependLocalTransformsTo(gfxMatrix());
|
||||
matrix = getLocalTransformHelper(aElement, true);
|
||||
}
|
||||
|
||||
if (auto* f = element->GetPrimaryFrame()) {
|
||||
|
|
|
@ -9,6 +9,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=366697
|
|||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<style>
|
||||
#padsvg1 { padding-left: 27px; padding-top: 43px; }
|
||||
#transrect1 { transform: scale(2,3); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -19,7 +20,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=366697
|
|||
<iframe id="svg" src="getCTM-helper.svg"></iframe>
|
||||
|
||||
<svg id="padsvg1" width="100" height="100">
|
||||
<rect width="10" height="10" />
|
||||
<rect id="transrect1" width="10" height="10" />
|
||||
</svg>
|
||||
|
||||
<pre id="test">
|
||||
|
@ -34,6 +35,10 @@ function runTest() {
|
|||
is(buggy.getCTM().e, 30, "buggy.getCTM().e");
|
||||
is(buggy.getCTM().f, 40, "buggy.getCTM().f");
|
||||
|
||||
var transrect1 = document.getElementById("transrect1");
|
||||
is(transrect1.getCTM().a, 2, "transrect1.getCTM().a");
|
||||
is(transrect1.getCTM().d, 3, "transrect1.getCTM().d");
|
||||
|
||||
var padsvg1 = document.getElementById("padsvg1");
|
||||
is(padsvg1.getScreenCTM().e - padsvg1.getBoundingClientRect().x, 27, "padsvg1.getScreenCTM().e");
|
||||
is(padsvg1.getScreenCTM().f - padsvg1.getBoundingClientRect().y, 43, "padsvg1.getScreenCTM().f");
|
||||
|
|
Загрузка…
Ссылка в новой задаче