Bug 1272549 - Part 9: Compute distance for mismatched transform lists. r=birtles

MozReview-Commit-ID: JJWcMgj88GX

--HG--
extra : rebase_source : 3f1c314a2bf9c7c12991fb3873738c79b0152ea9
This commit is contained in:
Boris Chiou 2016-10-05 15:36:16 +08:00
parent 6ce1d75c7f
commit 304026cd9d
9 changed files with 74 additions and 17 deletions

View File

@ -291,7 +291,7 @@ KeyframeEffectReadOnly::UpdateProperties(nsStyleContext* aStyleContext)
if (mEffectOptions.mSpacingMode == SpacingMode::paced) {
KeyframeUtils::ApplySpacing(keyframesCopy, SpacingMode::paced,
mEffectOptions.mPacedProperty,
computedValues);
computedValues, aStyleContext);
}
properties =

View File

@ -417,7 +417,8 @@ PaceRange(const Range<Keyframe>& aKeyframes,
static nsTArray<double>
GetCumulativeDistances(const nsTArray<ComputedKeyframeValues>& aValues,
nsCSSPropertyID aProperty);
nsCSSPropertyID aProperty,
nsStyleContext* aStyleContext);
// ------------------------------------------------------------------
//
@ -481,7 +482,8 @@ KeyframeUtils::GetKeyframesFromObject(JSContext* aCx,
KeyframeUtils::ApplySpacing(nsTArray<Keyframe>& aKeyframes,
SpacingMode aSpacingMode,
nsCSSPropertyID aProperty,
nsTArray<ComputedKeyframeValues>& aComputedValues)
nsTArray<ComputedKeyframeValues>& aComputedValues,
nsStyleContext* aStyleContext)
{
if (aKeyframes.IsEmpty()) {
return;
@ -492,7 +494,8 @@ KeyframeUtils::ApplySpacing(nsTArray<Keyframe>& aKeyframes,
MOZ_ASSERT(IsAnimatableProperty(aProperty),
"Paced property should be animatable");
cumulativeDistances = GetCumulativeDistances(aComputedValues, aProperty);
cumulativeDistances = GetCumulativeDistances(aComputedValues, aProperty,
aStyleContext);
// Reset the computed offsets if using paced spacing.
for (Keyframe& keyframe : aKeyframes) {
keyframe.mComputedOffset = Keyframe::kComputedOffsetNotSet;
@ -583,7 +586,7 @@ KeyframeUtils::ApplyDistributeSpacing(nsTArray<Keyframe>& aKeyframes)
{
nsTArray<ComputedKeyframeValues> emptyArray;
ApplySpacing(aKeyframes, SpacingMode::distribute, eCSSProperty_UNKNOWN,
emptyArray);
emptyArray, nullptr);
}
/* static */ nsTArray<ComputedKeyframeValues>
@ -1561,12 +1564,14 @@ PaceRange(const Range<Keyframe>& aKeyframes,
*
* @param aValues The computed values returned by GetComputedKeyframeValues.
* @param aPacedProperty The paced property.
* @param aStyleContext The style context for computing distance on transform.
* @return The cumulative distances for the paced property. The length will be
* the same as aValues.
*/
static nsTArray<double>
GetCumulativeDistances(const nsTArray<ComputedKeyframeValues>& aValues,
nsCSSPropertyID aPacedProperty)
nsCSSPropertyID aPacedProperty,
nsStyleContext* aStyleContext)
{
// a) If aPacedProperty is a shorthand property, get its components.
// Otherwise, just add the longhand property into the set.
@ -1634,6 +1639,7 @@ GetCumulativeDistances(const nsTArray<ComputedKeyframeValues>& aValues,
prop,
prevPacedValues[propIdx].mValue,
pacedValues[propIdx].mValue,
aStyleContext,
componentDistance)) {
dist += componentDistance * componentDistance;
}
@ -1647,6 +1653,7 @@ GetCumulativeDistances(const nsTArray<ComputedKeyframeValues>& aValues,
StyleAnimationValue::ComputeDistance(aPacedProperty,
prevPacedValues[0].mValue,
pacedValues[0].mValue,
aStyleContext,
dist);
}
cumulativeDistances[i] = cumulativeDistances[preIdx] + dist;

View File

@ -98,11 +98,14 @@ public:
* GetComputedKeyframeValues. Only used when |aSpacingMode| is
* SpacingMode::paced. In all other cases this parameter is unused and may
* be any value including an empty array.
* @param aStyleContext The style context used for calculating paced spacing
* on transform.
*/
static void ApplySpacing(nsTArray<Keyframe>& aKeyframes,
SpacingMode aSpacingMode,
nsCSSPropertyID aProperty,
nsTArray<ComputedKeyframeValues>& aComputedValues);
nsTArray<ComputedKeyframeValues>& aComputedValues,
nsStyleContext* aStyleContext);
/**
* Wrapper for ApplySpacing to simplify using distribute spacing.

View File

@ -2703,13 +2703,19 @@ nsDOMWindowUtils::ComputeAnimationDistance(nsIDOMElement* aElement,
"should not have shorthand");
StyleAnimationValue v1, v2;
Element* element = content->AsElement();
if (property == eCSSProperty_UNKNOWN ||
!ComputeAnimationValue(property, content->AsElement(), aValue1, v1) ||
!ComputeAnimationValue(property, content->AsElement(), aValue2, v2)) {
!ComputeAnimationValue(property, element, aValue1, v1) ||
!ComputeAnimationValue(property, element, aValue2, v2)) {
return NS_ERROR_ILLEGAL_VALUE;
}
if (!StyleAnimationValue::ComputeDistance(property, v1, v2, *aResult)) {
nsIPresShell* shell = element->GetUncomposedDoc()->GetShell();
RefPtr<nsStyleContext> styleContext = shell
? nsComputedDOMStyle::GetStyleContextForElement(element, nullptr, shell)
: nullptr;
if (!StyleAnimationValue::ComputeDistance(property, v1, v2, styleContext,
*aResult)) {
return NS_ERROR_FAILURE;
}

View File

@ -278,6 +278,7 @@ nsSMILCSSValueType::ComputeDistance(const nsSMILValue& aFrom,
return StyleAnimationValue::ComputeDistance(toWrapper->mPropID,
*fromCSSValue, *toCSSValue,
nullptr,
aDistance) ?
NS_OK : NS_ERROR_FAILURE;
}

View File

@ -998,10 +998,45 @@ ComputeTransformListDistance(const nsCSSValueList* aList1,
return sqrt(distance);
}
static double
ComputeMismatchedTransfromListDistance(const nsCSSValueList* aList1,
const nsCSSValueList* aList2,
nsStyleContext* aStyleContext)
{
// We need nsStyleContext and nsPresContext to compute calc() values while
// processing the translate part of transforms.
if (!aStyleContext) {
return 0.0;
}
RuleNodeCacheConditions dontCare;
bool dontCareBool;
nsStyleTransformMatrix::TransformReferenceBox emptyRefBox;
Matrix4x4 m1 = nsStyleTransformMatrix::ReadTransforms(
aList1,
aStyleContext,
aStyleContext->PresContext(),
dontCare,
emptyRefBox,
nsPresContext::AppUnitsPerCSSPixel(),
&dontCareBool);
Matrix4x4 m2 = nsStyleTransformMatrix::ReadTransforms(
aList2,
aStyleContext,
aStyleContext->PresContext(),
dontCare,
emptyRefBox,
nsPresContext::AppUnitsPerCSSPixel(),
&dontCareBool);
return sqrt(ComputeTransform3DMatrixDistance(m1, m2));
}
bool
StyleAnimationValue::ComputeDistance(nsCSSPropertyID aProperty,
const StyleAnimationValue& aStartValue,
const StyleAnimationValue& aEndValue,
nsStyleContext* aStyleContext,
double& aDistance)
{
Unit commonUnit =
@ -1415,13 +1450,11 @@ StyleAnimationValue::ComputeDistance(nsCSSPropertyID aProperty,
if (item1 || item2) {
// Either the transform function types don't match or
// the lengths don't match.
// TODO: Implement this for mismatched transform function in the later
// patch.
aDistance = 0.0;
return false;
aDistance =
ComputeMismatchedTransfromListDistance(list1, list2, aStyleContext);
} else {
aDistance = ComputeTransformListDistance(list1, list2);
}
aDistance = ComputeTransformListDistance(list1, list2);
}
return true;
}

View File

@ -87,6 +87,8 @@ public:
* should be calculated.
* @param aEndValue The end of the interval for which the distance
* should be calculated.
* @param aStyleContext The style context to use for processing the
* translate part of transforms.
* @param aDistance The result of the calculation.
* @return true on success, false on failure.
*/
@ -94,6 +96,7 @@ public:
ComputeDistance(nsCSSPropertyID aProperty,
const StyleAnimationValue& aStartValue,
const StyleAnimationValue& aEndValue,
nsStyleContext* aStyleContext,
double& aDistance);
/**

View File

@ -177,7 +177,7 @@ ProcessTranslatePart(const nsCSSValue& aValue,
nsPresContext::AppUnitsPerCSSPixel());
// We want to avoid calling aDimensionGetter if there's no percentage to be
// resolved (for performance reasons - see TransformReferenceBox).
if (percent != 0.0f && aRefBox) {
if (percent != 0.0f && aRefBox && !aRefBox->IsEmpty()) {
translation += percent *
NSAppUnitsToFloatPixels((aRefBox->*aDimensionGetter)(),
nsPresContext::AppUnitsPerCSSPixel());

View File

@ -110,6 +110,10 @@ namespace nsStyleTransformMatrix {
return mHeight;
}
bool IsEmpty() {
return !mFrame;
}
private:
// We don't really need to prevent copying, but since none of our consumers
// currently need to copy, preventing copying may allow us to catch some