summaryrefslogtreecommitdiffstats
path: root/layout/svg
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@gmail.com>2017-06-28 21:47:18 +0200
committerwolfbeast <mcwerewolf@gmail.com>2018-02-03 23:56:01 +0100
commitde11930c3fecac13bc06da4f8b7818178c63f20e (patch)
treeca400d834e923d8ddb49097acde48868cf22d7a6 /layout/svg
parent10494e1b7d0b3cd945bb76dca10f5637cf786f27 (diff)
downloadUXP-de11930c3fecac13bc06da4f8b7818178c63f20e.tar
UXP-de11930c3fecac13bc06da4f8b7818178c63f20e.tar.gz
UXP-de11930c3fecac13bc06da4f8b7818178c63f20e.tar.lz
UXP-de11930c3fecac13bc06da4f8b7818178c63f20e.tar.xz
UXP-de11930c3fecac13bc06da4f8b7818178c63f20e.zip
Only create a single display transform for SVG frames with single child transforms.
This improves performance on repeated scaling of vectors.
Diffstat (limited to 'layout/svg')
-rw-r--r--layout/svg/nsSVGOuterSVGFrame.cpp44
-rw-r--r--layout/svg/nsSVGOuterSVGFrame.h5
2 files changed, 36 insertions, 13 deletions
diff --git a/layout/svg/nsSVGOuterSVGFrame.cpp b/layout/svg/nsSVGOuterSVGFrame.cpp
index 683f10bc7..aeadccbc5 100644
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -979,21 +979,43 @@ nsSVGOuterSVGAnonChildFrame::GetType() const
}
bool
-nsSVGOuterSVGAnonChildFrame::HasChildrenOnlyTransform(gfx::Matrix *aTransform) const
+nsSVGOuterSVGAnonChildFrame::IsSVGTransformed(Matrix* aOwnTransform,
+ Matrix* aFromParentTransform) const
{
- // We must claim our nsSVGOuterSVGFrame's children-only transforms as our own
- // so that the children we are used to wrap are transformed properly.
+ // Our elements 'transform' attribute is applied to our nsSVGOuterSVGFrame
+ // parent, and the element's children-only transforms are applied to us, the
+ // anonymous child frame. Since we are the child frame, we apply the
+ // children-only transforms as if they are our own transform.
- SVGSVGElement *content = static_cast<SVGSVGElement*>(mContent);
+ SVGSVGElement* content = static_cast<SVGSVGElement*>(mContent);
+
+ if (!content->HasChildrenOnlyTransform()) {
+ return false;
+ }
+
+ // Outer-<svg> doesn't use x/y, so we can pass eChildToUserSpace here.
+ gfxMatrix ownMatrix =
+ content->PrependLocalTransformsTo(gfxMatrix(), eChildToUserSpace);
- bool hasTransform = content->HasChildrenOnlyTransform();
+ if (ownMatrix.IsIdentity()) {
+ return false;
+ }
+
+ if (aOwnTransform) {
+ if (ownMatrix.HasNonTranslation()) {
+ // Note: viewBox, currentScale and currentTranslate should only
+ // produce a rectilinear transform.
+ // The nsDisplayTransform code will apply this transform to our frame,
+ // including to our frame position. We don't want our frame position to
+ // be scaled though, so we need to correct for that in the transform.
+ CSSPoint pos = CSSPixel::FromAppUnits(GetPosition());
+ CSSPoint scaledPos = CSSPoint(ownMatrix._11 * pos.x, ownMatrix._22 * pos.y);
+ CSSPoint deltaPos = scaledPos - pos;
+ ownMatrix *= gfxMatrix::Translation(-deltaPos.x, -deltaPos.y);
+ }
- if (hasTransform && aTransform) {
- // Outer-<svg> doesn't use x/y, so we can pass eChildToUserSpace here.
- gfxMatrix identity;
- *aTransform = gfx::ToMatrix(
- content->PrependLocalTransformsTo(identity, eChildToUserSpace));
+ *aOwnTransform = gfx::ToMatrix(ownMatrix);
}
- return hasTransform;
+ return true;
}
diff --git a/layout/svg/nsSVGOuterSVGFrame.h b/layout/svg/nsSVGOuterSVGFrame.h
index a08593678..6d29234ac 100644
--- a/layout/svg/nsSVGOuterSVGFrame.h
+++ b/layout/svg/nsSVGOuterSVGFrame.h
@@ -263,6 +263,9 @@ public:
*/
virtual nsIAtom* GetType() const override;
+ bool IsSVGTransformed(Matrix *aOwnTransform,
+ Matrix *aFromParentTransform) const override;
+
// nsSVGContainerFrame methods:
virtual gfxMatrix GetCanvasTM() override {
// GetCanvasTM returns the transform from an SVG frame to the frame's
@@ -270,8 +273,6 @@ public:
// set on us for any CSS border or padding on our nsSVGOuterSVGFrame.
return static_cast<nsSVGOuterSVGFrame*>(GetParent())->GetCanvasTM();
}
-
- virtual bool HasChildrenOnlyTransform(Matrix *aTransform) const override;
};
#endif