From 3b61eb914aef80dc27ea1eabce3c53918edbd0d0 Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Mon, 2 Nov 2009 21:00:46 -0800 Subject: [PATCH] Bug 526075: Clamp tiny sines to zero when computing transformation matrices. --- layout/base/tests/test_bug435293-skew.html | 14 ++------------ layout/reftests/transform/reftest.list | 6 +++--- layout/style/nsStyleTransformMatrix.cpp | 17 ++++++++++++++--- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/layout/base/tests/test_bug435293-skew.html b/layout/base/tests/test_bug435293-skew.html index 5ac7744c9aa4..b6e6e5066cb0 100644 --- a/layout/base/tests/test_bug435293-skew.html +++ b/layout/base/tests/test_bug435293-skew.html @@ -121,19 +121,9 @@ function runtests() { is(style.getPropertyValue("-moz-transform"), "matrix(1, 1, 1, 1, 0px, 0px)", "Test3: Skew proper matrix is applied"); - // Argument reduction here may give us a value that is close to but not - // exactly zero. style = window.getComputedStyle(document.getElementById("test4"), ""); - tformStyle = style.getPropertyValue("-moz-transform"); - tformValues = tformStyle.substring(tformStyle.indexOf('(') + 1, - tformStyle.indexOf(')')).split(','); - is((+tformValues[0]), 1, "Test4: skew angle wrap: param 0 is 1"); - is((+tformValues[1]), 1, "Test4: skew angle wrap: param 1 is 1"); - ok(verifyRounded(tformValues[2], 0), - "Test4: skew angle wrap: rounded param 2 is 0"); - is((+tformValues[3]), 1, "Test4: skew angle wrap: param 3 is 1"); - is(tformValues[4].trim(), "0px", "Test4: skew angle wrap: param 4 is 0px"); - is(tformValues[5].trim(), "0px", "Test4: skew angle wrap: param 5 is 0px"); + is(style.getPropertyValue("-moz-transform"), "matrix(1, 1, 0, 1, 0px, 0px)", + "Test4: Skew angle wrap: proper matrix is applied"); style = window.getComputedStyle(document.getElementById("test5"), ""); is(style.getPropertyValue("-moz-transform"), "matrix(1, -1, 1, 1, 0px, 0px)", diff --git a/layout/reftests/transform/reftest.list b/layout/reftests/transform/reftest.list index 923a8a8217b3..1995d16c06c4 100644 --- a/layout/reftests/transform/reftest.list +++ b/layout/reftests/transform/reftest.list @@ -7,14 +7,14 @@ != compound-1a.html compound-1-fail.html # translatex should act like position: relative == translatex-1a.html translatex-1-ref.html -random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == translatex-1b.html translatex-1-ref.html +== translatex-1b.html translatex-1-ref.html == translatex-1c.html translatex-1-ref.html == translatex-1d.html translatex-1-ref.html == translatex-1e.html translatex-1-ref.html == translatex-1a.html translatex-1-ref-2.html # translatey should act like position: relative == translatey-1a.html translatey-1-ref.html -random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == translatey-1b.html translatey-1-ref.html +== translatey-1b.html translatey-1-ref.html == translatey-1c.html translatey-1-ref.html == translatey-1d.html translatey-1-ref.html == translatey-1e.html translatey-1-ref.html @@ -23,7 +23,7 @@ random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == translatey-1b.html translatey-1-ref.ht == translatey-2.html translatey-1-ref.html # translate should act like position: relative != translate-1a.html translate-1-ref.html -random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == translate-1b.html translate-1-ref.html +== translate-1b.html translate-1-ref.html == translate-1c.html translate-1-ref.html == translate-1d.html translate-1-ref.html == translate-1e.html translate-1-ref.html diff --git a/layout/style/nsStyleTransformMatrix.cpp b/layout/style/nsStyleTransformMatrix.cpp index 13d0ecbf0ceb..fd3bd842a295 100644 --- a/layout/style/nsStyleTransformMatrix.cpp +++ b/layout/style/nsStyleTransformMatrix.cpp @@ -53,6 +53,17 @@ * involving angles need to be done in 'double'. */ +/* Force small values to zero. We do this to avoid having sin(360deg) + * evaluate to a tiny but nonzero value. + */ +static double FlushToZero(double aVal) +{ + if (-FLT_EPSILON < aVal && aVal < FLT_EPSILON) + return 0.0f; + else + return aVal; +} + /* Computes tan(aTheta). For values of aTheta such that tan(aTheta) is * undefined or very large, SafeTangent returns a manageably large value * of the correct sign. @@ -73,7 +84,7 @@ static double SafeTangent(double aTheta) else if (cosTheta < 0 && cosTheta >= -kEpsilon) cosTheta = -kEpsilon; - return sinTheta / cosTheta; + return FlushToZero(sinTheta / cosTheta); } /* Constructor sets the data to the identity matrix. */ @@ -425,8 +436,8 @@ static void ProcessRotate(float aMain[4], const nsCSSValue::Array* aData) * (see http://www.w3.org/TR/SVG/coords.html#RotationDefined) */ double theta = aData->Item(1).GetAngleValueInRadians(); - float cosTheta = cos(theta); - float sinTheta = sin(theta); + float cosTheta = FlushToZero(cos(theta)); + float sinTheta = FlushToZero(sin(theta)); aMain[0] = cosTheta; aMain[1] = sinTheta;