Bug 1498734 - Always compute angle values to degrees. r=xidorn

This matches the spec, https://drafts.csswg.org/css-values/#angles, which says:

> All <angle> units are compatible, and deg is their canonical unit.

And https://drafts.csswg.org/css-values/#compat, which says:

>When serializing computed values [...], compatible units [...] are converted into a single canonical unit.

And also other implementations (Blink always serializes angles as degrees in
computed style for example).

Also allows us to get rid of quite a bit of code, and makes computed angle value
representation just a number, which is nice.

Differential Revision: https://phabricator.services.mozilla.com/D8619

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2018-10-13 00:41:03 +00:00
Родитель d021231888
Коммит 40b1e83d81
26 изменённых файлов: 186 добавлений и 522 удалений

Просмотреть файл

@ -66,9 +66,6 @@ StyleInfo::TextIndent(nsAString& aValue)
case eStyleUnit_None:
case eStyleUnit_Factor:
case eStyleUnit_Degree:
case eStyleUnit_Grad:
case eStyleUnit_Radian:
case eStyleUnit_Turn:
case eStyleUnit_FlexFraction:
case eStyleUnit_Integer:
case eStyleUnit_Enumerated:

Просмотреть файл

@ -876,9 +876,6 @@ TextAttrsMgr::TextPosTextAttr::
case eStyleUnit_None:
case eStyleUnit_Factor:
case eStyleUnit_Degree:
case eStyleUnit_Grad:
case eStyleUnit_Radian:
case eStyleUnit_Turn:
case eStyleUnit_FlexFraction:
case eStyleUnit_Integer:
case eStyleUnit_Calc:

Просмотреть файл

