зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1915971 - Simplify PrependLocalTransformsTo. r=longsonr
Now that there's only one transform kind seems worth doing this. Differential Revision: https://phabricator.services.mozilla.com/D220733
This commit is contained in:
Родитель
0d05060885
Коммит
8a62f66450
|
@ -496,15 +496,12 @@ static gfx::Matrix GetCTMInternal(SVGElement* aElement, CTMType aCTMType,
|
|||
auto getLocalTransformHelper =
|
||||
[](SVGElement const* e, bool shouldIncludeChildToUserSpace) -> gfxMatrix {
|
||||
gfxMatrix ret;
|
||||
|
||||
if (auto* f = e->GetPrimaryFrame()) {
|
||||
ret = SVGUtils::GetTransformMatrixInUserSpace(f);
|
||||
}
|
||||
|
||||
if (shouldIncludeChildToUserSpace) {
|
||||
ret = e->PrependLocalTransformsTo({}, eChildToUserSpace) * ret;
|
||||
ret = e->ChildToUserSpaceTransform() * ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
|
|
@ -41,26 +41,6 @@ class SVGViewportElement;
|
|||
|
||||
#define SVG_ZERO_LENGTH_PATH_FIX_FACTOR 512
|
||||
|
||||
/**
|
||||
* SVGTransformTypes controls the transforms that PrependLocalTransformsTo
|
||||
* applies.
|
||||
*
|
||||
* If aWhich is eAllTransforms, then all the transforms from the coordinate
|
||||
* space established by this element for its children to the coordinate
|
||||
* space established by this element's parent element for this element, are
|
||||
* included.
|
||||
*
|
||||
* If aWhich is eChildToUserSpace, then only the transforms from the
|
||||
* coordinate space established by this element for its childre to this
|
||||
* elements userspace are included. This includes any offsets due to e.g.
|
||||
* 'x'/'y' attributes, and any transform due to a 'viewBox' attribute, but
|
||||
* does not include any transforms due to the 'transform' attribute.
|
||||
*/
|
||||
enum SVGTransformTypes {
|
||||
eAllTransforms,
|
||||
eChildToUserSpace
|
||||
};
|
||||
|
||||
/**
|
||||
* Functions generally used by SVG Content classes. Functions here
|
||||
* should not generally depend on layout methods/classes e.g. SVGUtils
|
||||
|
|
|
@ -1564,10 +1564,7 @@ SVGViewportElement* SVGElement::GetCtx() const {
|
|||
}
|
||||
|
||||
/* virtual */
|
||||
gfxMatrix SVGElement::PrependLocalTransformsTo(const gfxMatrix& aMatrix,
|
||||
SVGTransformTypes aWhich) const {
|
||||
return aMatrix;
|
||||
}
|
||||
gfxMatrix SVGElement::ChildToUserSpaceTransform() const { return {}; }
|
||||
|
||||
SVGElement::LengthAttributesInfo SVGElement::GetLengthInfo() {
|
||||
return LengthAttributesInfo(nullptr, nullptr, 0);
|
||||
|
|
|
@ -135,23 +135,12 @@ class SVGElement : public SVGElementBase // nsIContent
|
|||
mozilla::dom::SVGViewportElement* GetCtx() const;
|
||||
|
||||
/**
|
||||
* Returns aMatrix pre-multiplied by (explicit or implicit) transforms that
|
||||
* are introduced by attributes on this element.
|
||||
*
|
||||
* If aWhich is eAllTransforms, then all the transforms from the coordinate
|
||||
* space established by this element for its children to the coordinate
|
||||
* space established by this element's parent element for this element, are
|
||||
* included.
|
||||
*
|
||||
* If aWhich is eChildToUserSpace, then only the transforms from the
|
||||
* coordinate space established by this element for its childre to this
|
||||
* elements userspace are included. This includes any offsets due to e.g.
|
||||
* 'x'/'y' attributes, and any transform due to a 'viewBox' attribute, but
|
||||
* does not include any transforms due to the 'transform' attribute.
|
||||
* Returns the transforms from the coordinate space established by this
|
||||
* element for its children to this element's userspace. This includes any
|
||||
* offsets due to e.g. 'x'/'y' attributes, and any transform due to a
|
||||
* 'viewBox' attribute.
|
||||
*/
|
||||
virtual gfxMatrix PrependLocalTransformsTo(
|
||||
const gfxMatrix& aMatrix,
|
||||
SVGTransformTypes aWhich = eAllTransforms) const;
|
||||
virtual gfxMatrix ChildToUserSpaceTransform() const;
|
||||
|
||||
// Setter for to set the current <animateMotion> transformation
|
||||
// Only visible for SVGGraphicElement, so it's a no-op here, and that
|
||||
|
|
|
@ -68,23 +68,16 @@ already_AddRefed<DOMSVGAnimatedLength> SVGForeignObjectElement::Height() {
|
|||
//----------------------------------------------------------------------
|
||||
// SVGElement methods
|
||||
|
||||
/* virtual */
|
||||
gfxMatrix SVGForeignObjectElement::PrependLocalTransformsTo(
|
||||
const gfxMatrix& aMatrix, SVGTransformTypes aWhich) const {
|
||||
gfxMatrix SVGForeignObjectElement::ChildToUserSpaceTransform() const {
|
||||
// our 'x' and 'y' attributes:
|
||||
float x, y;
|
||||
|
||||
if (!SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y>(this, &x, &y)) {
|
||||
// This function might be called for element in display:none subtree
|
||||
// (e.g. getScreenCTM), we fall back to use SVG attributes.
|
||||
const_cast<SVGForeignObjectElement*>(this)->GetAnimatedLengthValues(
|
||||
&x, &y, nullptr);
|
||||
}
|
||||
|
||||
gfxMatrix toUserSpace = gfxMatrix::Translation(x, y);
|
||||
MOZ_ASSERT(aWhich == eAllTransforms || aWhich == eChildToUserSpace,
|
||||
"Unknown TransformTypes");
|
||||
return toUserSpace * aMatrix;
|
||||
return gfxMatrix::Translation(x, y);
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
|
|
|
@ -32,9 +32,7 @@ class SVGForeignObjectElement final : public SVGGraphicsElement {
|
|||
|
||||
public:
|
||||
// SVGElement specializations:
|
||||
gfxMatrix PrependLocalTransformsTo(
|
||||
const gfxMatrix& aMatrix,
|
||||
SVGTransformTypes aWhich = eAllTransforms) const override;
|
||||
gfxMatrix ChildToUserSpaceTransform() const override;
|
||||
bool HasValidDimensions() const override;
|
||||
|
||||
// nsIContent interface
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "SVGAnimatedEnumeration.h"
|
||||
#include "SVGViewportElement.h"
|
||||
#include "mozilla/SVGImageContext.h"
|
||||
|
||||
nsresult NS_NewSVGSVGElement(
|
||||
nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
|
||||
|
|
|
@ -604,18 +604,12 @@ void SVGUseElement::UnlinkSource() {
|
|||
// SVGElement methods
|
||||
|
||||
/* virtual */
|
||||
gfxMatrix SVGUseElement::PrependLocalTransformsTo(
|
||||
const gfxMatrix& aMatrix, SVGTransformTypes aWhich) const {
|
||||
// our 'x' and 'y' attributes:
|
||||
gfxMatrix SVGUseElement::ChildToUserSpaceTransform() const {
|
||||
float x, y;
|
||||
if (!SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y>(this, &x, &y)) {
|
||||
const_cast<SVGUseElement*>(this)->GetAnimatedLengthValues(&x, &y, nullptr);
|
||||
}
|
||||
|
||||
gfxMatrix childToUser = gfxMatrix::Translation(x, y);
|
||||
MOZ_ASSERT(aWhich == eChildToUserSpace || aWhich == eAllTransforms,
|
||||
"Unknown TransformTypes");
|
||||
return childToUser * aMatrix;
|
||||
return gfxMatrix::Translation(x, y);
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
|
|
|
@ -64,9 +64,7 @@ class SVGUseElement final : public SVGUseElementBase,
|
|||
NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
|
||||
|
||||
// SVGElement specializations:
|
||||
gfxMatrix PrependLocalTransformsTo(
|
||||
const gfxMatrix& aMatrix,
|
||||
SVGTransformTypes aWhich = eAllTransforms) const override;
|
||||
gfxMatrix ChildToUserSpaceTransform() const override;
|
||||
bool HasValidDimensions() const override;
|
||||
|
||||
// nsIContent interface
|
||||
|
|
|
@ -237,31 +237,23 @@ float SVGViewportElement::GetLength(uint8_t aCtxType) const {
|
|||
// SVGElement methods
|
||||
|
||||
/* virtual */
|
||||
gfxMatrix SVGViewportElement::PrependLocalTransformsTo(
|
||||
const gfxMatrix& aMatrix, SVGTransformTypes aWhich) const {
|
||||
gfxMatrix childToUser;
|
||||
|
||||
gfxMatrix SVGViewportElement::ChildToUserSpaceTransform() const {
|
||||
auto viewBox = GetViewBoxTransform();
|
||||
if (IsInner()) {
|
||||
float x, y;
|
||||
const_cast<SVGViewportElement*>(this)->GetAnimatedLengthValues(&x, &y,
|
||||
nullptr);
|
||||
childToUser = ThebesMatrix(GetViewBoxTransform().PostTranslate(x, y));
|
||||
} else if (IsRootSVGSVGElement()) {
|
||||
return ThebesMatrix(viewBox.PostTranslate(x, y));
|
||||
}
|
||||
if (IsRootSVGSVGElement()) {
|
||||
const auto* svg = static_cast<const SVGSVGElement*>(this);
|
||||
const SVGPoint& translate = svg->GetCurrentTranslate();
|
||||
float scale = svg->CurrentScale();
|
||||
childToUser =
|
||||
ThebesMatrix(GetViewBoxTransform()
|
||||
.PostScale(scale, scale)
|
||||
.PostTranslate(translate.GetX(), translate.GetY()));
|
||||
} else {
|
||||
// outer-<svg>, but inline in some other content:
|
||||
childToUser = ThebesMatrix(GetViewBoxTransform());
|
||||
return ThebesMatrix(viewBox.PostScale(scale, scale)
|
||||
.PostTranslate(translate.GetX(), translate.GetY()));
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aWhich == eAllTransforms || aWhich == eChildToUserSpace,
|
||||
"Unknown TransformTypes");
|
||||
return childToUser * aMatrix;
|
||||
// outer-<svg>, but inline in some other content:
|
||||
return ThebesMatrix(viewBox);
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
|
|
|
@ -8,9 +8,6 @@
|
|||
#define DOM_SVG_SVGVIEWPORTELEMENT_H_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/SVGImageContext.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/dom/FromParser.h"
|
||||
#include "nsIContentInlines.h"
|
||||
#include "SVGAnimatedEnumeration.h"
|
||||
#include "SVGAnimatedLength.h"
|
||||
|
@ -45,9 +42,7 @@ class SVGViewportElement : public SVGGraphicsElement {
|
|||
NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
|
||||
|
||||
// SVGElement specializations:
|
||||
gfxMatrix PrependLocalTransformsTo(
|
||||
const gfxMatrix& aMatrix,
|
||||
SVGTransformTypes aWhich = eAllTransforms) const override;
|
||||
gfxMatrix ChildToUserSpaceTransform() const override;
|
||||
|
||||
bool HasValidDimensions() const override;
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ class ISVGDisplayableFrame : public nsQueryFrame {
|
|||
* SVG defines an element's bbox to be the element's fill bounds in the
|
||||
* userspace established by that element. By allowing callers to pass in the
|
||||
* transform from the userspace established by this element to the userspace
|
||||
* established by an an ancestor, this method allows callers to obtain this
|
||||
* established by an ancestor, this method allows callers to obtain this
|
||||
* element's fill bounds in the userspace established by that ancestor
|
||||
* instead. In that case, since we return the bounds in a different userspace
|
||||
* (the ancestor's), the bounds we return are not this element's bbox, but
|
||||
|
|
|
@ -217,7 +217,7 @@ void SVGDisplayContainerFrame::PaintSVG(gfxContext& aContext,
|
|||
|
||||
gfxMatrix matrix = aTransform;
|
||||
if (auto* svg = SVGElement::FromNode(GetContent())) {
|
||||
matrix = svg->PrependLocalTransformsTo(matrix, eChildToUserSpace);
|
||||
matrix = svg->ChildToUserSpaceTransform() * matrix;
|
||||
if (matrix.IsSingular()) {
|
||||
return;
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ nsIFrame* SVGDisplayContainerFrame::GetFrameForPoint(const gfxPoint& aPoint) {
|
|||
// for its children (e.g. take account of any 'viewBox' attribute):
|
||||
gfxPoint point = aPoint;
|
||||
if (const auto* svg = SVGElement::FromNode(GetContent())) {
|
||||
gfxMatrix m = svg->PrependLocalTransformsTo({}, eChildToUserSpace);
|
||||
gfxMatrix m = svg->ChildToUserSpaceTransform();
|
||||
if (!m.IsIdentity()) {
|
||||
if (!m.Invert()) {
|
||||
return nullptr;
|
||||
|
@ -399,7 +399,7 @@ SVGBBox SVGDisplayContainerFrame::GetBBoxContribution(
|
|||
}
|
||||
gfxMatrix transform = gfx::ThebesMatrix(aToBBoxUserspace);
|
||||
if (svg) {
|
||||
transform = svg->PrependLocalTransformsTo({}, eChildToUserSpace) *
|
||||
transform = svg->ChildToUserSpaceTransform() *
|
||||
SVGUtils::GetTransformMatrixInUserSpace(kid) * transform;
|
||||
}
|
||||
// We need to include zero width/height vertical/horizontal lines, so we
|
||||
|
@ -414,13 +414,10 @@ SVGBBox SVGDisplayContainerFrame::GetBBoxContribution(
|
|||
gfxMatrix SVGDisplayContainerFrame::GetCanvasTM() {
|
||||
if (!mCanvasTM) {
|
||||
NS_ASSERTION(GetParent(), "null parent");
|
||||
|
||||
auto* parent = static_cast<SVGContainerFrame*>(GetParent());
|
||||
auto* content = static_cast<SVGElement*>(GetContent());
|
||||
|
||||
gfxMatrix tm = content->PrependLocalTransformsTo(parent->GetCanvasTM());
|
||||
|
||||
mCanvasTM = MakeUnique<gfxMatrix>(tm);
|
||||
mCanvasTM = MakeUnique<gfxMatrix>(content->ChildToUserSpaceTransform() *
|
||||
parent->GetCanvasTM());
|
||||
}
|
||||
|
||||
return *mCanvasTM;
|
||||
|
|
|
@ -366,13 +366,10 @@ SVGBBox SVGForeignObjectFrame::GetBBoxContribution(
|
|||
gfxMatrix SVGForeignObjectFrame::GetCanvasTM() {
|
||||
if (!mCanvasTM) {
|
||||
NS_ASSERTION(GetParent(), "null parent");
|
||||
|
||||
auto* parent = static_cast<SVGContainerFrame*>(GetParent());
|
||||
auto* content = static_cast<SVGForeignObjectElement*>(GetContent());
|
||||
|
||||
gfxMatrix tm = content->PrependLocalTransformsTo(parent->GetCanvasTM());
|
||||
|
||||
mCanvasTM = MakeUnique<gfxMatrix>(tm);
|
||||
mCanvasTM = MakeUnique<gfxMatrix>(content->ChildToUserSpaceTransform() *
|
||||
parent->GetCanvasTM());
|
||||
}
|
||||
return *mCanvasTM;
|
||||
}
|
||||
|
|
|
@ -530,8 +530,7 @@ gfxMatrix SVGGeometryFrame::GetCanvasTM() {
|
|||
|
||||
auto* parent = static_cast<SVGContainerFrame*>(GetParent());
|
||||
auto* content = static_cast<SVGGraphicsElement*>(GetContent());
|
||||
|
||||
return content->PrependLocalTransformsTo(parent->GetCanvasTM());
|
||||
return content->ChildToUserSpaceTransform() * parent->GetCanvasTM();
|
||||
}
|
||||
|
||||
void SVGGeometryFrame::Render(gfxContext* aContext, uint32_t aRenderComponents,
|
||||
|
|
|
@ -634,7 +634,7 @@ SVGBBox SVGOuterSVGFrame::GetBBoxContribution(
|
|||
!PrincipalChildList().FirstChild()->GetNextSibling(),
|
||||
"We should have a single, anonymous, child");
|
||||
// We must defer to our child so that we don't include our
|
||||
// content->PrependLocalTransformsTo() transforms.
|
||||
// content->ChildToUserSpaceTransform() transform.
|
||||
auto* anonKid = static_cast<SVGOuterSVGAnonChildFrame*>(
|
||||
PrincipalChildList().FirstChild());
|
||||
return anonKid->GetBBoxContribution(aToBBoxUserspace, aFlags);
|
||||
|
@ -649,8 +649,8 @@ gfxMatrix SVGOuterSVGFrame::GetCanvasTM() {
|
|||
float devPxPerCSSPx = 1.0f / nsPresContext::AppUnitsToFloatCSSPixels(
|
||||
PresContext()->AppUnitsPerDevPixel());
|
||||
|
||||
gfxMatrix tm = content->PrependLocalTransformsTo(
|
||||
gfxMatrix::Scaling(devPxPerCSSPx, devPxPerCSSPx));
|
||||
gfxMatrix tm = content->ChildToUserSpaceTransform().PostScale(
|
||||
devPxPerCSSPx, devPxPerCSSPx);
|
||||
mCanvasTM = MakeUnique<gfxMatrix>(tm);
|
||||
}
|
||||
return *mCanvasTM;
|
||||
|
@ -797,9 +797,9 @@ bool SVGOuterSVGFrame::HasChildrenOnlyTransform(Matrix* aTransform) const {
|
|||
return false;
|
||||
}
|
||||
if (aTransform) {
|
||||
// Outer-<svg> doesn't use x/y, so we can pass eChildToUserSpace here.
|
||||
*aTransform = gfx::ToMatrix(
|
||||
content->PrependLocalTransformsTo(gfxMatrix(), eChildToUserSpace));
|
||||
// Outer-<svg> doesn't use x/y, so we can use the child-to-user-space
|
||||
// transform here.
|
||||
*aTransform = gfx::ToMatrix(content->ChildToUserSpaceTransform());
|
||||
if (aTransform->HasNonTranslation()) {
|
||||
// The nsDisplayTransform code will apply this transform to our inner kid,
|
||||
// including to its frame position. We don't want our frame position to
|
||||
|
|
|
@ -229,9 +229,9 @@ SVGBBox SVGSwitchFrame::GetBBoxContribution(const Matrix& aToBBoxUserspace,
|
|||
nsIContent* content = kid->GetContent();
|
||||
gfxMatrix transform = ThebesMatrix(aToBBoxUserspace);
|
||||
if (content->IsSVGElement()) {
|
||||
transform = static_cast<SVGElement*>(content)->PrependLocalTransformsTo(
|
||||
{}, eChildToUserSpace) *
|
||||
SVGUtils::GetTransformMatrixInUserSpace(kid) * transform;
|
||||
transform =
|
||||
static_cast<SVGElement*>(content)->ChildToUserSpaceTransform() *
|
||||
SVGUtils::GetTransformMatrixInUserSpace(kid) * transform;
|
||||
}
|
||||
return svgKid->GetBBoxContribution(ToMatrix(transform), aFlags);
|
||||
}
|
||||
|
@ -241,7 +241,6 @@ SVGBBox SVGSwitchFrame::GetBBoxContribution(const Matrix& aToBBoxUserspace,
|
|||
nsIFrame* SVGSwitchFrame::GetActiveChildFrame() {
|
||||
auto* activeChild =
|
||||
static_cast<dom::SVGSwitchElement*>(GetContent())->GetActiveChild();
|
||||
|
||||
return activeChild ? activeChild->GetPrimaryFrame() : nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -347,7 +347,7 @@ gfxMatrix SVGUtils::GetCanvasTM(nsIFrame* aFrame) {
|
|||
auto* parent = static_cast<SVGContainerFrame*>(aFrame->GetParent());
|
||||
auto* content = static_cast<SVGElement*>(aFrame->GetContent());
|
||||
|
||||
return content->PrependLocalTransformsTo(parent->GetCanvasTM());
|
||||
return content->ChildToUserSpaceTransform() * parent->GetCanvasTM();
|
||||
}
|
||||
|
||||
bool SVGUtils::GetParentSVGTransforms(const nsIFrame* aFrame,
|
||||
|
@ -888,8 +888,8 @@ gfxRect SVGUtils::GetBBox(nsIFrame* aFrame, uint32_t aFlags,
|
|||
// NOTE: When changing this to apply to other frame types, make sure to
|
||||
// also update SVGUtils::FrameSpaceInCSSPxToUserSpaceOffset.
|
||||
MOZ_ASSERT(aFrame->GetContent()->IsSVGElement(), "bad cast");
|
||||
SVGElement* element = static_cast<SVGElement*>(aFrame->GetContent());
|
||||
matrix = element->PrependLocalTransformsTo(matrix, eChildToUserSpace);
|
||||
auto* element = static_cast<SVGElement*>(aFrame->GetContent());
|
||||
matrix = element->ChildToUserSpaceTransform() * matrix;
|
||||
}
|
||||
gfxRect bbox =
|
||||
svg->GetBBoxContribution(ToMatrix(matrix), aFlags).ToThebesRect();
|
||||
|
@ -966,9 +966,8 @@ gfxPoint SVGUtils::FrameSpaceInCSSPxToUserSpaceOffset(const nsIFrame* aFrame) {
|
|||
// For foreignObject frames, SVGUtils::GetBBox applies their local
|
||||
// transform, so we need to do the same here.
|
||||
if (aFrame->IsSVGForeignObjectFrame()) {
|
||||
gfxMatrix transform =
|
||||
static_cast<SVGElement*>(aFrame->GetContent())
|
||||
->PrependLocalTransformsTo(gfxMatrix(), eChildToUserSpace);
|
||||
gfxMatrix transform = static_cast<SVGElement*>(aFrame->GetContent())
|
||||
->ChildToUserSpaceTransform();
|
||||
NS_ASSERTION(!transform.HasNonTranslation(),
|
||||
"we're relying on this being an offset-only transform");
|
||||
return transform.GetTranslation();
|
||||
|
@ -1462,9 +1461,9 @@ bool SVGUtils::GetSVGGlyphExtents(const Element* aElement,
|
|||
return false;
|
||||
}
|
||||
|
||||
gfxMatrix transform(aSVGToAppSpace);
|
||||
gfxMatrix transform = aSVGToAppSpace;
|
||||
if (auto* svg = SVGElement::FromNode(frame->GetContent())) {
|
||||
transform = svg->PrependLocalTransformsTo(aSVGToAppSpace);
|
||||
transform = svg->ChildToUserSpaceTransform() * transform;
|
||||
}
|
||||
|
||||
*aResult =
|
||||
|
|
Загрузка…
Ссылка в новой задаче