Bug 1299741 part 1 - Factor out ComputeColorDistance. r=birtles
MozReview-Commit-ID: HojkuHyqWoT
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -482,16 +482,49 @@ CalcPositionCoordSquareDistance(const ns
float difflen = calcVal2.mLength - calcVal1.mLength;
float diffpct = calcVal2.mPercent - calcVal1.mPercent;
return difflen * difflen + diffpct * diffpct;
}
// CLASS METHODS
// -------------
+double
+StyleAnimationValue::ComputeColorDistance(nscolor aStartColor,
+ nscolor aEndColor)
+{
+ // http://www.w3.org/TR/smil-animation/#animateColorElement says
+ // that we should use Euclidean RGB cube distance. However, we
+ // have to extend that to RGBA. For now, we'll just use the
+ // Euclidean distance in the (part of the) 4-cube of premultiplied
+ // colors.
+
+ // Get a color component on a 0-1 scale, which is much easier to
+ // deal with when working with alpha.
+#define GET_COMPONENT(component_, color_) \
+ (NS_GET_##component_(color_) * (1.0 / 255.0))
+
+ double startA = GET_COMPONENT(A, aStartColor);
+ double startR = GET_COMPONENT(R, aStartColor) * startA;
+ double startG = GET_COMPONENT(G, aStartColor) * startA;
+ double startB = GET_COMPONENT(B, aStartColor) * startA;
+ double endA = GET_COMPONENT(A, aEndColor);
+ double endR = GET_COMPONENT(R, aEndColor) * endA;
+ double endG = GET_COMPONENT(G, aEndColor) * endA;
+ double endB = GET_COMPONENT(B, aEndColor) * endA;
+
+#undef GET_COMPONENT
+
+ 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);
+}
+
bool
StyleAnimationValue::ComputeDistance(nsCSSPropertyID aProperty,
const StyleAnimationValue& aStartValue,
const StyleAnimationValue& aEndValue,
double& aDistance)
{
Unit commonUnit =
GetCommonUnit(aProperty, aStartValue.GetUnit(), aEndValue.GetUnit());
@@ -553,50 +586,19 @@ StyleAnimationValue::ComputeDistance(nsC
}
case eUnit_Float: {
float startFloat = aStartValue.GetFloatValue();
float endFloat = aEndValue.GetFloatValue();
aDistance = Abs(double(endFloat) - double(startFloat));
return true;
}
case eUnit_Color: {
- // http://www.w3.org/TR/smil-animation/#animateColorElement says
- // that we should use Euclidean RGB cube distance. However, we
- // have to extend that to RGBA. For now, we'll just use the
- // Euclidean distance in the (part of the) 4-cube of premultiplied
- // colors.
- // FIXME (spec): The CSS transitions spec doesn't say whether
- // colors are premultiplied, but things work better when they are,
- // so use premultiplication. Spec issue is still open per
- // http://lists.w3.org/Archives/Public/www-style/2009Jul/0050.html
nscolor startColor = aStartValue.GetCSSValueValue()->GetColorValue();
nscolor endColor = aEndValue.GetCSSValueValue()->GetColorValue();
-
- // Get a color component on a 0-1 scale, which is much easier to
- // deal with when working with alpha.
- #define GET_COMPONENT(component_, color_) \
- (NS_GET_##component_(color_) * (1.0 / 255.0))
-
- double startA = GET_COMPONENT(A, startColor);
- double startR = GET_COMPONENT(R, startColor) * startA;
- double startG = GET_COMPONENT(G, startColor) * startA;
- double startB = GET_COMPONENT(B, startColor) * startA;
- double endA = GET_COMPONENT(A, endColor);
- double endR = GET_COMPONENT(R, endColor) * endA;
- double endG = GET_COMPONENT(G, endColor) * endA;
- double endB = GET_COMPONENT(B, endColor) * endA;
-
- #undef GET_COMPONENT
-
- double diffA = startA - endA;
- double diffR = startR - endR;
- double diffG = startG - endG;
- double diffB = startB - endB;
- aDistance = sqrt(diffA * diffA + diffR * diffR +
- diffG * diffG + diffB * diffB);
+ aDistance = ComputeColorDistance(startColor, endColor);
return true;
}
case eUnit_Calc: {
PixelCalcValue v1 = ExtractCalcValue(aStartValue);
PixelCalcValue v2 = ExtractCalcValue(aEndValue);
float difflen = v2.mLength - v1.mLength;
float diffpct = v2.mPercent - v1.mPercent;
aDistance = sqrt(difflen * difflen + diffpct * diffpct);
@@ -843,27 +845,19 @@ StyleAnimationValue::ComputeDistance(nsC
color2.IsNumericColorUnit()) ||
(color1.GetUnit() == color2.GetUnit())) &&
inset1 == inset2,
"AddWeighted should have failed");
}
#endif
if (color1.GetUnit() != eCSSUnit_Null) {
- StyleAnimationValue color1Value
- (color1.GetColorValue(), StyleAnimationValue::ColorConstructor);
- StyleAnimationValue color2Value
- (color2.GetColorValue(), StyleAnimationValue::ColorConstructor);
- double colorDistance;
-
- DebugOnly<bool> ok =
- StyleAnimationValue::ComputeDistance(eCSSProperty_color,
- color1Value, color2Value,
- colorDistance);
- MOZ_ASSERT(ok, "should not fail");
+ double colorDistance =
+ StyleAnimationValue::ComputeColorDistance(color1.GetColorValue(),
+ color2.GetColorValue());
squareDistance += colorDistance * colorDistance;
}
shadow1 = shadow1->mNext;
shadow2 = shadow2->mNext;
MOZ_ASSERT(!shadow1 == !shadow2, "lists should be same length");
}
aDistance = sqrt(squareDistance);
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -55,16 +55,27 @@ public:
*/
static MOZ_MUST_USE bool
Add(nsCSSPropertyID aProperty, StyleAnimationValue& aDest,
const StyleAnimationValue& aValueToAdd, uint32_t aCount) {
return AddWeighted(aProperty, 1.0, aDest, aCount, aValueToAdd, aDest);
}
/**
+ * Calculates a measure of 'distance' between two colors.
+ *
+ * @param aStartColor The start of the interval for which the distance
+ * should be calculated.
+ * @param aEndColor The end of the interval for which the distance
+ * should be calculated.
+ * @return the result of the calculation.
+ */
+ static double ComputeColorDistance(nscolor aStartColor, nscolor aEndColor);
+
+ /**
* Calculates a measure of 'distance' between two values.
*
* This measure of Distance is guaranteed to be proportional to
* portions passed to Interpolate, Add, or AddWeighted. However, for
* some types of StyleAnimationValue it may not produce sensible results
* for paced animation.
*
* If this method succeeds, the returned distance value is guaranteed to be