diff options
author | wolfbeast <mcwerewolf@gmail.com> | 2017-06-28 21:47:18 +0200 |
---|---|---|
committer | wolfbeast <mcwerewolf@gmail.com> | 2018-02-03 23:56:01 +0100 |
commit | de11930c3fecac13bc06da4f8b7818178c63f20e (patch) | |
tree | ca400d834e923d8ddb49097acde48868cf22d7a6 | |
parent | 10494e1b7d0b3cd945bb76dca10f5637cf786f27 (diff) | |
download | UXP-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.
-rw-r--r-- | layout/svg/nsSVGOuterSVGFrame.cpp | 44 | ||||
-rw-r--r-- | layout/svg/nsSVGOuterSVGFrame.h | 5 |
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 |