Bug 1272549 - Part 4: Compute distance for none and a valid transform list.
Reuse AddTransformLists to get the identity transform functions to
replace none, and then treat them with another transform list as two matched
ones.
MozReview-Commit-ID: HwdBPCiUivg
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -713,16 +713,20 @@ StyleAnimationValue::ComputeColorDistanc
double diffA = startA - endA;
double diffR = startR - endR;
double diffG = startG - endG;
double diffB = startB - endB;
return sqrt(diffA * diffA + diffR * diffR + diffG * diffG + diffB * diffB);
}
+static nsCSSValueList*
+AddTransformLists(double aCoeff1, const nsCSSValueList* aList1,
+ double aCoeff2, const nsCSSValueList* aList2);
+
static double
ComputeTransformDistance(nsCSSValue::Array* aArray1,
nsCSSValue::Array* aArray2)
{
MOZ_ASSERT(aArray1, "aArray1 should be non-null.");
MOZ_ASSERT(aArray2, "aArray2 should be non-null.");
// Normalize translate and scale functions to equivalent "translate3d" and
@@ -1251,23 +1255,21 @@ StyleAnimationValue::ComputeDistance(nsC
MOZ_ASSERT(list1);
MOZ_ASSERT(list2);
if (list1->mValue.GetUnit() == eCSSUnit_None &&
list2->mValue.GetUnit() == eCSSUnit_None) {
// Both none, nothing happens.
aDistance = 0.0;
} else if (list1->mValue.GetUnit() == eCSSUnit_None) {
- // TODO: Implement none transform list in the later patch.
- aDistance = 0.0;
- return false;
+ nsAutoPtr<nsCSSValueList> none(AddTransformLists(0, list2, 0, list2));
+ aDistance = ComputeTransformListDistance(none, list2);
} else if (list2->mValue.GetUnit() == eCSSUnit_None) {
- // TODO: Implement none transform list in the later patch.
- aDistance = 0.0;
- return false;
+ nsAutoPtr<nsCSSValueList> none(AddTransformLists(0, list1, 0, list1));
+ aDistance = ComputeTransformListDistance(list1, none);
} else {
const nsCSSValueList *item1 = list1, *item2 = list2;
do {
nsCSSKeyword func1 = nsStyleTransformMatrix::TransformFunctionOf(
item1->mValue.GetArrayValue());
nsCSSKeyword func2 = nsStyleTransformMatrix::TransformFunctionOf(
item2->mValue.GetArrayValue());
if (!TransformFunctionsMatch(func1, func2)) {
@@ -2509,18 +2511,39 @@ AddTransformLists(double aCoeff1, const
AddCSSValueAngle(aCoeff1, a1->Item(4), aCoeff2, a2->Item(4),
arr->Item(4));
break;
}
MOZ_FALLTHROUGH;
}
case eCSSKeyword_matrix:
case eCSSKeyword_matrix3d:
- case eCSSKeyword_interpolatematrix:
- case eCSSKeyword_perspective: {
+ case eCSSKeyword_perspective:
+ if (aCoeff1 == 0.0 && aCoeff2 == 0.0) {
+ // Special case. If both coefficients are 0.0, we should apply an
+ // identity transform function.
+ arr = StyleAnimationValue::AppendTransformFunction(tfunc, resultTail);
+
+ if (tfunc == eCSSKeyword_rotate3d) {
+ arr->Item(1).SetFloatValue(0.0, eCSSUnit_Number);
+ arr->Item(2).SetFloatValue(0.0, eCSSUnit_Number);
+ arr->Item(3).SetFloatValue(1.0, eCSSUnit_Number);
+ arr->Item(4).SetFloatValue(0.0, eCSSUnit_Radian);
+ } else if (tfunc == eCSSKeyword_perspective) {
+ // The parameter of the identity perspective function is
+ // positive infinite.
+ arr->Item(1).SetFloatValue(std::numeric_limits<float>::infinity(),
+ eCSSUnit_Pixel);
+ } else {
+ nsStyleTransformMatrix::SetIdentityMatrix(arr);
+ }
+ break;
+ }
+ MOZ_FALLTHROUGH;
+ case eCSSKeyword_interpolatematrix: {
// FIXME: If the matrix contains only numbers then we could decompose
// here.
// Construct temporary lists with only this item in them.
nsCSSValueList tempList1, tempList2;
tempList1.mValue = aList1->mValue;
tempList2.mValue = aList2->mValue;
--- a/layout/style/nsStyleTransformMatrix.cpp
+++ b/layout/style/nsStyleTransformMatrix.cpp
@@ -680,16 +680,42 @@ MatrixForTransformFunction(Matrix4x4& aM
*/
nsCSSKeyword
TransformFunctionOf(const nsCSSValue::Array* aData)
{
MOZ_ASSERT(aData->Item(0).GetUnit() == eCSSUnit_Enumerated);
return aData->Item(0).GetKeywordValue();
}
+void
+SetIdentityMatrix(nsCSSValue::Array* aMatrix)
+{
+ MOZ_ASSERT(aMatrix, "aMatrix should be non-null");
+
+ nsCSSKeyword tfunc = TransformFunctionOf(aMatrix);
+ MOZ_ASSERT(tfunc == eCSSKeyword_matrix ||
+ tfunc == eCSSKeyword_matrix3d,
+ "Only accept matrix and matrix3d");
+
+ if (tfunc == eCSSKeyword_matrix) {
+ MOZ_ASSERT(aMatrix->Count() == 7, "Invalid matrix");
+ Matrix m;
+ for (size_t i = 0; i < 6; ++i) {
+ aMatrix->Item(i + 1).SetFloatValue(m.components[i], eCSSUnit_Number);
+ }
+ return;
+ }
+
+ MOZ_ASSERT(aMatrix->Count() == 17, "Invalid matrix3d");
+ Matrix4x4 m;
+ for (size_t i = 0; i < 16; ++i) {
+ aMatrix->Item(i + 1).SetFloatValue(m.components[i], eCSSUnit_Number);
+ }
+}
+
Matrix4x4
ReadTransforms(const nsCSSValueList* aList,
nsStyleContext* aContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions,
TransformReferenceBox& aRefBox,
float aAppUnitsPerMatrixUnit,
bool* aContains3dTransform)
--- a/layout/style/nsStyleTransformMatrix.h
+++ b/layout/style/nsStyleTransformMatrix.h
@@ -122,16 +122,18 @@ namespace nsStyleTransformMatrix {
};
/**
* Return the transform function, as an nsCSSKeyword, for the given
* nsCSSValue::Array from a transform list.
*/
nsCSSKeyword TransformFunctionOf(const nsCSSValue::Array* aData);
+ void SetIdentityMatrix(nsCSSValue::Array* aMatrix);
+
float ProcessTranslatePart(const nsCSSValue& aValue,
nsStyleContext* aContext,
nsPresContext* aPresContext,
mozilla::RuleNodeCacheConditions& aConditions,
TransformReferenceBox* aRefBox,
TransformReferenceBox::DimensionGetter aDimensionGetter = nullptr);
void