Bug 1316236 - Treat perspective(0) as perspective(infinity). r=dholbert

MozReview-Commit-ID: H9xlpjxrzht

--HG--
extra : rebase_source : 5060ae56163446a9dd6ae816c548ecd987a6e33e
This commit is contained in:
Xidorn Quan 2017-01-20 12:45:33 +11:00
parent c863cef487
commit c3e6a81bc4
6 changed files with 59 additions and 13 deletions

View File

@ -0,0 +1,7 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Reference: A green box</title>
<link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<p>Pass if there is NO red below:</p>
<div id="ref" style="width: 100px; height: 100px; background: green"></div>

View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Test: transform: perspective(0)</title>
<link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#funcdef-perspective">
<meta name="assert" content="perspective(0) should behave like identity transform function.">
<link rel="match" href="green.html">
<style>
#cover-me, #test {
width: 100px;
height: 100px;
}
#cover-me {
background: red;
position: relative;
margin-bottom: -100px;
}
#test {
background: green;
/* This should be an identity transform, since perspective(0) must be
* treated as perspective(infinity), and consequently translateZ()
* doesn't have any effect, so that it covers up #cover-me.
* If perspective(0) is invalid, #test would not create a stacking
* context, and #cover-me would be placed on top of #test showing red.
* If perspective(0) is handled as perspective(epsilon), #test would
* be invisible. */
transform: perspective(0) translateZ(50px);
}
</style>
<p>Pass if there is NO red below:</p>
<div id="cover-me"></div><div id="test"></div>

View File

@ -2,3 +2,4 @@
== 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 green.html

View File

@ -1375,14 +1375,11 @@ ComputeTransformDistance(nsCSSValue::Array* aArray1,
// Therefore, we use the same rule to get the distance as what we do for
// matrix3d.
auto clampPerspectiveDepth = [](float aDepth) {
// Perspective depth should be positive non-zero value.
return std::max(aDepth, std::numeric_limits<float>::epsilon());
};
using nsStyleTransformMatrix::ApplyPerspectiveToMatrix;
Matrix4x4 m1;
m1.Perspective(clampPerspectiveDepth(a1->Item(1).GetFloatValue()));
ApplyPerspectiveToMatrix(m1, a1->Item(1).GetFloatValue());
Matrix4x4 m2;
m2.Perspective(clampPerspectiveDepth(a2->Item(1).GetFloatValue()));
ApplyPerspectiveToMatrix(m2, a2->Item(1).GetFloatValue());
distance = ComputeTransform3DMatrixDistance(m1, m2);
break;

View File

@ -18,8 +18,6 @@
#include "gfxMatrix.h"
#include "gfxQuaternion.h"
#include <limits>
using namespace mozilla;
using namespace mozilla::gfx;
@ -751,11 +749,9 @@ ProcessPerspective(Matrix4x4& aMatrix,
{
NS_PRECONDITION(aData->Count() == 2, "Invalid array!");
float depth = std::max(ProcessTranslatePart(aData->Item(1), aContext,
aPresContext, aConditions,
nullptr),
std::numeric_limits<float>::epsilon());
aMatrix.Perspective(depth);
float depth = ProcessTranslatePart(aData->Item(1), aContext,
aPresContext, aConditions, nullptr);
ApplyPerspectiveToMatrix(aMatrix, depth);
}

View File

@ -13,6 +13,8 @@
#include "mozilla/EnumeratedArray.h"
#include "nsCSSValue.h"
#include <limits>
class nsIFrame;
class nsStyleContext;
class nsPresContext;
@ -27,6 +29,17 @@ class RuleNodeCacheConditions;
*/
namespace nsStyleTransformMatrix {
// Function for applying perspective() transform function. We treat
// any value smaller than epsilon as perspective(infinity), which
// follows CSSWG's resolution on perspective(0). See bug 1316236.
inline void ApplyPerspectiveToMatrix(mozilla::gfx::Matrix4x4& aMatrix,
float aDepth)
{
if (aDepth >= std::numeric_limits<float>::epsilon()) {
aMatrix.Perspective(aDepth);
}
}
/**
* This class provides on-demand access to the 'reference box' for CSS
* transforms (needed to resolve percentage values in 'transform',