зеркало из 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/SVGContextPaint.h"
|
||||||
#include "mozilla/TextUtils.h"
|
#include "mozilla/TextUtils.h"
|
||||||
#include "nsComputedDOMStyle.h"
|
#include "nsComputedDOMStyle.h"
|
||||||
|
#include "nsContainerFrame.h"
|
||||||
#include "nsFontMetrics.h"
|
#include "nsFontMetrics.h"
|
||||||
#include "nsIFrame.h"
|
#include "nsIFrame.h"
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
#include "nsMathUtils.h"
|
#include "nsMathUtils.h"
|
||||||
|
#include "nsSVGUtils.h"
|
||||||
#include "nsWhitespaceTokenizer.h"
|
#include "nsWhitespaceTokenizer.h"
|
||||||
#include "SVGAnimationElement.h"
|
#include "SVGAnimationElement.h"
|
||||||
#include "SVGAnimatedPreserveAspectRatio.h"
|
#include "SVGAnimatedPreserveAspectRatio.h"
|
||||||
|
@ -466,15 +468,37 @@ SVGViewportElement* SVGContentUtils::GetNearestViewportElement(
|
||||||
|
|
||||||
static gfx::Matrix GetCTMInternal(SVGElement* aElement, bool aScreenCTM,
|
static gfx::Matrix GetCTMInternal(SVGElement* aElement, bool aScreenCTM,
|
||||||
bool aHaveRecursed) {
|
bool aHaveRecursed) {
|
||||||
gfxMatrix matrix = aElement->PrependLocalTransformsTo(
|
auto getLocalTransformHelper =
|
||||||
gfxMatrix(), aHaveRecursed ? eAllTransforms : eUserSpaceToParent);
|
[](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;
|
SVGElement* element = aElement;
|
||||||
nsIContent* ancestor = aElement->GetFlattenedTreeParent();
|
nsIContent* ancestor = aElement->GetFlattenedTreeParent();
|
||||||
|
|
||||||
while (ancestor && ancestor->IsSVGElement() &&
|
while (ancestor && ancestor->IsSVGElement() &&
|
||||||
!ancestor->IsSVGElement(nsGkAtoms::foreignObject)) {
|
!ancestor->IsSVGElement(nsGkAtoms::foreignObject)) {
|
||||||
element = static_cast<SVGElement*>(ancestor);
|
element = static_cast<SVGElement*>(ancestor);
|
||||||
matrix *= element->PrependLocalTransformsTo(gfxMatrix()); // i.e. *A*ppend
|
matrix *= getLocalTransformHelper(element, true);
|
||||||
if (!aScreenCTM && SVGContentUtils::EstablishesViewport(element)) {
|
if (!aScreenCTM && SVGContentUtils::EstablishesViewport(element)) {
|
||||||
if (!element->NodeInfo()->Equals(nsGkAtoms::svg, kNameSpaceID_SVG) &&
|
if (!element->NodeInfo()->Equals(nsGkAtoms::svg, kNameSpaceID_SVG) &&
|
||||||
!element->NodeInfo()->Equals(nsGkAtoms::symbol, 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
|
// 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
|
// a while, and it keeps us consistent with WebKit and Opera (if not
|
||||||
// really with the ambiguous spec).
|
// really with the ambiguous spec).
|
||||||
matrix = aElement->PrependLocalTransformsTo(gfxMatrix());
|
matrix = getLocalTransformHelper(aElement, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* f = element->GetPrimaryFrame()) {
|
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" />
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
<style>
|
<style>
|
||||||
#padsvg1 { padding-left: 27px; padding-top: 43px; }
|
#padsvg1 { padding-left: 27px; padding-top: 43px; }
|
||||||
|
#transrect1 { transform: scale(2,3); }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -19,7 +20,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=366697
|
||||||
<iframe id="svg" src="getCTM-helper.svg"></iframe>
|
<iframe id="svg" src="getCTM-helper.svg"></iframe>
|
||||||
|
|
||||||
<svg id="padsvg1" width="100" height="100">
|
<svg id="padsvg1" width="100" height="100">
|
||||||
<rect width="10" height="10" />
|
<rect id="transrect1" width="10" height="10" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<pre id="test">
|
<pre id="test">
|
||||||
|
@ -34,6 +35,10 @@ function runTest() {
|
||||||
is(buggy.getCTM().e, 30, "buggy.getCTM().e");
|
is(buggy.getCTM().e, 30, "buggy.getCTM().e");
|
||||||
is(buggy.getCTM().f, 40, "buggy.getCTM().f");
|
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");
|
var padsvg1 = document.getElementById("padsvg1");
|
||||||
is(padsvg1.getScreenCTM().e - padsvg1.getBoundingClientRect().x, 27, "padsvg1.getScreenCTM().e");
|
is(padsvg1.getScreenCTM().e - padsvg1.getBoundingClientRect().x, 27, "padsvg1.getScreenCTM().e");
|
||||||
is(padsvg1.getScreenCTM().f - padsvg1.getBoundingClientRect().y, 43, "padsvg1.getScreenCTM().f");
|
is(padsvg1.getScreenCTM().f - padsvg1.getBoundingClientRect().y, 43, "padsvg1.getScreenCTM().f");
|
||||||
|
|
Загрузка…
Ссылка в новой задаче