Bug 1335876 - Part 3. (Main) Setup basis of the matrix according to transform-box.
MozReview-Commit-ID: GDVraFTlPbQ
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -6387,36 +6387,61 @@ nsDisplayTransform::GetResultingTransfor
// This is a simplification of the following |else| block, the
// simplification being possible because we don't need to apply
// mToTransformOrigin between two transforms.
result.ChangeBasis(aProperties.mToTransformOrigin);
} else {
Point3D refBoxOffset(NSAppUnitsToFloatPixels(refBox.X(), aAppUnitsPerPixel),
NSAppUnitsToFloatPixels(refBox.Y(), aAppUnitsPerPixel),
0);
+
// We have both a transform and children-only transform. The
// 'transform-origin' must apply between the two, so we need to apply it
// now before we apply transformFromSVGParent. Since mToTransformOrigin is
// relative to the frame's TopLeft(), we need to convert it to SVG user
// space by subtracting refBoxOffset. (Then after applying
// transformFromSVGParent we have to reapply refBoxOffset below.)
result.ChangeBasis(aProperties.mToTransformOrigin - refBoxOffset);
// Now apply the children-only transforms, converting the translation
// components to device pixels:
float pixelsPerCSSPx =
frame->PresContext()->AppUnitsPerCSSPixel() / aAppUnitsPerPixel;
transformFromSVGParent._31 *= pixelsPerCSSPx;
transformFromSVGParent._32 *= pixelsPerCSSPx;
- result = result * Matrix4x4::From2D(transformFromSVGParent);
-
- // Similar to the code in the |if| block above, but since we've accounted
- // for mToTransformOrigin so we don't include that. We also need to reapply
- // refBoxOffset.
+
+ // There are two kinds of transforms that we will apply to 'frame':
+ // frame's owned transform(stores in result, denotes as TO) and a
+ // transform from 'frame''s parent(stores in transformFromSVGParent,
+ // denotes as TP).
+ //
+ // The origin of TP has nothing to do with transform-box, and should
+ // always be at the origin of user space.
+ // Depends on the value of transform-box, the origin of TO can be either
+ // located at the top-left corner of 'frame''s fill-box if transform-box is
+ // fill-box, or at the origin of user space if transform-box is
+ // view-box(or border-box, which will be fallback to view-box in SVG
+ // layout).
+ // So the final transform will look like
+ // 1. For fill-box:
+ // TO.ChangeBasis(toFillBoxOffset) * TP.ChangeBasis(toUserSpaceOffset)
+ // 2. For view-box(or border-box):
+ // TO.ChangeBasis(toUserSpaceOffset) * TP.ChangeBasis(toUserSpaceOffset)
result.ChangeBasis(refBoxOffset);
+
+ Point3D frameOffset(
+ NSAppUnitsToFloatPixels(-frame->GetPosition().x, aAppUnitsPerPixel),
+ NSAppUnitsToFloatPixels(-frame->GetPosition().y, aAppUnitsPerPixel),
+ 0);
+ Matrix4x4 transformFromParent =
+ Matrix4x4::From2D(transformFromSVGParent).ChangeBasis(frameOffset);
+
+ // Compose frame's owned transform with the transforom from parent
+ // (usually produced by viewbox scaling) as the resulting transform.
+ result *= transformFromParent;
}
if (hasPerspective) {
result = result * perspectiveMatrix;
}
if ((aFlags & INCLUDE_PRESERVE3D_ANCESTORS) &&
frame && frame->Combines3DTransformWithAncestors()) {