From ab8ac0bf925f483433c5108739efb6fdc865156f Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Thu, 10 Nov 2016 17:46:35 +0800 Subject: [PATCH] Bug 1286151 - Part 2: Implement filter distance for drop-shadow. r=hiro MozReview-Commit-ID: 5Ad0GiWGkJg --HG-- extra : rebase_source : 3d3103bf976de199aed257e5f555d5f5158b20d3 --- layout/style/StyleAnimationValue.cpp | 49 ++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp index d9c9c2d45020..48bea52dc272 100644 --- a/layout/style/StyleAnimationValue.cpp +++ b/layout/style/StyleAnimationValue.cpp @@ -811,9 +811,54 @@ ComputeFilterSquareDistance(const nsCSSValueList* aList1, case eCSSKeyword_hue_rotate: // TODO break; - case eCSSKeyword_drop_shadow: - // TODO + case eCSSKeyword_drop_shadow: { + MOZ_ASSERT(!func1.GetListValue()->mNext && !func2.GetListValue()->mNext, + "drop-shadow filter func doesn't support lists"); + const nsCSSValue& shadow1 = func1.GetListValue()->mValue; + const nsCSSValue& shadow2 = func2.GetListValue()->mValue; + + MOZ_ASSERT(shadow1.GetUnit() == eCSSUnit_Array, "wrong unit"); + MOZ_ASSERT(shadow2.GetUnit() == eCSSUnit_Array, "wrong unit"); + const nsCSSValue::Array* array1 = shadow1.GetArrayValue(); + const nsCSSValue::Array* array2 = shadow2.GetArrayValue(); + double squareDistance = 0.0; + + // X, Y, Radius, Spread + for (size_t i = 0; i < 4; ++i) { + MOZ_ASSERT(array1->Item(i).GetUnit() == eCSSUnit_Pixel, + "unexpected unit"); + MOZ_ASSERT(array2->Item(i).GetUnit() == eCSSUnit_Pixel, + "unexpected unit"); + double diff = array1->Item(i).GetFloatValue() - + array2->Item(i).GetFloatValue(); + squareDistance += diff * diff; + } + + // Color, Inset + const nsCSSValue& colorValue1 = array1->Item(4); + const nsCSSValue& colorValue2 = array2->Item(4); + const nsCSSValue& inset1 = array1->Item(5); + const nsCSSValue& inset2 = array2->Item(5); + if ((colorValue1.GetUnit() != colorValue2.GetUnit() && + (!colorValue1.IsNumericColorUnit() || + !colorValue2.IsNumericColorUnit())) || + inset1.GetUnit() != inset2.GetUnit()) { + // We don't know how to animate between color and no-color, or + // between inset and not-inset. + // NOTE: In case when both colors' units are eCSSUnit_Null, that means + // neither color value was specified, so we can interpolate. + return false; + } + + if (colorValue1.GetUnit() != eCSSUnit_Null) { + double diff = + StyleAnimationValue::ComputeColorDistance(ExtractColor(colorValue1), + ExtractColor(colorValue2)); + squareDistance += diff * diff; + } + aSquareDistance = squareDistance; break; + } default: MOZ_ASSERT_UNREACHABLE("unknown filter function"); return false;