2011-01-24 Simon Fraser <simon.fraser@apple.com>

        Reviewed by Chris Marrin.

        perspective() transform function should take lengths
        https://bugs.webkit.org/show_bug.cgi?id=52683

        The argument to the perspective() transform function should
        be a Length, rather than a bare number. Bare numbers are still
        accepted (and treated as px), but this behavior is deprecated.

        Test: animations/3d/transform-perspective.html
              transforms/3d/general/3dtransform-values.html

        * css/CSSParser.cpp:
        (WebCore::CSSParser::parseTransform): Check the units for the perspective()
        function. Allow bare numbers for backwards compatibility.
        * css/CSSStyleSelector.cpp:
        (WebCore::CSSStyleSelector::createTransformOperations): Convert
        value to Length.
        * platform/graphics/transforms/PerspectiveTransformOperation.cpp:
        (WebCore::clampToPostiveInteger): Helper.
        (WebCore::PerspectiveTransformOperation::blend): Blend via Lengths.
        * platform/graphics/transforms/PerspectiveTransformOperation.h:
        (WebCore::PerspectiveTransformOperation::create): double -> Length.
        (WebCore::PerspectiveTransformOperation::perspective): Ditto.
        (WebCore::PerspectiveTransformOperation::isIdentity): Ditto.
        (WebCore::PerspectiveTransformOperation::apply): Ditto.
        (WebCore::PerspectiveTransformOperation::PerspectiveTransformOperation): Assert
        that the Length is a fixed type.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76568 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 2134a7cb
