lottie: code refactoring++

improved readability and maintenance by separating
the path modifier from the default path operation.
This commit is contained in:
Hermet Park 2025-01-29 18:33:27 +09:00 committed by Hermet Park
parent f8da536d1a
commit 6a7e6966c3

View file

@ -445,19 +445,9 @@ struct LottiePathSet : LottieProperty
return (*frames)[frames->count]; return (*frames)[frames->count];
} }
bool operator()(float frameNo, Array<PathCommand>& cmds, Array<Point>& pts, Matrix* transform, const LottieRoundnessModifier* roundness, const LottieOffsetModifier* offset, LottieExpressions* exps = nullptr) //return false means requiring the interpolation
bool dispatch(float frameNo, PathSet*& path, LottieScalarFrame<PathSet>*& frame, float& t)
{ {
//overriding with expressions
if (exps && exp) {
frameNo = _loop(frames, frameNo, exp);
if (exps->result<LottiePathSet>(frameNo, cmds, pts, transform, roundness, offset, exp)) return true;
}
PathSet* path = nullptr;
LottieScalarFrame<PathSet>* frame = nullptr;
float t;
bool interpolate = false;
if (!frames) path = &value; if (!frames) path = &value;
else if (frames->count == 1 || frameNo <= frames->first().no) path = &frames->first().value; else if (frames->count == 1 || frameNo <= frames->first().no) path = &frames->first().value;
else if (frameNo >= frames->last().no) path = &frames->last().value; else if (frameNo >= frames->last().no) path = &frames->last().value;
@ -471,15 +461,25 @@ struct LottiePathSet : LottieProperty
t = (frameNo - frame->no) / ((frame + 1)->no - frame->no); t = (frameNo - frame->no) / ((frame + 1)->no - frame->no);
if (frame->interpolator) t = frame->interpolator->progress(t); if (frame->interpolator) t = frame->interpolator->progress(t);
if (frame->hold) path = &(frame + ((t < 1.0f) ? 0 : 1))->value; if (frame->hold) path = &(frame + ((t < 1.0f) ? 0 : 1))->value;
else interpolate = true; else return false;
} }
} }
return true;
}
if (!interpolate) { bool modifiedPath(float frameNo, Array<PathCommand>& cmds, Array<Point>& pts, Matrix* transform, const LottieRoundnessModifier* roundness, const LottieOffsetModifier* offset)
{
PathSet* path;
LottieScalarFrame<PathSet>* frame;
Array<PathCommand> cmds1;
Array<Point> pts1;
float t;
if (dispatch(frameNo, path, frame, t)) {
if (roundness) { if (roundness) {
if (offset) { if (offset) {
Array<PathCommand> cmds1(path->cmdsCnt); cmds1 = Array<PathCommand>(path->cmdsCnt);
Array<Point> pts1(path->ptsCnt); pts1 = Array<Point>(path->ptsCnt);
roundness->modifyPath(path->cmds, path->cmdsCnt, path->pts, path->ptsCnt, cmds1, pts1, transform); roundness->modifyPath(path->cmds, path->cmdsCnt, path->pts, path->ptsCnt, cmds1, pts1, transform);
return offset->modifyPath(cmds1.data, cmds1.count, pts1.data, pts1.count, cmds, pts); return offset->modifyPath(cmds1.data, cmds1.count, pts1.data, pts1.count, cmds, pts);
} }
@ -492,21 +492,12 @@ struct LottiePathSet : LottieProperty
return true; return true;
} }
//interpolate 2 frames
auto s = frame->value.pts; auto s = frame->value.pts;
auto e = (frame + 1)->value.pts; auto e = (frame + 1)->value.pts;
if (!roundness && !offset) {
for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e) {
auto pt = lerp(*s, *e, t);
if (transform) pt *= *transform;
pts.push(pt);
}
_copy(&frame->value, cmds);
return true;
}
auto interpPts = (Point*)malloc(frame->value.ptsCnt * sizeof(Point)); auto interpPts = (Point*)malloc(frame->value.ptsCnt * sizeof(Point));
auto p = interpPts; auto p = interpPts;
for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e, ++p) { for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e, ++p) {
*p = lerp(*s, *e, t); *p = lerp(*s, *e, t);
if (transform) *p *= *transform; if (transform) *p *= *transform;
@ -514,8 +505,6 @@ struct LottiePathSet : LottieProperty
if (roundness) { if (roundness) {
if (offset) { if (offset) {
Array<PathCommand> cmds1;
Array<Point> pts1;
roundness->modifyPath(frame->value.cmds, frame->value.cmdsCnt, interpPts, frame->value.ptsCnt, cmds1, pts1, nullptr); roundness->modifyPath(frame->value.cmds, frame->value.cmdsCnt, interpPts, frame->value.ptsCnt, cmds1, pts1, nullptr);
offset->modifyPath(cmds1.data, cmds1.count, pts1.data, pts1.count, cmds, pts); offset->modifyPath(cmds1.data, cmds1.count, pts1.data, pts1.count, cmds, pts);
} else roundness->modifyPath(frame->value.cmds, frame->value.cmdsCnt, interpPts, frame->value.ptsCnt, cmds, pts, nullptr); } else roundness->modifyPath(frame->value.cmds, frame->value.cmdsCnt, interpPts, frame->value.ptsCnt, cmds, pts, nullptr);
@ -526,6 +515,43 @@ struct LottiePathSet : LottieProperty
return true; return true;
} }
bool defaultPath(float frameNo, Array<PathCommand>& cmds, Array<Point>& pts, Matrix* transform)
{
PathSet* path;
LottieScalarFrame<PathSet>* frame;
float t;
if (dispatch(frameNo, path, frame, t)) {
_copy(path, cmds);
_copy(path, pts, transform);
return true;
}
//interpolate 2 frames
auto s = frame->value.pts;
auto e = (frame + 1)->value.pts;
for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e) {
auto pt = lerp(*s, *e, t);
if (transform) pt *= *transform;
pts.push(pt);
}
_copy(&frame->value, cmds);
return true;
}
bool operator()(float frameNo, Array<PathCommand>& cmds, Array<Point>& pts, Matrix* transform, const LottieRoundnessModifier* roundness, const LottieOffsetModifier* offset, LottieExpressions* exps = nullptr)
{
//overriding with expressions
if (exps && exp) {
frameNo = _loop(frames, frameNo, exp);
if (exps->result<LottiePathSet>(frameNo, cmds, pts, transform, roundness, offset, exp)) return true;
}
if (roundness || offset) return modifiedPath(frameNo, cmds, pts, transform, roundness, offset);
else return defaultPath(frameNo, cmds, pts, transform);
}
void prepare() {} void prepare() {}
}; };