@ -7,6 +7,8 @@
<script type='text/javascript'>
'use strict';
const EPSILON = 1e-6;
// We don't have an official spec to define the distance between two filter
// lists, but we still need this for DevTools, so Gecko and Servo backends use
// the similar rules to define the distance. If there is a spec for it, we have
@ -122,15 +124,15 @@ test(function(t) {
var target = addDiv(t);
var dist = getDistance(target, 'filter', 'hue-rotate(180deg)', 'none');
// The default value of hue-rotate is 0deg.
assert_equals(dist, Math.PI, 'hue-rotate(180deg) and none');
assert_approx_equals(dist, Math.PI, EPSILON, 'hue-rotate(180deg) and none');
}, 'hue-rotate and none');
test(function(t) {
var target = addDiv(t);
var dist = getDistance(target, 'filter',
'hue-rotate(720deg)', 'hue-rotate(-180deg)');
assert_equals(dist, 5 * Math.PI,
'hue-rotate(720deg) and hue-rotate(-180deg)');
assert_approx_equals(dist, 5 * Math.PI, EPSILON,
'hue-rotate(720deg) and hue-rotate(-180deg)');
}, 'hue-rotates');
test(function(t) {

Просмотреть файл

@ -12,7 +12,7 @@
// the similar rules to define the distance. If there is a spec for it, we have
// to update this test file.
const epsilon = 0.00001;
const EPSILON = 0.00001;
// |v| should be a unit vector (i.e. having length 1)
function getQuaternion(v, angle) {
@ -136,14 +136,14 @@ test(function(t) {
var target = addDiv(t);
var dist =
getDistance(target, 'transform', 'rotate(45deg)', 'rotate(90deg)');
assert_equals(dist, Math.PI/ 2.0 - Math.PI / 4.0, 'distance of rotate');
assert_approx_equals(dist, Math.PI / 2.0 - Math.PI / 4.0, EPSILON, 'distance of rotate');
}, 'Test distance of rotate functions');
test(function(t) {
var target = addDiv(t);
var dist =
getDistance(target, 'transform', 'rotate(45deg)', 'none');
assert_equals(dist, Math.PI / 4.0, 'distance of rotate');
assert_approx_equals(dist, Math.PI / 4.0, EPSILON, 'distance of rotate');
}, 'Test distance of rotate function and none');
test(function(t) {
@ -151,7 +151,7 @@ test(function(t) {
var dist = getDistance(target, 'transform',
'rotate3d(0, 1, 0, 90deg)',
'none');
assert_equals(dist, Math.PI / 2, 'distance of rotate3d');
assert_approx_equals(dist, Math.PI / 2, EPSILON, 'distance of rotate3d');
}, 'Test distance of rotate3d function and none');
test(function(t) {
@ -161,7 +161,7 @@ test(function(t) {
'rotate3d(1, 0, 0, 90deg)');
let q1 = getQuaternion([0, 0, 1], Math.PI / 2.0);
let q2 = getQuaternion([1, 0, 0], Math.PI / 2.0);
assert_equals(dist, computeRotateDistance(q1, q2), 'distance of rotate3d');
assert_approx_equals(dist, computeRotateDistance(q1, q2), EPSILON, 'distance of rotate3d');
}, 'Test distance of rotate3d functions');
test(function(t) {
@ -169,14 +169,14 @@ test(function(t) {
var dist = getDistance(target, 'transform',
'rotate3d(0, 0, 1, 90deg)',
'rotate3d(0, 0, 0, 90deg)');
assert_equals(dist, Math.PI / 2, 'distance of rotate3d');
assert_approx_equals(dist, Math.PI / 2, EPSILON, 'distance of rotate3d');
}, 'Test distance of rotate3d functions whose direction vector cannot be ' +
'normalized');
test(function(t) {
var target = addDiv(t);
var dist = getDistance(target, 'transform', 'skew(1rad, 0.5rad)', 'none');
assert_equals(dist, Math.sqrt(1 * 1 + 0.5 * 0.5), 'distance of skew');
assert_approx_equals(dist, Math.sqrt(1 * 1 + 0.5 * 0.5), EPSILON, 'distance of skew');
}, 'Test distance of skew function and none');
test(function(t) {
@ -184,7 +184,7 @@ test(function(t) {
var dist = getDistance(target, 'transform',
'skew(1rad, 0.5rad)',
'skew(-1rad, 0)');
assert_equals(dist, Math.sqrt(2 * 2 + 0.5 * 0.5), 'distance of skew');
assert_approx_equals(dist, Math.sqrt(2 * 2 + 0.5 * 0.5), EPSILON, 'distance of skew');
}, 'Test distance of skew functions');
test(function(t) {
@ -224,7 +224,7 @@ test(function(t) {
var dist = getDistance(target, 'transform', matrix, 'none');
assert_approx_equals(dist,
Math.sqrt(100 * 100 + (Math.PI / 6) * (Math.PI / 6)),
epsilon,
EPSILON,
'distance of matrix');
}, 'Test distance of matrix function and none');
@ -243,7 +243,7 @@ test(function(t) {
Math.sqrt(100 * 100 + 100 * 100 + // translate
(Math.PI / 6) * (Math.PI / 6) + // rotate
0.5 * 0.5 + 0.5 * 0.5), // scale
epsilon,
EPSILON,
'distance of matrix');
}, 'Test distance of matrix functions');
@ -251,7 +251,7 @@ test(function(t) {
var target = addDiv(t);
var matrix = createMatrixFromArray(rotate3dToMatrix(0, 1, 0, Math.PI / 6));
var dist = getDistance(target, 'transform', matrix, 'none');
assert_approx_equals(dist, Math.PI / 6, epsilon, 'distance of matrix3d');
assert_approx_equals(dist, Math.PI / 6, EPSILON, 'distance of matrix3d');
}, 'Test distance of matrix3d function and none');
test(function(t) {
@ -268,7 +268,7 @@ test(function(t) {
Math.sqrt(100 * 100 + // translate
0.5 * 0.5 * 3 + // scale
(Math.PI / 6) * (Math.PI / 6)), // rotate
epsilon,
EPSILON,
'distance of matrix');
}, 'Test distance of matrix3d functions');
@ -291,7 +291,7 @@ test(function(t) {
Math.sqrt(900 * 900 + 50 * 50 + 10 * 10 + // translate
Math.PI * Math.PI + // rotate
(Math.PI / 4) * (Math.PI / 4)), // skew angle
epsilon,
EPSILON,
'distance of matrix');
}, 'Test distance of matrix3d functions with skew factors');
@ -301,8 +301,8 @@ test(function(t) {
getDistance(target, 'transform',
'rotate(180deg) translate(1000px)',
'rotate(360deg) translate(0px)');
assert_equals(dist, Math.sqrt(1000 * 1000 + Math.PI * Math.PI),
'distance of transform lists');
assert_approx_equals(dist, Math.sqrt(1000 * 1000 + Math.PI * Math.PI), EPSILON,
'distance of transform lists');
}, 'Test distance of transform lists');
test(function(t) {
@ -315,7 +315,7 @@ test(function(t) {
Math.PI / 2 * Math.PI / 2 +
4 * 4 * 2 +
1 * 1),
epsilon,
EPSILON,
'distance of transform lists');
}, 'Test distance of transform lists where one has extra items');
@ -335,7 +335,7 @@ test(function(t) {
'translate(1000px) rotate3d(0, 1, 0, -2rad)');
assert_approx_equals(dist,
Math.sqrt(900 * 900 + 1 * 1 + 2 * 2),
epsilon,
EPSILON,
'distance of transform lists');
}, 'Test distance of mismatched transform lists with skew function');

Просмотреть файл

@ -189,37 +189,16 @@ bool nsCSSValue::operator==(const nsCSSValue& aOther) const
}
double
nsCSSValue::GetAngleValueInRadians() const
nsCSSValue::GetAngleValueInDegrees() const
{
double angle = GetFloatValue();
switch (GetUnit()) {
case eCSSUnit_Radian: return angle;
case eCSSUnit_Turn: return angle * 2 * M_PI;
case eCSSUnit_Degree: return angle * M_PI / 180.0;
case eCSSUnit_Grad: return angle * M_PI / 200.0;
default:
MOZ_ASSERT(false, "unrecognized angular unit");
return 0.0;
}
// Note that this extends the value from float to double.
return GetAngleValue();
}
double
nsCSSValue::GetAngleValueInDegrees() const
nsCSSValue::GetAngleValueInRadians() const
{
double angle = GetFloatValue();
switch (GetUnit()) {
case eCSSUnit_Degree: return angle;
case eCSSUnit_Grad: return angle * 0.9; // grad / 400 * 360
case eCSSUnit_Radian: return angle * 180.0 / M_PI; // rad / 2pi * 360
case eCSSUnit_Turn: return angle * 360.0;
default:
MOZ_ASSERT(false, "unrecognized angular unit");
return 0.0;
}
return GetAngleValueInDegrees() * M_PI / 180.0;
}
nscoord nsCSSValue::GetPixelLength() const
@ -614,9 +593,6 @@ nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
case eCSSUnit_Pixel:
case eCSSUnit_Quarter:
case eCSSUnit_Degree:
case eCSSUnit_Grad:
case eCSSUnit_Turn:
case eCSSUnit_Radian:
case eCSSUnit_Hertz:
case eCSSUnit_Kilohertz:
case eCSSUnit_Seconds:

Просмотреть файл

@ -335,9 +335,6 @@ enum nsCSSUnit {
// Angular units
eCSSUnit_Degree = 1000, // (float) 360 per circle
eCSSUnit_Grad = 1001, // (float) 400 per circle
eCSSUnit_Radian = 1002, // (float) 2*pi per circle
eCSSUnit_Turn = 1003, // (float) 1 per circle
// Frequency units
eCSSUnit_Hertz = 2000, // (float) 1/seconds
@ -433,7 +430,7 @@ public:
static bool IsFloatUnit(nsCSSUnit aUnit)
{ return eCSSUnit_Number <= aUnit; }
bool IsAngularUnit() const
{ return eCSSUnit_Degree <= mUnit && mUnit <= eCSSUnit_Turn; }
{ return eCSSUnit_Degree == mUnit; }
bool IsFrequencyUnit() const
{ return eCSSUnit_Hertz <= mUnit && mUnit <= eCSSUnit_Kilohertz; }
bool IsTimeUnit() const
@ -475,8 +472,7 @@ public:
float GetAngleValue() const
{
MOZ_ASSERT(eCSSUnit_Degree <= mUnit && mUnit <= eCSSUnit_Turn,
"not an angle value");
MOZ_ASSERT(eCSSUnit_Degree == mUnit, "not an angle value");
return mValue.mFloat;
}

Просмотреть файл

@ -3887,18 +3887,6 @@ nsComputedDOMStyle::SetValueToCoord(nsROCSSPrimitiveValue* aValue,
aValue->SetDegree(aCoord.GetAngleValue());
break;
case eStyleUnit_Grad:
aValue->SetGrad(aCoord.GetAngleValue());
break;
case eStyleUnit_Radian:
aValue->SetRadian(aCoord.GetAngleValue());
break;
case eStyleUnit_Turn:
aValue->SetTurn(aCoord.GetAngleValue());
break;
case eStyleUnit_FlexFraction: {
nsAutoString tmpStr;
nsStyleUtil::AppendCSSNumber(aCoord.GetFlexFractionValue(), tmpStr);

Просмотреть файл

@ -109,24 +109,6 @@ nsROCSSPrimitiveValue::GetCssText(nsAString& aCssText)
tmpStr.AppendLiteral("deg");
break;
}
case CSS_GRAD:
{
nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
tmpStr.AppendLiteral("grad");
break;
}
case CSS_RAD:
{
nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
tmpStr.AppendLiteral("rad");
break;
}
case CSS_TURN:
{
nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
tmpStr.AppendLiteral("turn");
break;
}
case CSS_S:
{
nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
@ -168,138 +150,6 @@ nsROCSSPrimitiveValue::CssValueType() const
return CSSValue::CSS_PRIMITIVE_VALUE;
}
void
nsROCSSPrimitiveValue::SetFloatValue(uint16_t aType, float aVal,
ErrorResult& aRv)
{
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
}
float
nsROCSSPrimitiveValue::GetFloatValue(uint16_t aUnitType, ErrorResult& aRv)
{
switch(aUnitType) {
case CSS_PX:
if (mType == CSS_PX) {
return nsPresContext::AppUnitsToFloatCSSPixels(mValue.mAppUnits);
}
break;
case CSS_CM:
if (mType == CSS_PX) {
return mValue.mAppUnits * CM_PER_INCH_FLOAT / AppUnitsPerCSSInch();
}
break;
case CSS_MM:
if (mType == CSS_PX) {
return mValue.mAppUnits * MM_PER_INCH_FLOAT / AppUnitsPerCSSInch();
}
break;
case CSS_IN:
if (mType == CSS_PX) {
return mValue.mAppUnits / AppUnitsPerCSSInch();
}
break;
case CSS_PT:
if (mType == CSS_PX) {
return mValue.mAppUnits * POINTS_PER_INCH_FLOAT / AppUnitsPerCSSInch();
}
break;
case CSS_PC:
if (mType == CSS_PX) {
return mValue.mAppUnits * 6.0f / AppUnitsPerCSSInch();
}
break;
case CSS_PERCENTAGE:
if (mType == CSS_PERCENTAGE) {
return mValue.mFloat * 100;
}
break;
case CSS_NUMBER:
if (mType == CSS_NUMBER) {
return mValue.mFloat;
}
if (mType == CSS_NUMBER_INT32) {
return mValue.mInt32;
}
if (mType == CSS_NUMBER_UINT32) {
return mValue.mUint32;
}
break;
case CSS_UNKNOWN:
case CSS_EMS:
case CSS_EXS:
case CSS_DEG:
case CSS_RAD:
case CSS_GRAD:
case CSS_MS:
case CSS_S:
case CSS_HZ:
case CSS_KHZ:
case CSS_DIMENSION:
case CSS_STRING:
case CSS_URI:
case CSS_IDENT:
case CSS_ATTR:
case CSS_COUNTER:
case CSS_RGBCOLOR:
break;
}
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return 0;
}
void
nsROCSSPrimitiveValue::SetStringValue(uint16_t aType, const nsAString& aString,
mozilla::ErrorResult& aRv)
{
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
}
void
nsROCSSPrimitiveValue::GetStringValue(nsString& aReturn, ErrorResult& aRv)
{
switch (mType) {
case CSS_IDENT:
CopyUTF8toUTF16(nsCSSKeywords::GetStringValue(mValue.mKeyword), aReturn);
break;
case CSS_STRING:
case CSS_ATTR:
aReturn.Assign(mValue.mString);
break;
case CSS_URI: {
nsAutoCString spec;
if (mValue.mURI) {
nsresult rv = mValue.mURI->GetSpec(spec);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
}
CopyUTF8toUTF16(spec, aReturn);
break;
}
default:
aReturn.Truncate();
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return;
}
}
void
nsROCSSPrimitiveValue::GetCounterValue(ErrorResult& aRv)
{
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
}
void
nsROCSSPrimitiveValue::SetNumber(float aValue)
{
@ -340,30 +190,6 @@ nsROCSSPrimitiveValue::SetDegree(float aValue)
mType = CSS_DEG;
}
void
nsROCSSPrimitiveValue::SetGrad(float aValue)
{
Reset();
mValue.mFloat = aValue;
mType = CSS_GRAD;
}
void
nsROCSSPrimitiveValue::SetRadian(float aValue)
{
Reset();
mValue.mFloat = aValue;
mType = CSS_RAD;
}
void
nsROCSSPrimitiveValue::SetTurn(float aValue)
{
Reset();
mValue.mFloat = aValue;
mType = CSS_TURN;
}
void
nsROCSSPrimitiveValue::SetAppUnits(nscoord aValue)
{

Просмотреть файл

@ -36,8 +36,6 @@ public:
CSS_PT,
CSS_PC,
CSS_DEG,
CSS_RAD,
CSS_GRAD,
CSS_MS,
CSS_S,
CSS_HZ,
@ -49,7 +47,6 @@ public:
CSS_ATTR,
CSS_COUNTER,
CSS_RGBCOLOR,
CSS_TURN,
CSS_NUMBER_INT32,
CSS_NUMBER_UINT32,
};
@ -60,13 +57,6 @@ public:
// CSSPrimitiveValue
uint16_t PrimitiveType();
void SetFloatValue(uint16_t aUnitType, float aValue,
mozilla::ErrorResult& aRv);
float GetFloatValue(uint16_t aUnitType, mozilla::ErrorResult& aRv);
void GetStringValue(nsString& aString, mozilla::ErrorResult& aRv);
void SetStringValue(uint16_t aUnitType, const nsAString& aString,
mozilla::ErrorResult& aRv);
void GetCounterValue(mozilla::ErrorResult& aRv);
// nsROCSSPrimitiveValue
nsROCSSPrimitiveValue();
@ -77,9 +67,6 @@ public:
void SetNumber(uint32_t aValue);
void SetPercent(float aValue);
void SetDegree(float aValue);
void SetGrad(float aValue);
void SetRadian(float aValue);
void SetTurn(float aValue);
void SetAppUnits(nscoord aValue);
void SetAppUnits(float aValue);
void SetIdent(nsCSSKeyword aKeyword);

Просмотреть файл

@ -69,9 +69,6 @@ bool nsStyleCoord::operator==(const nsStyleCoord& aOther) const
case eStyleUnit_Percent:
case eStyleUnit_Factor:
case eStyleUnit_Degree:
case eStyleUnit_Grad:
case eStyleUnit_Radian:
case eStyleUnit_Turn:
case eStyleUnit_FlexFraction:
return mValue.mFloat == aOther.mValue.mFloat;
case eStyleUnit_Coord:
@ -123,20 +120,6 @@ void nsStyleCoord::SetFactorValue(float aValue)
mValue.mFloat = aValue;
}
void nsStyleCoord::SetAngleValue(float aValue, nsStyleUnit aUnit)
{
Reset();
if (aUnit == eStyleUnit_Degree ||
aUnit == eStyleUnit_Grad ||
aUnit == eStyleUnit_Radian ||
aUnit == eStyleUnit_Turn) {
mUnit = aUnit;
mValue.mFloat = aValue;
} else {
MOZ_ASSERT_UNREACHABLE("not an angle value");
}
}
void nsStyleCoord::SetFlexFractionValue(float aValue)
{
Reset();
@ -178,24 +161,14 @@ void nsStyleCoord::SetNoneValue()
double
nsStyleCoord::GetAngleValueInDegrees() const
{
return GetAngleValueInRadians() * (180.0 / M_PI);
// Note that this extends the value from float to double.
return GetAngleValue();
}
double
nsStyleCoord::GetAngleValueInRadians() const
{
double angle = mValue.mFloat;
switch (GetUnit()) {
case eStyleUnit_Radian: return angle;
case eStyleUnit_Turn: return angle * 2 * M_PI;
case eStyleUnit_Degree: return angle * M_PI / 180.0;
case eStyleUnit_Grad: return angle * M_PI / 200.0;
default:
MOZ_ASSERT_UNREACHABLE("unrecognized angular unit");
return 0.0;
}
return GetAngleValueInDegrees() * M_PI / 180.0;
}
nscoord

Просмотреть файл

@ -55,9 +55,6 @@ enum nsStyleUnit : uint8_t {
eStyleUnit_Percent = 10, // (float) 1.0 == 100%
eStyleUnit_Factor = 11, // (float) a multiplier
eStyleUnit_Degree = 12, // (float) angle in degrees
eStyleUnit_Grad = 13, // (float) angle in grads
eStyleUnit_Radian = 14, // (float) angle in radians
eStyleUnit_Turn = 15, // (float) angle in turns
eStyleUnit_FlexFraction = 16, // (float) <flex> in fr units
eStyleUnit_Coord = 20, // (nscoord) value is twips
eStyleUnit_Integer = 30, // (int) value is simple integer
@ -153,7 +150,7 @@ public:
}
bool IsAngleValue() const {
return eStyleUnit_Degree <= mUnit && mUnit <= eStyleUnit_Turn;
return eStyleUnit_Degree == mUnit;
}
static bool IsCalcUnit(nsStyleUnit aUnit) {
@ -256,7 +253,6 @@ public:
void SetIntValue(int32_t aValue, nsStyleUnit aUnit);
void SetPercentValue(float aValue);
void SetFactorValue(float aValue);
void SetAngleValue(float aValue, nsStyleUnit aUnit);
void SetFlexFractionValue(float aValue);
void SetNormalValue();
void SetAutoValue();
@ -494,12 +490,8 @@ inline float nsStyleCoord::GetFactorOrPercentValue() const
inline float nsStyleCoord::GetAngleValue() const
{
NS_ASSERTION(mUnit >= eStyleUnit_Degree &&
mUnit <= eStyleUnit_Turn, "not an angle value");
if (mUnit >= eStyleUnit_Degree && mUnit <= eStyleUnit_Turn) {
return mValue.mFloat;
}
return 0.0f;
MOZ_ASSERT(mUnit == eStyleUnit_Degree);
return mValue.mFloat;
}
inline float nsStyleCoord::GetFlexFractionValue() const

Просмотреть файл

@ -209,9 +209,6 @@ nsStyleUtil::AppendAngleValue(const nsStyleCoord& aAngle, nsAString& aResult)
// Append unit.
switch (aAngle.GetUnit()) {
case eStyleUnit_Degree: aResult.AppendLiteral("deg"); break;
case eStyleUnit_Grad: aResult.AppendLiteral("grad"); break;
case eStyleUnit_Radian: aResult.AppendLiteral("rad"); break;
case eStyleUnit_Turn: aResult.AppendLiteral("turn"); break;
default: MOZ_ASSERT_UNREACHABLE("unrecognized angle unit");
}
}

Просмотреть файл

@ -225,7 +225,7 @@ var noframe_container = document.getElementById("content");
"linear-gradient(-45deg, rgb(255, 0, 0), rgb(0, 0, 255))",
"linear gradient with angle in degrees" ],
[ "linear-gradient(-0.125turn, red, blue)",
"linear-gradient(-0.125turn, rgb(255, 0, 0), rgb(0, 0, 255))",
"linear-gradient(-45deg, rgb(255, 0, 0), rgb(0, 0, 255))",
"linear gradient with angle in turns" ],
];

Просмотреть файл

@ -993,19 +993,19 @@ var filterTests = [
{ start: "hue-rotate(0deg)", end: "hue-rotate(720deg)",
expected: ["hue-rotate", "180deg"] },
{ start: "hue-rotate(0rad)", end: "hue-rotate("+4*Math.PI+"rad)",
expected: ["hue-rotate", Math.PI.toFixed(5)+"rad"] },
expected: ["hue-rotate", "180deg"] },
{ start: "hue-rotate(0grad)", end: "hue-rotate(800grad)",
expected: ["hue-rotate", "200grad"] },
expected: ["hue-rotate", "180deg"] },
{ start: "hue-rotate(0turn)", end: "hue-rotate(2turn)",
expected: ["hue-rotate", "0.5turn"] },
expected: ["hue-rotate", "180deg"] },
{ start: "hue-rotate(0deg)", end: "hue-rotate("+4*Math.PI+"rad)",
expected: ["hue-rotate", Math.PI.toFixed(5)+"rad"] },
expected: ["hue-rotate", "180deg"] },
{ start: "hue-rotate(0turn)", end: "hue-rotate(800grad)",
expected: ["hue-rotate", Math.PI.toFixed(5)+"rad"] },
expected: ["hue-rotate", "180deg"] },
{ start: "hue-rotate(0grad)", end: "hue-rotate("+4*Math.PI+"rad)",
expected: ["hue-rotate", Math.PI.toFixed(5)+"rad"] },
expected: ["hue-rotate", "180deg"] },
{ start: "hue-rotate(0grad)", end: "hue-rotate(0turn)",
expected: ["hue-rotate", "0rad"] },
expected: ["hue-rotate", "0deg"] },
// multiple matching functions, same length
{ start: "contrast(25%) brightness(0.25) blur(25px) sepia(75%)",
end: "contrast(75%) brightness(0.75) blur(75px) sepia(25%)",

Просмотреть файл

@ -11,7 +11,7 @@
use app_units::Au;
use gecko::values::GeckoStyleCoordConvertible;
use gecko_bindings::bindings;
use gecko_bindings::structs::{self, nsCSSUnit, nsStyleCoord_CalcValue};
use gecko_bindings::structs::{self, nsStyleCoord_CalcValue};
use gecko_bindings::structs::{nsresult, SheetType, nsStyleImage};
use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
use std::f32::consts::PI;
@ -128,35 +128,7 @@ impl From<nsStyleCoord_CalcValue> for NonNegativeLengthOrPercentageOrAuto {
impl From<Angle> for CoordDataValue {
fn from(reference: Angle) -> Self {
match reference {
Angle::Deg(val) => CoordDataValue::Degree(val),
Angle::Grad(val) => CoordDataValue::Grad(val),
Angle::Rad(val) => CoordDataValue::Radian(val),
Angle::Turn(val) => CoordDataValue::Turn(val),
}
}
}
impl Angle {
/// Converts Angle struct into (value, unit) pair.
pub fn to_gecko_values(&self) -> (f32, nsCSSUnit) {
match *self {
Angle::Deg(val) => (val, nsCSSUnit::eCSSUnit_Degree),
Angle::Grad(val) => (val, nsCSSUnit::eCSSUnit_Grad),
Angle::Rad(val) => (val, nsCSSUnit::eCSSUnit_Radian),
Angle::Turn(val) => (val, nsCSSUnit::eCSSUnit_Turn),
}
}
/// Converts gecko (value, unit) pair into Angle struct
pub fn from_gecko_values(value: f32, unit: nsCSSUnit) -> Angle {
match unit {
nsCSSUnit::eCSSUnit_Degree => Angle::Deg(value),
nsCSSUnit::eCSSUnit_Grad => Angle::Grad(value),
nsCSSUnit::eCSSUnit_Radian => Angle::Rad(value),
nsCSSUnit::eCSSUnit_Turn => Angle::Turn(value),
_ => panic!("Unexpected unit for angle"),
}
CoordDataValue::Degree(reference.degrees())
}
}

Просмотреть файл

@ -325,10 +325,7 @@ impl GeckoStyleCoordConvertible for Angle {
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
match coord.as_value() {
CoordDataValue::Degree(val) => Some(Angle::Deg(val)),
CoordDataValue::Grad(val) => Some(Angle::Grad(val)),
CoordDataValue::Radian(val) => Some(Angle::Rad(val)),
CoordDataValue::Turn(val) => Some(Angle::Turn(val)),
CoordDataValue::Degree(val) => Some(Angle::from_degrees(val)),
_ => None,
}
}

Просмотреть файл

@ -198,19 +198,19 @@ impl nsCSSValue {
/// Returns an `Angle` value from this `nsCSSValue`.
///
/// Panics if the unit is not `eCSSUnit_Degree` `eCSSUnit_Grad`, `eCSSUnit_Turn`
/// or `eCSSUnit_Radian`.
/// Panics if the unit is not `eCSSUnit_Degree`.
#[inline]
pub fn get_angle(&self) -> Angle {
Angle::from_gecko_values(self.float_unchecked(), self.mUnit)
debug_assert_eq!(self.mUnit, nsCSSUnit::eCSSUnit_Degree);
Angle::from_degrees(self.float_unchecked())
}
/// Sets Angle value to this nsCSSValue.
pub fn set_angle(&mut self, angle: Angle) {
debug_assert_eq!(self.mUnit, nsCSSUnit::eCSSUnit_Null);
let (value, unit) = angle.to_gecko_values();
self.mUnit = unit;
self.mUnit = nsCSSUnit::eCSSUnit_Degree;
unsafe {
*self.mValue.mFloat.as_mut() = value;
*self.mValue.mFloat.as_mut() = angle.degrees();
}
}

Просмотреть файл

@ -200,12 +200,6 @@ pub enum CoordDataValue {
Factor(f32),
/// eStyleUnit_Degree
Degree(f32),
/// eStyleUnit_Grad
Grad(f32),
/// eStyleUnit_Radian
Radian(f32),
/// eStyleUnit_Turn
Turn(f32),
/// eStyleUnit_FlexFraction
FlexFraction(f32),
/// eStyleUnit_Coord
@ -317,18 +311,6 @@ pub unsafe trait CoordDataMut: CoordData {
*unit = eStyleUnit_Degree;
*union.mFloat.as_mut() = f;
},
Grad(f) => {
*unit = eStyleUnit_Grad;
*union.mFloat.as_mut() = f;
},
Radian(f) => {
*unit = eStyleUnit_Radian;
*union.mFloat.as_mut() = f;
},
Turn(f) => {
*unit = eStyleUnit_Turn;
*union.mFloat.as_mut() = f;
},
FlexFraction(f) => {
*unit = eStyleUnit_FlexFraction;
*union.mFloat.as_mut() = f;
@ -393,9 +375,6 @@ pub unsafe trait CoordData {
eStyleUnit_Percent => Percent(self.get_float()),
eStyleUnit_Factor => Factor(self.get_float()),
eStyleUnit_Degree => Degree(self.get_float()),
eStyleUnit_Grad => Grad(self.get_float()),
eStyleUnit_Radian => Radian(self.get_float()),
eStyleUnit_Turn => Turn(self.get_float()),
eStyleUnit_FlexFraction => FlexFraction(self.get_float()),
eStyleUnit_Coord => Coord(self.get_integer()),
eStyleUnit_Integer => Integer(self.get_integer()),
@ -413,9 +392,6 @@ pub unsafe trait CoordData {
self.unit() == eStyleUnit_Percent ||
self.unit() == eStyleUnit_Factor ||
self.unit() == eStyleUnit_Degree ||
self.unit() == eStyleUnit_Grad ||
self.unit() == eStyleUnit_Radian ||
self.unit() == eStyleUnit_Turn ||
self.unit() == eStyleUnit_FlexFraction
);
*self.union().mFloat.as_ref()

Просмотреть файл

@ -5,38 +5,41 @@
//! Computed angles.
use num_traits::Zero;
use std::fmt::{self, Write};
use std::{f32, f64};
use std::f64::consts::PI;
use std::ops::Add;
use style_traits::{CssWriter, ToCss};
use values::CSSFloat;
use values::animated::{Animate, Procedure};
use values::distance::{ComputeSquaredDistance, SquaredDistance};
/// A computed angle.
#[animate(fallback = "Self::animate_fallback")]
/// A computed angle in degrees.
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
#[derive(
Animate, Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, ToAnimatedZero, ToCss,
)]
pub enum Angle {
/// An angle with degree unit.
#[css(dimension)]
Deg(CSSFloat),
/// An angle with gradian unit.
#[css(dimension)]
Grad(CSSFloat),
/// An angle with radian unit.
#[css(dimension)]
Rad(CSSFloat),
/// An angle with turn unit.
#[css(dimension)]
Turn(CSSFloat),
#[derive(Animate, Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, ToAnimatedZero)]
pub struct Angle(CSSFloat);
impl ToCss for Angle {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
self.degrees().to_css(dest)?;
dest.write_str("deg")
}
}
const RAD_PER_DEG: f64 = PI / 180.0;
impl Angle {
/// Creates a computed `Angle` value from a radian amount.
pub fn from_radians(radians: CSSFloat) -> Self {
Angle::Rad(radians)
Angle(radians / RAD_PER_DEG as f32)
}
/// Creates a computed `Angle` value from a degrees amount.
#[inline]
pub fn from_degrees(degrees: CSSFloat) -> Self {
Angle(degrees)
}
/// Returns the amount of radians this angle represents.
@ -48,43 +51,18 @@ impl Angle {
/// Returns the amount of radians this angle represents as a `f64`.
///
/// Gecko stores angles as singles, but does this computation using doubles.
/// See nsCSSValue::GetAngleValueInRadians.
///
/// This is significant enough to mess up rounding to the nearest
/// quarter-turn for 225 degrees, for example.
#[inline]
pub fn radians64(&self) -> f64 {
const RAD_PER_DEG: f64 = PI / 180.0;
const RAD_PER_GRAD: f64 = PI / 200.0;
const RAD_PER_TURN: f64 = PI * 2.0;
let radians = match *self {
Angle::Deg(val) => val as f64 * RAD_PER_DEG,
Angle::Grad(val) => val as f64 * RAD_PER_GRAD,
Angle::Turn(val) => val as f64 * RAD_PER_TURN,
Angle::Rad(val) => val as f64,
};
radians.min(f64::MAX).max(f64::MIN)
self.0 as f64 * RAD_PER_DEG as f64
}
/// Return the value in degrees.
pub fn degrees(&self) -> f32 {
use std::f32::consts::PI;
self.radians() * 360. / (2. * PI)
}
/// <https://drafts.csswg.org/css-transitions/#animtype-number>
#[inline]
fn animate_fallback(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
Ok(Angle::from_radians(
self.radians().animate(&other.radians(), procedure)?,
))
}
}
impl AsRef<Angle> for Angle {
#[inline]
fn as_ref(&self) -> &Self {
self
pub fn degrees(&self) -> CSSFloat {
self.0
}
}
@ -93,27 +71,19 @@ impl Add for Angle {
#[inline]
fn add(self, rhs: Self) -> Self {
match (self, rhs) {
(Angle::Deg(x), Angle::Deg(y)) => Angle::Deg(x + y),
(Angle::Grad(x), Angle::Grad(y)) => Angle::Grad(x + y),
(Angle::Turn(x), Angle::Turn(y)) => Angle::Turn(x + y),
(Angle::Rad(x), Angle::Rad(y)) => Angle::Rad(x + y),
_ => Angle::from_radians(self.radians() + rhs.radians()),
}
Angle(self.0 + rhs.0)
}
}
impl Zero for Angle {
#[inline]
fn zero() -> Self {
Angle::from_radians(0.0)
Angle(0.0)
}
#[inline]
fn is_zero(&self) -> bool {
match *self {
Angle::Deg(val) | Angle::Grad(val) | Angle::Turn(val) | Angle::Rad(val) => val == 0.,
}
self.0 == 0.
}
}
@ -122,7 +92,6 @@ impl ComputeSquaredDistance for Angle {
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
// Use the formula for calculating the distance between angles defined in SVG:
// https://www.w3.org/TR/SVG/animate.html#complexDistances
self.radians64()
.compute_squared_distance(&other.radians64())
self.radians64().compute_squared_distance(&other.radians64())
}
}

Просмотреть файл

@ -866,7 +866,7 @@ impl ToAnimatedValue for FontStyleAngle {
#[inline]
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
FontStyleAngle(Angle::Deg(
FontStyleAngle(Angle::from_degrees(
animated
.degrees()
.min(specified::FONT_STYLE_OBLIQUE_MAX_ANGLE_DEGREES)
@ -899,7 +899,7 @@ impl FontStyle {
/// https://drafts.csswg.org/css-fonts-4/#valdef-font-style-oblique-angle
#[inline]
pub fn default_angle() -> FontStyleAngle {
FontStyleAngle(Angle::Deg(
FontStyleAngle(Angle::from_degrees(
specified::DEFAULT_FONT_STYLE_OBLIQUE_ANGLE_DEGREES,
))
}
@ -919,7 +919,7 @@ impl FontStyle {
if italic {
return generics::FontStyle::Italic;
}
generics::FontStyle::Oblique(FontStyleAngle(Angle::Deg(angle)))
generics::FontStyle::Oblique(FontStyleAngle(Angle::from_degrees(angle)))
}
}

Просмотреть файл

@ -10,6 +10,7 @@ use num_traits::Zero;
use values::{computed, CSSFloat};
use values::computed::length::Length as ComputedLength;
use values::computed::length::LengthOrPercentage as ComputedLengthOrPercentage;
use values::specified::angle::Angle as SpecifiedAngle;
use values::specified::length::Length as SpecifiedLength;
use values::specified::length::LengthOrPercentage as SpecifiedLengthOrPercentage;
@ -394,10 +395,30 @@ pub trait ToMatrix {
fn to_3d_matrix(&self, reference_box: Option<&Rect<Au>>) -> Result<Transform3D<f64>, ()>;
}
/// A little helper to deal with both specified and computed angles.
pub trait ToRadians {
/// Return the radians value as a 64-bit floating point value.
fn radians64(&self) -> f64;
}
impl ToRadians for computed::angle::Angle {
#[inline]
fn radians64(&self) -> f64 {
computed::angle::Angle::radians64(self)
}
}
impl ToRadians for SpecifiedAngle {
#[inline]
fn radians64(&self) -> f64 {
computed::angle::Angle::from_degrees(self.degrees()).radians64()
}
}
impl<Angle, Number, Length, Integer, LoP> ToMatrix
for TransformOperation<Angle, Number, Length, Integer, LoP>
where
Angle: Copy + AsRef<computed::angle::Angle>,
Angle: ToRadians + Copy,
Number: Copy + Into<f32> + Into<f64>,
Length: ToAbsoluteLength,
LoP: ToAbsoluteLength,
@ -426,7 +447,7 @@ where
let reference_height = reference_box.map(|v| v.size.height);
let matrix = match *self {
Rotate3D(ax, ay, az, theta) => {
let theta = TWO_PI - theta.as_ref().radians64();
let theta = TWO_PI - theta.radians64();
let (ax, ay, az, theta) =
get_normalized_vector_and_angle(ax.into(), ay.into(), az.into(), theta);
Transform3D::create_rotation(
@ -437,15 +458,15 @@ where
)
},
RotateX(theta) => {
let theta = euclid::Angle::radians(TWO_PI - theta.as_ref().radians64());
let theta = euclid::Angle::radians(TWO_PI - theta.radians64());
Transform3D::create_rotation(1., 0., 0., theta)
},
RotateY(theta) => {
let theta = euclid::Angle::radians(TWO_PI - theta.as_ref().radians64());
let theta = euclid::Angle::radians(TWO_PI - theta.radians64());
Transform3D::create_rotation(0., 1., 0., theta)
},
RotateZ(theta) | Rotate(theta) => {
let theta = euclid::Angle::radians(TWO_PI - theta.as_ref().radians64());
let theta = euclid::Angle::radians(TWO_PI - theta.radians64());
Transform3D::create_rotation(0., 0., 1., theta)
},
Perspective(ref d) => {
@ -479,16 +500,16 @@ where
Transform3D::create_translation(0., 0., z.to_pixel_length(None)? as f64)
},
Skew(theta_x, theta_y) => Transform3D::create_skew(
euclid::Angle::radians(theta_x.as_ref().radians64()),
euclid::Angle::radians(theta_y.map_or(0., |a| a.as_ref().radians64())),
euclid::Angle::radians(theta_x.radians64()),
euclid::Angle::radians(theta_y.map_or(0., |a| a.radians64())),
),
SkewX(theta) => Transform3D::create_skew(
euclid::Angle::radians(theta.as_ref().radians64()),
euclid::Angle::radians(theta.radians64()),
euclid::Angle::radians(0.),
),
SkewY(theta) => Transform3D::create_skew(
euclid::Angle::radians(0.),
euclid::Angle::radians(theta.as_ref().radians64()),
euclid::Angle::radians(theta.radians64()),
),
Matrix3D(m) => m.into(),
Matrix(m) => m.into(),

Просмотреть файл

@ -7,21 +7,53 @@
use cssparser::{Parser, Token};
use parser::{Parse, ParserContext};
use std::fmt::{self, Write};
use std::f32::consts::PI;
use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, ToCss};
use values::CSSFloat;
use values::computed::{Context, ToComputedValue};
use values::computed::angle::Angle as ComputedAngle;
use values::specified::calc::CalcNode;
/// A specified angle.
///
/// Computed angles are essentially same as specified ones except for `calc()`
/// value serialization. Therefore we are storing a computed angle inside
/// to hold the actual value and its unit.
/// A specified angle dimension.
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, ToCss)]
pub enum AngleDimension {
/// An angle with degree unit.
#[css(dimension)]
Deg(CSSFloat),
/// An angle with gradian unit.
#[css(dimension)]
Grad(CSSFloat),
/// An angle with radian unit.
#[css(dimension)]
Rad(CSSFloat),
/// An angle with turn unit.
#[css(dimension)]
Turn(CSSFloat),
}
impl AngleDimension {
/// Returns the amount of degrees this angle represents.
#[inline]
fn degrees(&self) -> CSSFloat {
const DEG_PER_RAD: f32 = 180.0 / PI;
const DEG_PER_TURN: f32 = 360.0;
const DEG_PER_GRAD: f32 = 180.0 / 200.0;
match *self {
AngleDimension::Deg(d) => d,
AngleDimension::Rad(rad) => rad * DEG_PER_RAD,
AngleDimension::Turn(turns) => turns * DEG_PER_TURN,
AngleDimension::Grad(gradians) => gradians * DEG_PER_GRAD,
}
}
}
/// A specified Angle value, which is just the angle dimension, plus whether it
/// was specified as `calc()` or not.
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
pub struct Angle {
value: ComputedAngle,
value: AngleDimension,
was_calc: bool,
}
@ -41,22 +73,18 @@ impl ToCss for Angle {
}
}
// FIXME(emilio): Probably computed angles shouldn't preserve the unit and
// should serialize to degrees per:
//
// https://drafts.csswg.org/css-values/#compat
impl ToComputedValue for Angle {
type ComputedValue = ComputedAngle;
#[inline]
fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue {
self.value
ComputedAngle::from_degrees(self.degrees())
}
#[inline]
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
Angle {
value: *computed,
value: AngleDimension::Deg(computed.degrees()),
was_calc: false,
}
}
@ -64,35 +92,18 @@ impl ToComputedValue for Angle {
impl Angle {
/// Creates an angle with the given value in degrees.
#[inline]
pub fn from_degrees(value: CSSFloat, was_calc: bool) -> Self {
Angle {
value: ComputedAngle::Deg(value),
value: AngleDimension::Deg(value),
was_calc,
}
}
/// Creates an angle with the given value in gradians.
pub fn from_gradians(value: CSSFloat, was_calc: bool) -> Self {
Angle {
value: ComputedAngle::Grad(value),
was_calc,
}
}
/// Creates an angle with the given value in turns.
pub fn from_turns(value: CSSFloat, was_calc: bool) -> Self {
Angle {
value: ComputedAngle::Turn(value),
was_calc,
}
}
/// Creates an angle with the given value in radians.
pub fn from_radians(value: CSSFloat, was_calc: bool) -> Self {
Angle {
value: ComputedAngle::Rad(value),
was_calc,
}
/// Returns the value of the angle in degrees, mostly for `calc()`.
#[inline]
pub fn degrees(&self) -> CSSFloat {
self.value.degrees()
}
/// Whether this specified angle came from a `calc()` expression.
@ -101,39 +112,21 @@ impl Angle {
self.was_calc
}
/// Returns the amount of radians this angle represents.
#[inline]
pub fn radians(self) -> f32 {
self.value.radians()
}
/// Returns the amount of degrees this angle represents.
#[inline]
pub fn degrees(self) -> f32 {
self.value.degrees()
}
/// Returns `0deg`.
#[inline]
pub fn zero() -> Self {
Self::from_degrees(0.0, false)
}
/// Returns an `Angle` parsed from a `calc()` expression.
pub fn from_calc(radians: CSSFloat) -> Self {
pub fn from_calc(degrees: CSSFloat) -> Self {
Angle {
value: ComputedAngle::Rad(radians),
value: AngleDimension::Deg(degrees),
was_calc: true,
}
}
}
impl AsRef<ComputedAngle> for Angle {
#[inline]
fn as_ref(&self) -> &ComputedAngle {
&self.value
}
}
/// Whether to allow parsing an unitless zero as a valid angle.
///
/// This should always be `No`, except for exceptions like:
@ -158,20 +151,26 @@ impl Parse for Angle {
impl Angle {
/// Parse an `<angle>` value given a value and an unit.
pub fn parse_dimension(value: CSSFloat, unit: &str, from_calc: bool) -> Result<Angle, ()> {
let angle = match_ignore_ascii_case! { unit,
"deg" => Angle::from_degrees(value, from_calc),
"grad" => Angle::from_gradians(value, from_calc),
"turn" => Angle::from_turns(value, from_calc),
"rad" => Angle::from_radians(value, from_calc),
pub fn parse_dimension(
value: CSSFloat,
unit: &str,
was_calc: bool,
) -> Result<Angle, ()> {
let value = match_ignore_ascii_case! { unit,
"deg" => AngleDimension::Deg(value),
"grad" => AngleDimension::Grad(value),
"turn" => AngleDimension::Turn(value),
"rad" => AngleDimension::Rad(value),
_ => return Err(())
};
Ok(angle)
Ok(Self { value, was_calc })
}
/// Parse an `<angle>` allowing unitless zero to represent a zero angle.
///
/// See the comment in `AllowUnitlessZeroAngle` for why.
#[inline]
pub fn parse_with_unitless<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,

Просмотреть файл

@ -469,22 +469,22 @@ impl CalcNode {
CalcNode::Sub(ref a, ref b) => {
let lhs = a.to_angle()?;
let rhs = b.to_angle()?;
Angle::from_calc(lhs.radians() - rhs.radians())
Angle::from_calc(lhs.degrees() - rhs.degrees())
},
CalcNode::Sum(ref a, ref b) => {
let lhs = a.to_angle()?;
let rhs = b.to_angle()?;
Angle::from_calc(lhs.radians() + rhs.radians())
Angle::from_calc(lhs.degrees() + rhs.degrees())
},
CalcNode::Mul(ref a, ref b) => match a.to_angle() {
Ok(lhs) => {
let rhs = b.to_number()?;
Angle::from_calc(lhs.radians() * rhs)
Angle::from_calc(lhs.degrees() * rhs)
},
Err(..) => {
let lhs = a.to_number()?;
let rhs = b.to_angle()?;
Angle::from_calc(lhs * rhs.radians())
Angle::from_calc(lhs * rhs.degrees())
},
},
CalcNode::Div(ref a, ref b) => {
@ -493,7 +493,7 @@ impl CalcNode {
if rhs == 0. {
return Err(());
}
Angle::from_calc(lhs.radians() / rhs)
Angle::from_calc(lhs.degrees() / rhs)
},
CalcNode::Number(..) |
CalcNode::Length(..) |

Просмотреть файл

@ -301,7 +301,7 @@ impl SpecifiedFontStyle {
}
fn compute_angle(angle: &Angle) -> ComputedAngle {
ComputedAngle::Deg(Self::compute_angle_degrees(angle))
ComputedAngle::from_degrees(Self::compute_angle_degrees(angle))
}
/// Parse a suitable angle for font-style: oblique.

Просмотреть файл

@ -15,7 +15,6 @@ use selectors::parser::SelectorParseErrorKind;
#[cfg(feature = "servo")]
use servo_url::ServoUrl;
use std::cmp::Ordering;
use std::f32::consts::PI;
use std::fmt::{self, Write};
use style_traits::{CssType, CssWriter, KeywordsCollectFn, ParseError};
use style_traits::{StyleParseErrorKind, SpecifiedValueInfo, ToCss};
@ -679,7 +678,7 @@ impl GradientKind {
impl generic::LineDirection for LineDirection {
fn points_downwards(&self, compat_mode: CompatMode) -> bool {
match *self {
LineDirection::Angle(ref angle) => angle.radians() == PI,
LineDirection::Angle(ref angle) => angle.degrees() == 180.0,
LineDirection::Vertical(Y::Bottom) if compat_mode == CompatMode::Modern => true,
LineDirection::Vertical(Y::Top) if compat_mode != CompatMode::Modern => true,
#[cfg(feature = "gecko")]

Просмотреть файл

@ -2104,7 +2104,7 @@ const filterListType = {
// 10deg = 0.1745rad.
testAnimationSamples(animation, idlName,
[{ time: 500, expected: 'hue-rotate(50.0873rad)' }]);
[{ time: 500, expected: 'hue-rotate(2869.79deg)' }]);
}, `${property}: hue-rotate function with different unit(deg -> rad)`);
test(t => {