Bug 1294614 - Part 3: Add DiluteColor(). r?dholbert.
MozReview-Commit-ID: A82Oesv8aor
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -1191,16 +1191,42 @@ AddWeightedColors(double aCoeff1, nscolo
double factor = 1.0 / Aresf;
uint8_t Ares = NSToIntRound(Aresf * 255.0);
uint8_t Rres = ClampColor((R1 * aCoeff1 + R2 * aCoeff2) * factor);
uint8_t Gres = ClampColor((G1 * aCoeff1 + G2 * aCoeff2) * factor);
uint8_t Bres = ClampColor((B1 * aCoeff1 + B2 * aCoeff2) * factor);
return NS_RGBA(Rres, Gres, Bres, Ares);
}
+// Multiplies |aColor| by |aDilutionRatio| with premultiplication.
+// (The logic here should pretty closely match AddWeightedColors()' logic.)
+static nscolor
+DiluteColor(nscolor aColor, double aDilutionRatio)
+{
+ MOZ_ASSERT(aDilutionRatio >= 0.0 && aDilutionRatio <= 1.0,
+ "Dilution ratio should be in [0, 1]");
+
+ double A = NS_GET_A(aColor) * (1.0 / 255.0);
+ double Aresf = A * aDilutionRatio;
+ if (Aresf <= 0.0) {
+ return NS_RGBA(0, 0, 0, 0);
+ }
+
+ // Premultiplication
+ double R = NS_GET_R(aColor) * A;
+ double G = NS_GET_G(aColor) * A;
+ double B = NS_GET_B(aColor) * A;
+
+ double factor = 1.0 / Aresf;
+ return NS_RGBA(ClampColor(R * aDilutionRatio * factor),
+ ClampColor(G * aDilutionRatio * factor),
+ ClampColor(B * aDilutionRatio * factor),
+ NSToIntRound(Aresf * 255.0));
+}
+
static bool
AddShadowItems(double aCoeff1, const nsCSSValue &aValue1,
double aCoeff2, const nsCSSValue &aValue2,
nsCSSValueList **&aResultTail)
{
// X, Y, Radius, Spread, Color, Inset
MOZ_ASSERT(aValue1.GetUnit() == eCSSUnit_Array,
"wrong unit");
@@ -2379,18 +2405,28 @@ StyleAnimationValue::AddWeighted(nsCSSPr
aResultValue.SetFloatValue(RestrictValue(aProperty,
aCoeff1 * aValue1.GetFloatValue() +
aCoeff2 * aValue2.GetFloatValue()));
return true;
}
case eUnit_Color: {
nscolor color1 = aValue1.GetColorValue();
nscolor color2 = aValue2.GetColorValue();
- nscolor resultColor =
- AddWeightedColors(aCoeff1, color1, aCoeff2, color2);
+ nscolor resultColor;
+
+ // We are using AddWeighted() with a zero aCoeff2 for colors to
+ // pretend AddWeighted() against transparent color, i.e. rgba(0, 0, 0, 0).
+ // But unpremultiplication in AddWeightedColors() does not work well
+ // for such cases, so we use another function named DiluteColor() which
+ // has a similar logic to AddWeightedColors().
+ if (aCoeff2 == 0.0) {
+ resultColor = DiluteColor(color1, aCoeff1);
+ } else {
+ resultColor = AddWeightedColors(aCoeff1, color1, aCoeff2, color2);
+ }
aResultValue.SetColorValue(resultColor);
return true;
}
case eUnit_Calc: {
PixelCalcValue v1 = ExtractCalcValue(aValue1);
PixelCalcValue v2 = ExtractCalcValue(aValue2);
double len = aCoeff1 * v1.mLength + aCoeff2 * v2.mLength;
double pct = aCoeff1 * v1.mPercent + aCoeff2 * v2.mPercent;