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(); } }
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; }
PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(const TimingFunction* timefunc) { switch (timefunc->type()) { case TimingFunction::LinearFunction: { const LinearTimingFunction* linear = toLinearTimingFunction(timefunc); return reverse(linear); } case TimingFunction::CubicBezierFunction: { const CubicBezierTimingFunction* cubic = toCubicBezierTimingFunction(timefunc); return reverse(cubic); } case TimingFunction::ChainedFunction: { const ChainedTimingFunction* chained = toChainedTimingFunction(timefunc); return reverse(chained); } // Steps function can not be reversed. case TimingFunction::StepsFunction: default: ASSERT_NOT_REACHED(); return PassRefPtr<TimingFunction>(); } }
// Like in the PrintTo case, 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); } case TimingFunction::ChainedFunction: { const ChainedTimingFunction& chained = toChainedTimingFunction(lhs); return (chained == rhs); } default: ASSERT_NOT_REACHED(); } return false; }