Bug 1342229 - Handle perspective: 0 and perspective(0) similarly
MozReview-Commit-ID: 5RHjdcGqg7t
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -3326,17 +3326,17 @@ nsDisplayBackgroundImage::GetLayerState(
MOZ_ASSERT(shouldLayerize == ONLY_FOR_SCALING, "unhandled ImageLayerization value?");
MOZ_ASSERT(mImage);
int32_t imageWidth;
int32_t imageHeight;
mImage->GetWidth(&imageWidth);
mImage->GetHeight(&imageHeight);
NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!");
-
+
int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(GetDestRect(), appUnitsPerDevPixel);
const LayerRect destLayerRect = destRect * aParameters.Scale();
// Calculate the scaling factor for the frame.
const gfxSize scale = gfxSize(destLayerRect.width / imageWidth,
destLayerRect.height / imageHeight);
@@ -3826,17 +3826,17 @@ nsDisplayImageContainer::ConfigureLayer(
// the ImageContainer's size rather than the image's intrinsic size.
// XXX(seth): In reality, since the size of the ImageContainer may change
// asynchronously, this is not enough. Bug 1183378 will provide a more
// complete fix, but this solution is safe in more cases than simply relying
// on the intrinsic size.
IntSize containerSize = aLayer->GetContainer()
? aLayer->GetContainer()->GetCurrentSize()
: IntSize(imageWidth, imageHeight);
-
+
const int32_t factor = mFrame->PresContext()->AppUnitsPerDevPixel();
const LayoutDeviceRect destRect =
LayoutDeviceRect::FromAppUnits(GetDestRect(), factor);
const LayoutDevicePoint p = destRect.TopLeft();
Matrix transform = Matrix::Translation(p.x, p.y);
transform.PreScale(destRect.width / containerSize.width,
destRect.height / containerSize.height);
@@ -6487,17 +6487,17 @@ nsDisplayTransform::ComputePerspectiveMa
/* Grab the values for perspective and perspective-origin (if present) */
const nsStyleDisplay* cbDisplay = cbFrame->StyleDisplay();
if (cbDisplay->mChildPerspective.GetUnit() != eStyleUnit_Coord) {
return false;
}
nscoord perspective = cbDisplay->mChildPerspective.GetCoordValue();
- if (perspective < 0) {
+ if (perspective < std::numeric_limits<Float>::epsilon()) {
return true;
}
TransformReferenceBox refBox(cbFrame);
/* Allows us to access named variables by index. */
Point3D perspectiveOrigin;
gfx::Float* coords[2] = {&perspectiveOrigin.x, &perspectiveOrigin.y};
@@ -6540,20 +6540,19 @@ nsDisplayTransform::ComputePerspectiveMa
NSAppUnitsToFloatPixels(frameToCbOffset.y, aAppUnitsPerPixel),
0.0f);
/* Move the perspective origin to be relative to aFrame, instead of relative
* to the containing block which is how it was specified in the style system.
*/
perspectiveOrigin += frameToCbGfxOffset;
- Float perspectivePx = std::max(NSAppUnitsToFloatPixels(perspective,
- aAppUnitsPerPixel),
- std::numeric_limits<Float>::epsilon());
- aOutMatrix._34 = -1.0 / perspectivePx;
+ aOutMatrix._34 =
+ -1.0 / NSAppUnitsToFloatPixels(perspective, aAppUnitsPerPixel);
+
aOutMatrix.ChangeBasis(perspectiveOrigin);
return true;
}
nsDisplayTransform::FrameTransformProperties::FrameTransformProperties(const nsIFrame* aFrame,
float aAppUnitsPerPixel,
const nsRect* aBoundsOverride)
: mFrame(aFrame)
@@ -6966,18 +6965,20 @@ nsDisplayTransform::MayBeAnimated(nsDisp
nsDisplayItem::LayerState
nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) {
// If the transform is 3d, the layer takes part in preserve-3d
// sorting, or the layer is a separator then we *always* want this
// to be an active layer.
+ // Checking HasPerspective() is needed to handle perspective value 0 when
+ // the transform is 2D.
if (!GetTransform().Is2D() || mFrame->Combines3DTransformWithAncestors() ||
- mIsTransformSeparator) {
+ mIsTransformSeparator || mFrame->HasPerspective()) {
return LAYER_ACTIVE_FORCE;
}
if (MayBeAnimated(aBuilder)) {
// Returns LAYER_ACTIVE_FORCE to avoid flatterning the layer for async
// animations.
return LAYER_ACTIVE_FORCE;
}
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/transforms/perspective-zero-2-ref.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>CSS transforms: perspective: 0px reference</title>
+<link rel="author" title="Miko Mynttinen" href="mailto:mmynttinen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<style type="text/css">
+.parent {
+ transform: perspective(0px);
+}
+.parent > div {
+ width: 200px;
+ height: 200px;
+ position: absolute;
+}
+.child-3d {
+ background: green;
+ transform: translateZ(1px);
+}
+</style>
+</head>
+<body>
+<p>Test passes if there is only green below.</p>
+<div class="parent">
+ <div class="child-3d"></div>
+</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/transforms/perspective-zero-2.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>CSS transforms: perspective: 0px</title>
+<link rel="author" title="Miko Mynttinen" href="mailto:mmynttinen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/413">
+<meta name="assert" content="Test checks that perspective: 0px behaves like transform: perspective(0) on parent container">
+<link rel="match" href="perspective-zero-2-ref.html">
+<style type="text/css">
+.parent {
+ perspective: 0px;
+}
+.parent > div {
+ width: 200px;
+ height: 200px;
+ position: absolute;
+}
+.child-2d {
+ background: red;
+}
+.child-3d {
+ background: green;
+ transform: translateZ(1px);
+}
+</style>
+</head>
+<body>
+<p>Test passes if there is only green below.</p>
+<div class="parent">
+ <div class="child-2d"></div>
+ <div class="child-3d"></div>
+</div>
+</body>
+</html>
--- a/layout/reftests/w3c-css/submitted/transforms/reftest.list
+++ b/layout/reftests/w3c-css/submitted/transforms/reftest.list
@@ -1,5 +1,6 @@
== transform-containing-block-dynamic-1a.html containing-block-dynamic-1-ref.html
== transform-containing-block-dynamic-1b.html containing-block-dynamic-1-ref.html
== perspective-containing-block-dynamic-1a.html containing-block-dynamic-1-ref.html
== perspective-containing-block-dynamic-1b.html containing-block-dynamic-1-ref.html
== perspective-zero.html reference/green.html
+== perspective-zero-2.html perspective-zero-2-ref.html