2011-01-24 Simon Fraser <simon.fraser@apple.com>
Reviewed by Chris Marrin.
perspective() transform function should take lengths
https://bugs.webkit.org/show_bug.cgi?id=52683
Add tests for perspective() handling, and interpolation for animation.
* animations/3d/transform-perspective-expected.txt: Added.
* animations/3d/transform-perspective.html: Added.
* transforms/3d/general/3dtransform-values-expected.txt:
* transforms/3d/general/3dtransform-values.html:
2011-01-24 Kent Tamura <tkent@chromium.org>
Reviewed by Dimitri Glazkov.
......
PASS - "webkitTransform" property for "box" element at 0.5s saw something close to: 1,0,0,0,0,1,0,0,0,0,1,-0.0075,0,0,0,1
PASS - "webkitTransform" property for "box2" element at 0.5s saw something close to: 1,0,0,0,0,1,0,0,0,0,1,-0.00199,0,0,0,1
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.box {
height: 100px;
width: 100px;
background-color: blue;
}
#box {
-webkit-animation: anim 2s linear;
}
#box2 {
-webkit-animation: anim2 2s linear;
}
@-webkit-keyframes anim {
from { -webkit-transform: perspective(100px); }
to { -webkit-transform: perspective(200px); }
}
@-webkit-keyframes anim2 {
from { -webkit-transform: perspective(1000px); }
to { -webkit-transform: none; }
}
</style>
<script src="../animation-test-helpers.js" type="text/javascript"></script>
<script type="text/javascript">
const expectedValues = [
// [time, element-id, property, expected-value, tolerance]
["anim", 0.5, "box", "webkitTransform", [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.0075, 0, 0, 0, 1], 0.002],
["anim2", 0.5, "box2", "webkitTransform", [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00199, 0, 0, 0, 1], 0.002],
];
function setupTest()
{
var box = document.getElementById('box');
box.style.webkitTransform = 'perspective(1000px) rotateX(90deg)';
}
runAnimationTest(expectedValues);
</script>
</head>
<body>
<div class="box" id="box"></div>
<div class="box" id="box2"></div>
<div id="result"></div>
</body>
</html>
......@@ -9,4 +9,12 @@ transform "translateZ(10)" expected "none" : PASS
transform "rotate3d(0, 1, 0, 180)" expected "none" : PASS
transform "rotate3d(0, 1, 0, 180px)" expected "none" : PASS
transform "rotate3d(0, 1, 0, 180px)" expected "none" : PASS
transform "perspective(400)" expected "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)" : PASS
transform "perspective(400px)" expected "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)" : PASS
transform "perspective(400em)" expected "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00015625, 0, 0, 0, 1)" : PASS
transform "perspective(50%)" expected "none" : PASS
transform "perspective(-400)" expected "none" : PASS
transform "perspective(0)" expected "matrix(1, 0, 0, 1, 0, 0)" : PASS
transform "perspective(400deg)" expected "none" : PASS
transform "perspective(banana)" expected "none" : PASS
......@@ -37,6 +37,14 @@
{ 'transform' : 'rotate3d(0, 1, 0, 180)', 'result' : 'none' }, // last value must be an angle
{ 'transform' : 'rotate3d(0, 1, 0, 180px)', 'result' : 'none' }, // last value must be an angle
{ 'transform' : 'rotate3d(0, 1, 0, 180px)', 'result' : 'none' }, // last value must be an angle
{ 'transform' : 'perspective(400)', 'result' : 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)' }, // legacy
{ 'transform' : 'perspective(400px)', 'result' : 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.0025, 0, 0, 0, 1)' },
{ 'transform' : 'perspective(400em)', 'result' : 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00015625, 0, 0, 0, 1)' },
{ 'transform' : 'perspective(50%)', 'result' : 'none' },
{ 'transform' : 'perspective(-400)', 'result' : 'none' },
{ 'transform' : 'perspective(0)', 'result' : 'matrix(1, 0, 0, 1, 0, 0)' },
{ 'transform' : 'perspective(400deg)', 'result' : 'none' }, // unit must be length
{ 'transform' : 'perspective(banana)', 'result' : 'none' }, // unit must be length
];
function runTests()
......
2011-01-24 Simon Fraser <simon.fraser@apple.com>
Reviewed by Chris Marrin.
perspective() transform function should take lengths
https://bugs.webkit.org/show_bug.cgi?id=52683
The argument to the perspective() transform function should
be a Length, rather than a bare number. Bare numbers are still
accepted (and treated as px), but this behavior is deprecated.
Test: animations/3d/transform-perspective.html
transforms/3d/general/3dtransform-values.html
* css/CSSParser.cpp:
(WebCore::CSSParser::parseTransform): Check the units for the perspective()
function. Allow bare numbers for backwards compatibility.
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::createTransformOperations): Convert
value to Length.
* platform/graphics/transforms/PerspectiveTransformOperation.cpp:
(WebCore::clampToPostiveInteger): Helper.
(WebCore::PerspectiveTransformOperation::blend): Blend via Lengths.
* platform/graphics/transforms/PerspectiveTransformOperation.h:
(WebCore::PerspectiveTransformOperation::create): double -> Length.
(WebCore::PerspectiveTransformOperation::perspective): Ditto.
(WebCore::PerspectiveTransformOperation::isIdentity): Ditto.
(WebCore::PerspectiveTransformOperation::apply): Ditto.
(WebCore::PerspectiveTransformOperation::PerspectiveTransformOperation): Assert
that the Length is a fixed type.
2011-01-24 Kent Tamura <tkent@chromium.org>
Reviewed by Dimitri Glazkov.
......@@ -5316,6 +5316,10 @@ PassRefPtr<CSSValueList> CSSParser::parseTransform()
// 1st param of translateZ() cannot be a percentage
if (!validUnit(a, FLength, true))
return 0;
} else if (info.type() == WebKitCSSTransformValue::PerspectiveTransformOperation && argNumber == 0) {
// 1st param of perspective() must be a non-negative number (deprecated) or length.
if (!validUnit(a, FNumber | FLength | FNonNeg, true))
return 0;
} else if (!validUnit(a, unit, true))
return 0;
......
......@@ -7052,9 +7052,21 @@ bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle*
break;
}
case WebKitCSSTransformValue::PerspectiveTransformOperation: {
double p = firstValue->getDoubleValue();
if (p < 0.0)
bool ok = true;
Length p = Length(0, Fixed);
if (CSSPrimitiveValue::isUnitTypeLength(firstValue->primitiveType()))
p = convertToLength(firstValue, style, rootStyle, zoomFactor, &ok);
else {
// This is a quirk that should go away when 3d transforms are finalized.
double val = firstValue->getDoubleValue();
ok = val >= 0;
val = min<double>(val, numeric_limits<int>::max());
p = Length(static_cast<int>(val), Fixed);
}
if (!ok)
return false;
operations.operations().append(PerspectiveTransformOperation::create(p));
break;
}
......
......@@ -27,32 +27,45 @@
#include "PerspectiveTransformOperation.h"
#include <algorithm>
#include <limits>
using namespace std;
namespace WebCore {
static int clampToPostiveInteger(double val)
{
return static_cast<int>(max<double>(min<double>(val, numeric_limits<int>::max()), 0));
}
PassRefPtr<TransformOperation> PerspectiveTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
{
if (from && !from->isSameType(*this))
return this;
if (blendToIdentity)
return PerspectiveTransformOperation::create(m_p + (1. - m_p) * progress);
if (blendToIdentity) {
double p = m_p.calcFloatValue(1);
p = p + (1. - p) * progress; // FIXME: this seems wrong. https://bugs.webkit.org/show_bug.cgi?id=52700
return PerspectiveTransformOperation::create(Length(clampToPostiveInteger(p), Fixed));
}
const PerspectiveTransformOperation* fromOp = static_cast<const PerspectiveTransformOperation*>(from);
double fromP = fromOp ? fromOp->m_p : 0;
double toP = m_p;
Length fromP = fromOp ? fromOp->m_p : Length(m_p.type());
Length toP = m_p;
TransformationMatrix fromT;
TransformationMatrix toT;
fromT.applyPerspective(fromP);
toT.applyPerspective(toP);
fromT.applyPerspective(fromP.calcFloatValue(1));
toT.applyPerspective(toP.calcFloatValue(1));
toT.blend(fromT, progress);
TransformationMatrix::DecomposedType decomp;
toT.decompose(decomp);
return PerspectiveTransformOperation::create(decomp.perspectiveZ ? -1.0 / decomp.perspectiveZ : 0.0);
if (decomp.perspectiveZ) {
double val = -1.0 / decomp.perspectiveZ;
return PerspectiveTransformOperation::create(Length(clampToPostiveInteger(val), Fixed));
}
return PerspectiveTransformOperation::create(Length(0, Fixed));
}
} // namespace WebCore
......@@ -26,21 +26,22 @@
#ifndef PerspectiveTransformOperation_h
#define PerspectiveTransformOperation_h
#include "Length.h"
#include "TransformOperation.h"
namespace WebCore {
class PerspectiveTransformOperation : public TransformOperation {
public:
static PassRefPtr<PerspectiveTransformOperation> create(double p)
static PassRefPtr<PerspectiveTransformOperation> create(const Length& p)
{
return adoptRef(new PerspectiveTransformOperation(p));
}
double perspective() const { return m_p; }
Length perspective() const { return m_p; }
private:
virtual bool isIdentity() const { return m_p == 0; }
virtual bool isIdentity() const { return m_p.calcFloatValue(1) == 0; }
virtual OperationType getOperationType() const { return PERSPECTIVE; }
virtual bool isSameType(const TransformOperation& o) const { return o.getOperationType() == PERSPECTIVE; }
......@@ -54,18 +55,19 @@ private:
virtual bool apply(TransformationMatrix& transform, const IntSize&) const
{
transform.applyPerspective(m_p);
transform.applyPerspective(m_p.calcFloatValue(1));
return false;
}
virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false);
PerspectiveTransformOperation(double p)
PerspectiveTransformOperation(const Length& p)
: m_p(p)
{
ASSERT(p.isFixed());
}
double m_p;
Length m_p;
};
} // namespace WebCore
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment