lottie: clean up code for maintenance

Point/Position is too ambuguous to classify,
Renamed them to LottieScalar and LottieVector,
and unify the duplicate logic among them.
This commit is contained in:
Hermet Park 2025-01-29 02:12:41 +09:00 committed by Hermet Park
parent c5ae9a5045
commit a67f90951c
4 changed files with 83 additions and 168 deletions

View file

@ -111,7 +111,7 @@ static jerry_value_t _value(float frameNo, LottieProperty* property)
switch (property->type) {
case LottieProperty::Type::Point: {
auto value = jerry_object();
auto pos = (*static_cast<LottiePoint*>(property))(frameNo);
auto pos = (*static_cast<LottieScalar*>(property))(frameNo);
auto val1 = jerry_number(pos.x);
auto val2 = jerry_number(pos.y);
jerry_object_set_index(value, 0, val1);
@ -133,7 +133,7 @@ static jerry_value_t _value(float frameNo, LottieProperty* property)
}
case LottieProperty::Type::Position: {
auto value = jerry_object();
auto pos = (*static_cast<LottiePosition*>(property))(frameNo);
auto pos = (*static_cast<LottieVector*>(property))(frameNo);
auto val1 = jerry_number(pos.x);
auto val2 = jerry_number(pos.y);
jerry_object_set_index(value, 0, val1);
@ -764,13 +764,13 @@ static jerry_value_t _velocityAtTime(const jerry_call_info_t* info, const jerry_
//compute the velocity
switch (exp->property->type) {
case LottieProperty::Type::Point: {
auto prv = (*static_cast<LottiePoint*>(exp->property))(pframe);
auto cur = (*static_cast<LottiePoint*>(exp->property))(cframe);
auto prv = (*static_cast<LottieScalar*>(exp->property))(pframe);
auto cur = (*static_cast<LottieScalar*>(exp->property))(cframe);
return _velocity(prv.x, cur.x, prv.y, cur.y, elapsed);
}
case LottieProperty::Type::Position: {
auto prv = (*static_cast<LottiePosition*>(exp->property))(pframe);
auto cur = (*static_cast<LottiePosition*>(exp->property))(cframe);
auto prv = (*static_cast<LottieVector*>(exp->property))(pframe);
auto cur = (*static_cast<LottieVector*>(exp->property))(cframe);
return _velocity(prv.x, cur.x, prv.y, cur.y, elapsed);
}
case LottieProperty::Type::Float: {
@ -800,13 +800,13 @@ static jerry_value_t _speedAtTime(const jerry_call_info_t* info, const jerry_val
//compute the velocity
switch (exp->property->type) {
case LottieProperty::Type::Point: {
prv = (*static_cast<LottiePoint*>(exp->property))(pframe);
cur = (*static_cast<LottiePoint*>(exp->property))(cframe);
prv = (*static_cast<LottieScalar*>(exp->property))(pframe);
cur = (*static_cast<LottieScalar*>(exp->property))(cframe);
break;
}
case LottieProperty::Type::Position: {
prv = (*static_cast<LottiePosition*>(exp->property))(pframe);
cur = (*static_cast<LottiePosition*>(exp->property))(cframe);
prv = (*static_cast<LottieVector*>(exp->property))(pframe);
cur = (*static_cast<LottieVector*>(exp->property))(cframe);
break;
}
default: {

View file

@ -60,12 +60,12 @@ void LottieSlot::assign(LottieObject* target, bool byDefault)
//backup the original properties before overwriting
switch (type) {
case LottieProperty::Type::Position: {
if (copy) pair->prop = new LottiePosition(static_cast<LottieTransform*>(pair->obj)->position);
if (copy) pair->prop = new LottieVector(static_cast<LottieTransform*>(pair->obj)->position);
pair->obj->override(&static_cast<LottieTransform*>(target)->position, shallow, byDefault);
break;
}
case LottieProperty::Type::Point: {
if (copy) pair->prop = new LottiePoint(static_cast<LottieTransform*>(pair->obj)->scale);
if (copy) pair->prop = new LottieScalar(static_cast<LottieTransform*>(pair->obj)->scale);
pair->obj->override(&static_cast<LottieTransform*>(target)->scale, shallow, byDefault);
break;
}

View file

@ -261,8 +261,8 @@ struct LottieTextRange
struct {
LottieColor fillColor = RGB24{255, 255, 255};
LottieColor strokeColor = RGB24{255, 255, 255};
LottiePosition position = Point{0, 0};
LottiePoint scale = Point{100, 100};
LottieVector position = Point{0, 0};
LottieScalar scale = Point{100, 100};
LottieFloat letterSpacing = 0.0f;
LottieFloat lineSpacing = 0.0f;
LottieFloat strokeWidth = 0.0f;
@ -328,7 +328,7 @@ struct LottieText : LottieObject, LottieRenderPooler<tvg::Shape>
{
enum Group : uint8_t { Chars = 1, Word = 2, Line = 3, All = 4 };
Group grouping = Chars;
LottiePoint anchor{};
LottieScalar anchor{};
} alignOption;
LottieText()
@ -452,8 +452,8 @@ struct LottieRect : LottieShape
return nullptr;
}
LottiePosition position = Point{0.0f, 0.0f};
LottiePoint size = Point{0.0f, 0.0f};
LottieVector position = Point{0.0f, 0.0f};
LottieScalar size = Point{0.0f, 0.0f};
LottieFloat radius = 0.0f; //rounded corner radius
};
@ -476,7 +476,7 @@ struct LottiePolyStar : LottieShape
return nullptr;
}
LottiePosition position = Point{0.0f, 0.0f};
LottieVector position = Point{0.0f, 0.0f};
LottieFloat innerRadius = 0.0f;
LottieFloat outerRadius = 0.0f;
LottieFloat innerRoundness = 0.0f;
@ -498,8 +498,8 @@ struct LottieEllipse : LottieShape
return nullptr;
}
LottiePosition position = Point{0.0f, 0.0f};
LottiePoint size = Point{0.0f, 0.0f};
LottieVector position = Point{0.0f, 0.0f};
LottieScalar size = Point{0.0f, 0.0f};
};
@ -555,7 +555,7 @@ struct LottieTransform : LottieObject
switch (prop->type) {
case LottieProperty::Type::Position: {
if (byDefault) position.release();
position.copy(*static_cast<LottiePosition*>(prop), shallow);
position.copy(*static_cast<LottieVector*>(prop), shallow);
break;
}
case LottieProperty::Type::Float: {
@ -565,7 +565,7 @@ struct LottieTransform : LottieObject
}
case LottieProperty::Type::Point: {
if (byDefault) scale.release();
scale.copy(*static_cast<LottiePoint*>(prop), shallow);
scale.copy(*static_cast<LottieScalar*>(prop), shallow);
break;
}
case LottieProperty::Type::Opacity: {
@ -577,10 +577,10 @@ struct LottieTransform : LottieObject
}
}
LottiePosition position = Point{0.0f, 0.0f};
LottieVector position = Point{0.0f, 0.0f};
LottieFloat rotation = 0.0f; //z rotation
LottiePoint scale = Point{100.0f, 100.0f};
LottiePoint anchor = Point{0.0f, 0.0f};
LottieScalar scale = Point{100.0f, 100.0f};
LottieScalar anchor = Point{0.0f, 0.0f};
LottieOpacity opacity = 255;
LottieFloat skewAngle = 0.0f;
LottieFloat skewAxis = 0.0f;
@ -692,8 +692,8 @@ struct LottieGradient : LottieObject
uint32_t populate(ColorStop& color, size_t count);
Fill* fill(float frameNo, LottieExpressions* exps);
LottiePoint start = Point{0.0f, 0.0f};
LottiePoint end = Point{0.0f, 0.0f};
LottieScalar start = Point{0.0f, 0.0f};
LottieScalar end = Point{0.0f, 0.0f};
LottieFloat height = 0.0f;
LottieFloat angle = 0.0f;
LottieOpacity opacity = 255;
@ -773,10 +773,10 @@ struct LottieRepeater : LottieObject
LottieFloat offset = 0.0f;
//Transform
LottiePosition position = Point{0.0f, 0.0f};
LottieVector position = Point{0.0f, 0.0f};
LottieFloat rotation = 0.0f;
LottiePoint scale = Point{100.0f, 100.0f};
LottiePoint anchor = Point{0.0f, 0.0f};
LottieScalar scale = Point{100.0f, 100.0f};
LottieScalar anchor = Point{0.0f, 0.0f};
LottieOpacity startOpacity = 255;
LottieOpacity endOpacity = 255;
bool inorder = true; //true: higher, false: lower

View file

@ -55,6 +55,15 @@ struct LottieScalarFrame
}
return lerp(value, next->value, t);
}
float angle(LottieScalarFrame* next, float frameNo)
{
return 0.0f;
}
void prepare(TVG_UNUSED LottieScalarFrame* next)
{
}
};
@ -253,17 +262,17 @@ float _loop(T* frames, float frameNo, LottieExpression* exp)
}
template<typename T>
template<typename Frame, typename Value, bool Scalar = 1>
struct LottieGenericProperty : LottieProperty
{
//Property has an either keyframes or single value.
Array<LottieScalarFrame<T>>* frames = nullptr;
T value;
Array<Frame>* frames = nullptr;
Value value;
LottieGenericProperty(T v) : value(v) {}
LottieGenericProperty(Value v) : value(v) {}
LottieGenericProperty() {}
LottieGenericProperty(const LottieGenericProperty<T>& rhs)
LottieGenericProperty(const LottieGenericProperty<Frame, Value>& rhs)
{
copy(rhs);
type = rhs.type;
@ -299,24 +308,24 @@ struct LottieGenericProperty : LottieProperty
return _frameNo(frames, key);
}
LottieScalarFrame<T>& newFrame()
Frame& newFrame()
{
if (!frames) frames = new Array<LottieScalarFrame<T>>;
if (!frames) frames = new Array<Frame>;
if (frames->count + 1 >= frames->reserved) {
auto old = frames->reserved;
frames->grow(frames->count + 2);
memset((void*)(frames->data + old), 0x00, sizeof(LottieScalarFrame<T>) * (frames->reserved - old));
memset((void*)(frames->data + old), 0x00, sizeof(Frame) * (frames->reserved - old));
}
++frames->count;
return frames->last();
}
LottieScalarFrame<T>& nextFrame()
Frame& nextFrame()
{
return (*frames)[frames->count];
}
T operator()(float frameNo)
Value operator()(float frameNo)
{
if (!frames) return value;
if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value;
@ -327,31 +336,51 @@ struct LottieGenericProperty : LottieProperty
return frame->interpolate(frame + 1, frameNo);
}
T operator()(float frameNo, LottieExpressions* exps)
Value operator()(float frameNo, LottieExpressions* exps)
{
if (exps && exp) {
T out{};
Value out{};
frameNo = _loop(frames, frameNo, exp);
if (exps->result<LottieGenericProperty<T>>(frameNo, out, exp)) return out;
if (exps->result<LottieGenericProperty<Frame, Value>>(frameNo, out, exp)) return out;
}
return operator()(frameNo);
}
void copy(const LottieGenericProperty<T>& rhs, bool shallow = true)
void copy(const LottieGenericProperty<Frame, Value, Scalar>& rhs, bool shallow = true)
{
if (rhs.frames) {
if (shallow) {
frames = rhs.frames;
const_cast<LottieGenericProperty<T>&>(rhs).frames = nullptr;
const_cast<LottieGenericProperty<Frame, Value, Scalar>&>(rhs).frames = nullptr;
} else {
frames = new Array<LottieScalarFrame<T>>;
frames = new Array<Frame>;
*frames = *rhs.frames;
}
} else value = rhs.value;
}
float angle(float frameNo) { return 0; }
void prepare() {}
float angle(float frameNo)
{
if (!frames || frames->count == 1) return 0;
if (frameNo <= frames->first().no) return frames->first().angle(frames->data + 1, frames->first().no);
if (frameNo >= frames->last().no) {
auto frame = frames->data + frames->count - 2;
return frame->angle(frame + 1, frames->last().no);
}
auto frame = frames->data + _bsearch(frames, frameNo);
return frame->angle(frame + 1, frameNo);
}
void prepare()
{
if (Scalar) return;
if (!frames || frames->count < 2) return;
for (auto frame = frames->begin() + 1; frame < frames->end(); ++frame) {
(frame - 1)->prepare(frame);
}
}
};
@ -649,121 +678,6 @@ struct LottieColorStop : LottieProperty
};
struct LottiePosition : LottieProperty
{
Array<LottieVectorFrame<Point>>* frames = nullptr;
Point value;
LottiePosition(Point v) : value(v)
{
}
~LottiePosition()
{
release();
}
void release()
{
delete(frames);
frames = nullptr;
if (exp) {
delete(exp);
exp = nullptr;
}
}
uint32_t nearest(float frameNo) override
{
return _nearest(frames, frameNo);
}
uint32_t frameCnt() override
{
return frames ? frames->count : 1;
}
float frameNo(int32_t key) override
{
return _frameNo(frames, key);
}
LottieVectorFrame<Point>& newFrame()
{
if (!frames) frames = new Array<LottieVectorFrame<Point>>;
if (frames->count + 1 >= frames->reserved) {
auto old = frames->reserved;
frames->grow(frames->count + 2);
memset((void*)(frames->data + old), 0x00, sizeof(LottieVectorFrame<Point>) * (frames->reserved - old));
}
++frames->count;
return frames->last();
}
LottieVectorFrame<Point>& nextFrame()
{
return (*frames)[frames->count];
}
Point operator()(float frameNo)
{
if (!frames) return value;
if (frames->count == 1 || frameNo <= frames->first().no) return frames->first().value;
if (frameNo >= frames->last().no) return frames->last().value;
auto frame = frames->data + _bsearch(frames, frameNo);
if (tvg::equal(frame->no, frameNo)) return frame->value;
return frame->interpolate(frame + 1, frameNo);
}
Point operator()(float frameNo, LottieExpressions* exps)
{
Point out{};
if (exps && exp) {
frameNo = _loop(frames, frameNo, exp);
if (exps->result<LottiePosition>(frameNo, out, exp)) return out;
}
return operator()(frameNo);
}
float angle(float frameNo)
{
if (!frames || frames->count == 1) return 0;
if (frameNo <= frames->first().no) return frames->first().angle(frames->data + 1, frames->first().no);
if (frameNo >= frames->last().no) {
auto frame = frames->data + frames->count - 2;
return frame->angle(frame + 1, frames->last().no);
}
auto frame = frames->data + _bsearch(frames, frameNo);
return frame->angle(frame + 1, frameNo);
}
void copy(const LottiePosition& rhs, bool shallow = true)
{
if (rhs.frames) {
if (shallow) {
frames = rhs.frames;
const_cast<LottiePosition&>(rhs).frames = nullptr;
} else {
frames = new Array<LottieVectorFrame<Point>>;
*frames = *rhs.frames;
}
} else value = rhs.value;
}
void prepare()
{
if (!frames || frames->count < 2) return;
for (auto frame = frames->begin() + 1; frame < frames->end(); ++frame) {
(frame - 1)->prepare(frame);
}
}
};
struct LottieTextDoc : LottieProperty
{
Array<LottieScalarFrame<TextDocument>>* frames = nullptr;
@ -929,10 +843,11 @@ struct LottieBitmap : LottieProperty
};
using LottiePoint = LottieGenericProperty<Point>;
using LottieFloat = LottieGenericProperty<float>;
using LottieOpacity = LottieGenericProperty<uint8_t>;
using LottieColor = LottieGenericProperty<RGB24>;
using LottieInteger = LottieGenericProperty<int8_t>;
using LottieScalar = LottieGenericProperty<LottieScalarFrame<Point>, Point>;
using LottieFloat = LottieGenericProperty<LottieScalarFrame<float>, float>;
using LottieOpacity = LottieGenericProperty<LottieScalarFrame<uint8_t>, uint8_t>;
using LottieColor = LottieGenericProperty<LottieScalarFrame<RGB24>, RGB24>;
using LottieInteger = LottieGenericProperty<LottieScalarFrame<int8_t>, int8_t>;
using LottieVector = LottieGenericProperty<LottieVectorFrame<Point>, Point, 0>;
#endif //_TVG_LOTTIE_PROPERTY_H_