#include "UnitBezier.h"
#include <wtf/CurrentTime.h>
-
-#ifdef DEBUG
-
#include <cutils/log.h>
#include <wtf/text/CString.h>
+#undef XLOGC
+#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "AndroidAnimation", __VA_ARGS__)
+
+#ifdef DEBUG
+
#undef XLOG
#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "AndroidAnimation", __VA_ARGS__)
double beginTime)
: m_beginTime(beginTime)
, m_duration(animation->duration())
- , m_finished(false)
+ , m_fillsBackwards(animation->fillsBackwards())
+ , m_fillsForwards(animation->fillsForwards())
, m_iterationCount(animation->iterationCount())
, m_direction(animation->direction())
, m_timingFunction(animation->timingFunction())
, m_type(type)
, m_operations(operations)
- , m_originalLayer(0)
{
ASSERT(m_timingFunction);
AndroidAnimation::AndroidAnimation(AndroidAnimation* anim)
: m_beginTime(anim->m_beginTime)
, m_duration(anim->m_duration)
- , m_finished(anim->m_finished)
+ , m_fillsBackwards(anim->m_fillsBackwards)
+ , m_fillsForwards(anim->m_fillsForwards)
, m_iterationCount(anim->m_iterationCount)
, m_direction(anim->m_direction)
, m_timingFunction(anim->m_timingFunction)
, m_name(anim->name())
, m_type(anim->m_type)
, m_operations(anim->m_operations)
- , m_originalLayer(0)
{
gDebugAndroidAnimationInstances++;
}
return fractionalTime;
}
+bool AndroidAnimation::evaluate(LayerAndroid* layer, double time)
+{
+ float progress;
+ if (!checkIterationsAndProgress(time, &progress)
+ && !(m_fillsBackwards || m_fillsForwards))
+ return false;
+
+ if (progress < 0) {
+ // The animation hasn't started yet
+ if (m_fillsBackwards) {
+ // in this case we want to apply the initial keyframe to the layer
+ applyForProgress(layer, 0);
+ }
+ // we still want to be evaluated until we get progress > 0
+ return true;
+ }
+
+ if (progress >= 1) {
+ if (!m_fillsForwards)
+ return false;
+ progress = 1;
+ }
+
+ if (!m_operations->size())
+ return false;
+
+ applyForProgress(layer, progress);
+
+ return true;
+}
+
PassRefPtr<AndroidOpacityAnimation> AndroidOpacityAnimation::create(
const Animation* animation,
KeyframeValueList* operations,
*end = foundAt;
}
-bool AndroidOpacityAnimation::evaluate(LayerAndroid* layer, double time)
+void AndroidOpacityAnimation::applyForProgress(LayerAndroid* layer, float progress)
{
- float progress;
- if (!checkIterationsAndProgress(time, &progress))
- return false;
-
- if (progress < 0) // we still want to be evaluated until we get progress > 0
- return true;
-
- if (progress >= 1) {
- m_finished = true;
- if (layer != m_originalLayer)
- return false;
- }
-
- if (!m_originalLayer)
- m_originalLayer = layer;
-
// First, we need to get the from and to values
-
int from, to;
pickValues(progress, &from, &to);
FloatAnimationValue* fromValue = (FloatAnimationValue*) m_operations->at(from);
const TimingFunction* timingFunction = fromValue->timingFunction();
progress = applyTimingFunction(fromValue->keyTime(), toValue->keyTime(),
progress, timingFunction);
- float value = fromValue->value() + ((toValue->value() - fromValue->value()) * progress);
- layer->setOpacity(value);
- XLOG("AndroidOpacityAnimation::evaluate(%p, %p, %.2f) value=%.6f", this, layer, time, value);
+ float value = fromValue->value() + ((toValue->value() - fromValue->value()) * progress);
- return true;
+ layer->setOpacity(value);
}
PassRefPtr<AndroidTransformAnimation> AndroidTransformAnimation::create(
return adoptRef(new AndroidTransformAnimation(this));
}
-bool AndroidTransformAnimation::evaluate(LayerAndroid* layer, double time)
+void AndroidTransformAnimation::applyForProgress(LayerAndroid* layer, float progress)
{
- float progress;
- bool ret = true;
- if (!checkIterationsAndProgress(time, &progress)) {
- m_finished = true;
- ret = false;
- }
-
- if (progress < 0) // we still want to be evaluated until we get progress > 0
- return true;
-
- if (progress >= 1) {
- m_finished = true;
- if (layer != m_originalLayer)
- return false;
- }
-
- if (!m_originalLayer)
- m_originalLayer = layer;
-
- IntSize size(layer->getSize().width(), layer->getSize().height());
- TransformationMatrix matrix;
- XLOG("Evaluate transforms animations, %d operations, progress %.2f for layer %d (%d, %d)"
- , m_operations->size(), progress, layer->uniqueId(), size.width(), size.height());
-
- if (!m_operations->size())
- return false;
-
// First, we need to get the from and to values
-
int from, to;
pickValues(progress, &from, &to);
+
TransformAnimationValue* fromValue = (TransformAnimationValue*) m_operations->at(from);
TransformAnimationValue* toValue = (TransformAnimationValue*) m_operations->at(to);
}
}
+ IntSize size(layer->getSize().width(), layer->getSize().height());
if (valid) {
for (size_t i = 0; i < toValue->value()->size(); ++i)
toValue->value()->operations()[i]->blend(fromValue->value()->at(i),
// Set the final transform on the layer
layer->setTransform(transformMatrix);
-
- return ret;
}
} // namespace WebCore
bool checkIterationsAndProgress(double time, float* finalProgress);
double applyTimingFunction(float from, float to, double progress,
const TimingFunction* timingFunction);
- virtual bool evaluate(LayerAndroid* layer, double time) = 0;
+ bool evaluate(LayerAndroid* layer, double time);
+ virtual void applyForProgress(LayerAndroid* layer, float progress) = 0;
static long instancesCount();
void setName(const String& name) { m_name = name; }
String name() { return m_name; }
AnimatedPropertyID type() { return m_type; }
- bool finished() { return m_finished; }
+ bool fillsBackwards() { return m_fillsBackwards; }
+ bool fillsForwards() { return m_fillsForwards; }
+
protected:
double m_beginTime;
double m_elapsedTime;
double m_duration;
- bool m_finished;
+ bool m_fillsBackwards;
+ bool m_fillsForwards;
int m_iterationCount;
int m_direction;
RefPtr<TimingFunction> m_timingFunction;
String m_name;
AnimatedPropertyID m_type;
KeyframeValueList* m_operations;
- LayerAndroid* m_originalLayer;
};
class AndroidOpacityAnimation : public AndroidAnimation {
AndroidOpacityAnimation(AndroidOpacityAnimation* anim);
virtual PassRefPtr<AndroidAnimation> copy();
- virtual bool evaluate(LayerAndroid* layer, double time);
+ virtual void applyForProgress(LayerAndroid* layer, float progress);
};
class AndroidTransformAnimation : public AndroidAnimation {
AndroidTransformAnimation(AndroidTransformAnimation* anim);
virtual PassRefPtr<AndroidAnimation> copy();
- virtual bool evaluate(LayerAndroid* layer, double time);
+ virtual void applyForProgress(LayerAndroid* layer, float progress);
};
} // namespace WebCore