void Layer::SetAnimations(const AnimationArray& aAnimations) { mAnimations = aAnimations; mAnimationData.Clear(); for (uint32_t i = 0; i < mAnimations.Length(); i++) { AnimData* data = mAnimationData.AppendElement(); InfallibleTArray<nsAutoPtr<css::ComputedTimingFunction> >& functions = data->mFunctions; nsTArray<AnimationSegment> segments = mAnimations.ElementAt(i).segments(); for (uint32_t j = 0; j < segments.Length(); j++) { TimingFunction tf = segments.ElementAt(j).sampleFn(); css::ComputedTimingFunction* ctf = new css::ComputedTimingFunction(); switch (tf.type()) { case TimingFunction::TCubicBezierFunction: { CubicBezierFunction cbf = tf.get_CubicBezierFunction(); ctf->Init(nsTimingFunction(cbf.x1(), cbf.y1(), cbf.x2(), cbf.y2())); break; } default: { NS_ASSERTION(tf.type() == TimingFunction::TStepFunction, "Function must be bezier or step"); StepFunction sf = tf.get_StepFunction(); nsTimingFunction::Type type = sf.type() == 1 ? nsTimingFunction::StepStart : nsTimingFunction::StepEnd; ctf->Init(nsTimingFunction(type, sf.steps())); break; } } functions.AppendElement(ctf); } // Precompute the nsStyleAnimation::Values that we need if this is a transform // animation. InfallibleTArray<nsStyleAnimation::Value>& startValues = data->mStartValues; InfallibleTArray<nsStyleAnimation::Value>& endValues = data->mEndValues; for (uint32_t j = 0; j < mAnimations[i].segments().Length(); j++) { const AnimationSegment& segment = mAnimations[i].segments()[j]; nsStyleAnimation::Value* startValue = startValues.AppendElement(); nsStyleAnimation::Value* endValue = endValues.AppendElement(); if (segment.endState().type() == Animatable::TArrayOfTransformFunction) { const InfallibleTArray<TransformFunction>& startFunctions = segment.startState().get_ArrayOfTransformFunction(); startValue->SetAndAdoptCSSValueListValue(CreateCSSValueList(startFunctions), nsStyleAnimation::eUnit_Transform); const InfallibleTArray<TransformFunction>& endFunctions = segment.endState().get_ArrayOfTransformFunction(); endValue->SetAndAdoptCSSValueListValue(CreateCSSValueList(endFunctions), nsStyleAnimation::eUnit_Transform); } else { NS_ASSERTION(segment.endState().type() == Animatable::Tfloat, "Unknown Animatable type"); startValue->SetFloatValue(segment.startState().get_float()); endValue->SetFloatValue(segment.endState().get_float()); } } } Mutated(); }
void CompositorAnimationsImpl::addKeyframesToCurve(blink::WebAnimationCurve& curve, const KeyframeVector& keyframes, const TimingFunction& timingFunction) { for (size_t i = 0; i < keyframes.size(); i++) { const TimingFunction* keyframeTimingFunction = 0; if (i + 1 < keyframes.size()) { // Last keyframe has no timing function switch (timingFunction.type()) { case TimingFunction::LinearFunction: case TimingFunction::CubicBezierFunction: keyframeTimingFunction = &timingFunction; break; case TimingFunction::ChainedFunction: { const ChainedTimingFunction& chained = toChainedTimingFunction(timingFunction); // ChainedTimingFunction criteria was checked in isCandidate, // assert it is valid. ASSERT(keyframes.size() == chained.m_segments.size() + 1); keyframeTimingFunction = chained.m_segments[i].m_timingFunction.get(); break; } case TimingFunction::StepsFunction: default: ASSERT_NOT_REACHED(); } } ASSERT(!keyframes[i]->value()->dependsOnUnderlyingValue()); RefPtr<AnimatableValue> value = keyframes[i]->value()->compositeOnto(0); switch (curve.type()) { case blink::WebAnimationCurve::AnimationCurveTypeFilter: { OwnPtr<blink::WebFilterOperations> ops = adoptPtr(blink::Platform::current()->compositorSupport()->createFilterOperations()); bool converted = toWebFilterOperations(toAnimatableFilterOperations(value.get())->operations(), ops.get()); ASSERT_UNUSED(converted, converted); blink::WebFilterKeyframe filterKeyframe(keyframes[i]->offset(), ops.release()); blink::WebFilterAnimationCurve* filterCurve = static_cast<blink::WebFilterAnimationCurve*>(&curve); addKeyframeWithTimingFunction(*filterCurve, filterKeyframe, keyframeTimingFunction); break; } case blink::WebAnimationCurve::AnimationCurveTypeFloat: { blink::WebFloatKeyframe floatKeyframe(keyframes[i]->offset(), toAnimatableDouble(value.get())->toDouble()); blink::WebFloatAnimationCurve* floatCurve = static_cast<blink::WebFloatAnimationCurve*>(&curve); addKeyframeWithTimingFunction(*floatCurve, floatKeyframe, keyframeTimingFunction); break; } case blink::WebAnimationCurve::AnimationCurveTypeTransform: { OwnPtr<blink::WebTransformOperations> ops = adoptPtr(blink::Platform::current()->compositorSupport()->createTransformOperations()); toWebTransformOperations(toAnimatableTransform(value.get())->transformOperations(), FloatSize(), ops.get()); blink::WebTransformKeyframe transformKeyframe(keyframes[i]->offset(), ops.release()); blink::WebTransformAnimationCurve* transformCurve = static_cast<blink::WebTransformAnimationCurve*>(&curve); addKeyframeWithTimingFunction(*transformCurve, transformKeyframe, keyframeTimingFunction); break; } default: ASSERT_NOT_REACHED(); } } }
// The generic PrintTo *must* come after the non-generic PrintTo otherwise it // will end up calling itself. void PrintTo(const TimingFunction& timingFunction, ::std::ostream* os) { switch (timingFunction.type()) { case TimingFunction::LinearFunction: { const LinearTimingFunction& linear = toLinearTimingFunction(timingFunction); PrintTo(linear, os); return; } case TimingFunction::CubicBezierFunction: { const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(timingFunction); PrintTo(cubic, os); return; } case TimingFunction::StepsFunction: { const StepsTimingFunction& step = toStepsTimingFunction(timingFunction); PrintTo(step, os); return; } case TimingFunction::ChainedFunction: { const ChainedTimingFunction& chained = toChainedTimingFunction(timingFunction); PrintTo(chained, os); return; } default: ASSERT_NOT_REACHED(); } }
bool operator==(const StepsTimingFunction& lhs, const TimingFunction& rhs) { if (rhs.type() != TimingFunction::StepsFunction) return false; const StepsTimingFunction& stf = toStepsTimingFunction(rhs); return (lhs.numberOfSteps() == stf.numberOfSteps()) && (lhs.stepAtPosition() == stf.stepAtPosition()); }
static PassRefPtr<TimingFunction> generateTimingFunction(const KeyframeEffectModel::KeyframeVector keyframes, const HashMap<double, RefPtr<TimingFunction> > perKeyframeTimingFunctions) { // Generate the chained timing function. Note that timing functions apply // from the keyframe in which they're specified to the next keyframe. bool isTimingFunctionLinearThroughout = true; RefPtr<ChainedTimingFunction> chainedTimingFunction = ChainedTimingFunction::create(); for (size_t i = 0; i < keyframes.size() - 1; ++i) { double lowerBound = keyframes[i]->offset(); ASSERT(lowerBound >=0 && lowerBound < 1); double upperBound = keyframes[i + 1]->offset(); ASSERT(upperBound > 0 && upperBound <= 1); TimingFunction* timingFunction = perKeyframeTimingFunctions.get(lowerBound); isTimingFunctionLinearThroughout &= timingFunction->type() == TimingFunction::LinearFunction; chainedTimingFunction->appendSegment(upperBound, timingFunction); } if (isTimingFunctionLinearThroughout) return LinearTimingFunction::create(); return chainedTimingFunction; }
bool operator==(const StepsTimingFunction& lhs, const TimingFunction& rhs) { if (rhs.type() != TimingFunction::StepsFunction) return false; const StepsTimingFunction& stf = toStepsTimingFunction(rhs); if ((lhs.subType() == StepsTimingFunction::Custom) && (stf.subType() == StepsTimingFunction::Custom)) return (lhs.numberOfSteps() == stf.numberOfSteps()) && (lhs.stepAtStart() == stf.stepAtStart()); return lhs.subType() == stf.subType(); }
bool operator==(const CubicBezierTimingFunction& lhs, const TimingFunction& rhs) { if (rhs.type() != TimingFunction::CubicBezierFunction) return false; const CubicBezierTimingFunction& ctf = toCubicBezierTimingFunction(rhs); if ((lhs.subType() == CubicBezierTimingFunction::Custom) && (ctf.subType() == CubicBezierTimingFunction::Custom)) return (lhs.x1() == ctf.x1()) && (lhs.y1() == ctf.y1()) && (lhs.x2() == ctf.x2()) && (lhs.y2() == ctf.y2()); return lhs.subType() == ctf.subType(); }
/* static */ Maybe<ComputedTimingFunction> AnimationUtils::TimingFunctionToComputedTimingFunction( const TimingFunction& aTimingFunction) { switch (aTimingFunction.type()) { case TimingFunction::Tnull_t: return Nothing(); case TimingFunction::TCubicBezierFunction: { CubicBezierFunction cbf = aTimingFunction.get_CubicBezierFunction(); return Some(ComputedTimingFunction::CubicBezier(cbf.x1(), cbf.y1(), cbf.x2(), cbf.y2())); } case TimingFunction::TStepFunction: { StepFunction sf = aTimingFunction.get_StepFunction(); StyleStepPosition pos = static_cast<StyleStepPosition>(sf.type()); return Some(ComputedTimingFunction::Steps(sf.steps(), pos)); } default: MOZ_ASSERT_UNREACHABLE("Function must be null, bezier, step or frames"); break; } return Nothing(); }
static bool equals(const ChainedTimingFunction& lhs, const TimingFunction& rhs) { if (rhs.type() != TimingFunction::ChainedFunction) return false; if (&lhs == &rhs) return true; const ChainedTimingFunction& ctf = toChainedTimingFunction(rhs); if (lhs.m_segments.size() != ctf.m_segments.size()) return false; for (size_t i = 0; i < lhs.m_segments.size(); i++) { if (!equals(lhs.m_segments[i], ctf.m_segments[i])) return false; } return true; }
// The generic operator== *must* come after the // non-generic operator== otherwise it will end up calling itself. bool operator==(const TimingFunction& lhs, const TimingFunction& rhs) { switch (lhs.type()) { case TimingFunction::LinearFunction: { const LinearTimingFunction& linear = toLinearTimingFunction(lhs); return (linear == rhs); } case TimingFunction::CubicBezierFunction: { const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(lhs); return (cubic == rhs); } case TimingFunction::StepsFunction: { const StepsTimingFunction& step = toStepsTimingFunction(lhs); return (step == rhs); } default: ASSERT_NOT_REACHED(); } return false; }
bool operator==(const LinearTimingFunction& lhs, const TimingFunction& rhs) { return rhs.type() == TimingFunction::LinearFunction; }
void CompositorTransformAnimationCurve::setTimingFunction( const TimingFunction& timingFunction) { m_curve->SetTimingFunction(timingFunction.cloneToCC()); }