diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index 65c93e9e..654419d0 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -233,7 +233,7 @@ static void _updateStroke(LottieStroke* stroke, float frameNo, RenderContext* ct } -static bool _fragmented(LottieGroup* parent, LottieObject** child, Inlist& contexts, RenderContext* ctx) +bool LottieBuilder::fragmented(LottieGroup* parent, LottieObject** child, Inlist& contexts, RenderContext* ctx) { if (!ctx->reqFragment) return false; if (ctx->fragmenting) return true; @@ -249,7 +249,7 @@ static bool _fragmented(LottieGroup* parent, LottieObject** child, Inlist& contexts, RenderContext* ctx) { - if (_fragmented(parent, child, contexts, ctx)) return; + if (fragmented(parent, child, contexts, ctx)) return; auto stroke = static_cast(*child); @@ -262,7 +262,7 @@ void LottieBuilder::updateSolidStroke(LottieGroup* parent, LottieObject** child, void LottieBuilder::updateGradientStroke(LottieGroup* parent, LottieObject** child, float frameNo, Inlist& contexts, RenderContext* ctx) { - if (_fragmented(parent, child, contexts, ctx)) return; + if (fragmented(parent, child, contexts, ctx)) return; auto stroke = static_cast(*child); @@ -274,7 +274,7 @@ void LottieBuilder::updateGradientStroke(LottieGroup* parent, LottieObject** chi void LottieBuilder::updateSolidFill(LottieGroup* parent, LottieObject** child, float frameNo, Inlist& contexts, RenderContext* ctx) { - if (_fragmented(parent, child, contexts, ctx)) return; + if (fragmented(parent, child, contexts, ctx)) return; auto fill = static_cast(*child); @@ -289,7 +289,7 @@ void LottieBuilder::updateSolidFill(LottieGroup* parent, LottieObject** child, f void LottieBuilder::updateGradientFill(LottieGroup* parent, LottieObject** child, float frameNo, Inlist& contexts, RenderContext* ctx) { - if (_fragmented(parent, child, contexts, ctx)) return; + if (fragmented(parent, child, contexts, ctx)) return; auto fill = static_cast(*child); @@ -547,11 +547,11 @@ void LottieBuilder::updatePath(LottieGroup* parent, LottieObject** child, float if (!ctx->repeaters.empty()) { auto shape = path->pooling(); shape->reset(); - path->pathset(frameNo, SHAPE(shape)->rs.path, ctx->transform, exps, ctx->roundness, ctx->offset); + path->pathset(frameNo, SHAPE(shape)->rs.path, ctx->transform, exps, ctx->modifier); _repeat(parent, shape, ctx); } else { _draw(parent, path, ctx); - if (path->pathset(frameNo, SHAPE(ctx->merging)->rs.path, ctx->transform, exps, ctx->roundness, ctx->offset)) { + if (path->pathset(frameNo, SHAPE(ctx->merging)->rs.path, ctx->transform, exps, ctx->modifier)) { PAINT(ctx->merging)->update(RenderUpdateFlag::Path); } } @@ -674,13 +674,7 @@ void LottieBuilder::updateStar(LottiePolyStar* star, float frameNo, Matrix* tran } shape->close(); - if (roundedCorner) { - if (ctx->offset) { - buffer.clear(); - ctx->roundness->modifyPolystar(SHAPE(shape)->rs.path, buffer, outerRoundness, hasRoundness); - ctx->offset->modifyPolystar(buffer, SHAPE(merging)->rs.path); - } else ctx->roundness->modifyPolystar(SHAPE(shape)->rs.path, SHAPE(merging)->rs.path, outerRoundness, hasRoundness); - } else if (ctx->offset) ctx->offset->modifyPolystar(SHAPE(shape)->rs.path, SHAPE(merging)->rs.path); + if (ctx->modifier) ctx->modifier->modifyPolystar(SHAPE(shape)->rs.path, SHAPE(merging)->rs.path, outerRoundness, hasRoundness); } @@ -758,13 +752,7 @@ void LottieBuilder::updatePolygon(LottieGroup* parent, LottiePolyStar* star, flo } shape->close(); - if (roundedCorner) { - if (ctx->offset) { - buffer.clear(); - ctx->roundness->modifyPolystar(SHAPE(shape)->rs.path, buffer, 0.0f, false); - ctx->offset->modifyPolystar(buffer, SHAPE(merging)->rs.path); - } else ctx->roundness->modifyPolystar(SHAPE(shape)->rs.path, SHAPE(merging)->rs.path, 0.0f, false); - } else if (ctx->offset) ctx->offset->modifyPolystar(SHAPE(shape)->rs.path, SHAPE(merging)->rs.path); + if (ctx->modifier) ctx->modifier->modifyPolystar(SHAPE(shape)->rs.path, SHAPE(merging)->rs.path, 0.0f, false); } @@ -803,8 +791,10 @@ void LottieBuilder::updateRoundedCorner(TVG_UNUSED LottieGroup* parent, LottieOb auto r = roundedCorner->radius(frameNo, exps); if (r < LottieRoundnessModifier::ROUNDNESS_EPSILON) return; - if (!ctx->roundness) ctx->roundness = new LottieRoundnessModifier(r); + if (!ctx->roundness) ctx->roundness = new LottieRoundnessModifier(&buffer, r); else if (ctx->roundness->r < r) ctx->roundness->r = r; + + ctx->update(ctx->roundness); } @@ -812,6 +802,8 @@ void LottieBuilder::updateOffsetPath(TVG_UNUSED LottieGroup* parent, LottieObjec { auto offset = static_cast(*child); if (!ctx->offset) ctx->offset = new LottieOffsetModifier(offset->offset(frameNo, exps), offset->miterLimit(frameNo, exps), offset->join); + + ctx->update(ctx->offset); } @@ -1261,7 +1253,7 @@ void LottieBuilder::updateMasks(LottieLayer* layer, float frameNo) } else { //TODO: Once path direction support is implemented, ensure that the direction is ignored here auto offset = LottieOffsetModifier(expand); - mask->pathset(frameNo, SHAPE(pShape)->rs.path, nullptr, exps, nullptr, &offset); + mask->pathset(frameNo, SHAPE(pShape)->rs.path, nullptr, exps, &offset); } if (fastTrack) return; @@ -1309,7 +1301,7 @@ void LottieBuilder::updateStrokeEffect(LottieLayer* layer, LottieFxStroke* effec auto idx = static_cast(effect->mask(frameNo) - 1); if (idx < 0 || idx >= layer->masks.count) return; auto mask = layer->masks[idx]; - mask->pathset(frameNo, SHAPE(shape)->rs.path, nullptr, exps, nullptr, nullptr); + mask->pathset(frameNo, SHAPE(shape)->rs.path, nullptr, exps); } shape->transform(layer->cache.matrix); diff --git a/src/loaders/lottie/tvgLottieBuilder.h b/src/loaders/lottie/tvgLottieBuilder.h index 6cc58a74..b44bcaee 100644 --- a/src/loaders/lottie/tvgLottieBuilder.h +++ b/src/loaders/lottie/tvgLottieBuilder.h @@ -57,6 +57,7 @@ struct RenderContext Matrix* transform = nullptr; LottieRoundnessModifier* roundness = nullptr; LottieOffsetModifier* offset = nullptr; + LottieModifier* modifier = nullptr; bool fragmenting = false; //render context has been fragmented by filling bool reqFragment = false; //requirement to fragment the render context @@ -81,8 +82,20 @@ struct RenderContext propagator->ref(); this->propagator = propagator; repeaters = rhs.repeaters; - if (rhs.roundness) roundness = new LottieRoundnessModifier(rhs.roundness->r); - if (rhs.offset) offset = new LottieOffsetModifier(rhs.offset->offset, rhs.offset->miterLimit, rhs.offset->join); + if (rhs.roundness) { + roundness = new LottieRoundnessModifier(rhs.roundness->buffer, rhs.roundness->r); + update(roundness); + } + if (rhs.offset) { + offset = new LottieOffsetModifier(rhs.offset->offset, rhs.offset->miterLimit, rhs.offset->join); + update(offset); + } + } + + void update(LottieModifier* next) + { + if (modifier) modifier = modifier->decorate(next); + else modifier = next; } }; @@ -108,6 +121,7 @@ struct LottieBuilder private: void appendRect(Shape* shape, Point& pos, Point& size, float r, bool clockwise, RenderContext* ctx); + bool fragmented(LottieGroup* parent, LottieObject** child, Inlist& contexts, RenderContext* ctx); void updateStrokeEffect(LottieLayer* layer, LottieFxStroke* effect, float frameNo); void updateEffect(LottieLayer* layer, float frameNo); diff --git a/src/loaders/lottie/tvgLottieExpressions.h b/src/loaders/lottie/tvgLottieExpressions.h index 2da72281..6b96679a 100644 --- a/src/loaders/lottie/tvgLottieExpressions.h +++ b/src/loaders/lottie/tvgLottieExpressions.h @@ -29,8 +29,7 @@ struct LottieExpression; struct LottieComposition; struct LottieLayer; -struct LottieRoundnessModifier; -struct LottieOffsetModifier; +struct LottieModifier; #ifdef THORVG_LOTTIE_EXPRESSIONS_SUPPORT @@ -112,13 +111,13 @@ public: } template - bool result(float frameNo, RenderPath& out, Matrix* transform, LottieRoundnessModifier* roundness, LottieOffsetModifier* offset, LottieExpression* exp) + bool result(float frameNo, RenderPath& out, Matrix* transform, LottieModifier* modifier, LottieExpression* exp) { auto bm_rt = evaluate(frameNo, exp); if (jerry_value_is_undefined(bm_rt)) return false; if (auto pathset = static_cast(jerry_object_get_native_ptr(bm_rt, nullptr))) { - (*pathset)(frameNo, out, transform, nullptr, roundness, offset); + (*pathset)(frameNo, out, transform, nullptr, modifier); } jerry_value_free(bm_rt); return true; @@ -157,7 +156,7 @@ struct LottieExpressions template bool result(TVG_UNUSED float, TVG_UNUSED Point&, LottieExpression*) { return false; } template bool result(TVG_UNUSED float, TVG_UNUSED RGB24&, TVG_UNUSED LottieExpression*) { return false; } template bool result(TVG_UNUSED float, TVG_UNUSED Fill*, TVG_UNUSED LottieExpression*) { return false; } - template bool result(TVG_UNUSED float, TVG_UNUSED RenderPath&, TVG_UNUSED Matrix*, TVG_UNUSED LottieRoundnessModifier*, TVG_UNUSED LottieOffsetModifier*, TVG_UNUSED LottieExpression*) { return false; } + template bool result(TVG_UNUSED float, TVG_UNUSED RenderPath&, TVG_UNUSED Matrix*, TVG_UNUSED LottieModifier*, TVG_UNUSED LottieExpression*) { return false; } void update(TVG_UNUSED float) {} static LottieExpressions* instance() { return nullptr; } static void retrieve(TVG_UNUSED LottieExpressions* instance) {} diff --git a/src/loaders/lottie/tvgLottieModifier.cpp b/src/loaders/lottie/tvgLottieModifier.cpp index 9d3a6327..9100ba2b 100644 --- a/src/loaders/lottie/tvgLottieModifier.cpp +++ b/src/loaders/lottie/tvgLottieModifier.cpp @@ -96,7 +96,7 @@ static bool _clockwise(Point* pts, uint32_t n) } -void LottieOffsetModifier::corner(RenderPath& out, Line& line, Line& nextLine, uint32_t movetoOutIndex, bool nextClose) const +void LottieOffsetModifier::corner(RenderPath& out, Line& line, Line& nextLine, uint32_t movetoOutIndex, bool nextClose) { bool inside{}; Point intersect{}; @@ -127,7 +127,7 @@ void LottieOffsetModifier::corner(RenderPath& out, Line& line, Line& nextLine, u } -void LottieOffsetModifier::line(RenderPath& out, PathCommand* inCmds, uint32_t inCmdsCnt, Point* inPts, uint32_t& curPt, uint32_t curCmd, State& state, float offset, bool degenerated) const +void LottieOffsetModifier::line(RenderPath& out, PathCommand* inCmds, uint32_t inCmdsCnt, Point* inPts, uint32_t& curPt, uint32_t curCmd, State& state, float offset, bool degenerated) { if (tvg::zero(inPts[curPt - 1] - inPts[curPt])) { ++curPt; @@ -172,19 +172,23 @@ void LottieOffsetModifier::line(RenderPath& out, PathCommand* inCmds, uint32_t i /* External Class Implementation */ /************************************************************************/ -bool LottieRoundnessModifier::modifyPath(PathCommand* inCmds, uint32_t inCmdsCnt, Point* inPts, uint32_t inPtsCnt, Matrix* transform, RenderPath& out) const +bool LottieRoundnessModifier::modifyPath(PathCommand* inCmds, uint32_t inCmdsCnt, Point* inPts, uint32_t inPtsCnt, Matrix* transform, RenderPath& out) { - out.cmds.reserve(inCmdsCnt * 2); - out.pts.reserve((uint32_t)(inPtsCnt * 1.5)); - auto ptsCnt = out.pts.count; + buffer->clear(); + + auto& path = (next) ? *buffer : out; + + path.cmds.reserve(inCmdsCnt * 2); + path.pts.reserve((uint32_t)(inPtsCnt * 1.5)); + auto pivot = path.pts.count; uint32_t startIndex = 0; for (uint32_t iCmds = 0, iPts = 0; iCmds < inCmdsCnt; ++iCmds) { switch (inCmds[iCmds]) { case PathCommand::MoveTo: { - startIndex = out.pts.count; - out.cmds.push(PathCommand::MoveTo); - out.pts.push(inPts[iPts++]); + startIndex = path.pts.count; + path.cmds.push(PathCommand::MoveTo); + path.pts.push(inPts[iPts++]); break; } case PathCommand::CubicTo: { @@ -196,52 +200,59 @@ bool LottieRoundnessModifier::modifyPath(PathCommand* inCmds, uint32_t inCmdsCnt if (inCmds[iCmds + 1] == PathCommand::CubicTo && tvg::zero(inPts[iPts + 2] - inPts[iPts + 3]) && tvg::zero(inPts[iPts + 4] - inPts[iPts + 5])) { - _roundCorner(out.cmds, out.pts, prev, curr, inPts[iPts + 5], r); + _roundCorner(path.cmds, path.pts, prev, curr, inPts[iPts + 5], r); iPts += 3; break; } else if (inCmds[iCmds + 1] == PathCommand::Close) { - _roundCorner(out.cmds, out.pts, prev, curr, inPts[2], r); - out.pts[startIndex] = out.pts.last(); + _roundCorner(path.cmds, path.pts, prev, curr, inPts[2], r); + path.pts[startIndex] = path.pts.last(); iPts += 3; break; } } - out.cmds.push(PathCommand::CubicTo); - out.pts.push(inPts[iPts++]); - out.pts.push(inPts[iPts++]); - out.pts.push(inPts[iPts++]); + path.cmds.push(PathCommand::CubicTo); + path.pts.push(inPts[iPts++]); + path.pts.push(inPts[iPts++]); + path.pts.push(inPts[iPts++]); break; } case PathCommand::Close: { - out.cmds.push(PathCommand::Close); + path.cmds.push(PathCommand::Close); break; } default: break; } } if (transform) { - for (auto i = ptsCnt; i < out.pts.count; ++i) { - out.pts[i] *= *transform; + for (auto i = pivot; i < path.pts.count; ++i) { + path.pts[i] *= *transform; } } + + if (next) return next->modifyPath(path.cmds.data, path.cmds.count, path.pts.data, path.pts.count, transform, out); + return true; } -bool LottieRoundnessModifier::modifyPolystar(RenderPath& in, RenderPath& out, float outerRoundness, bool hasRoundness) const +bool LottieRoundnessModifier::modifyPolystar(RenderPath& in, RenderPath& out, float outerRoundness, bool hasRoundness) { - static constexpr auto ROUNDED_POLYSTAR_MAGIC_NUMBER = 0.47829f; + constexpr auto ROUNDED_POLYSTAR_MAGIC_NUMBER = 0.47829f; + + buffer->clear(); + + auto& path = (next) ? *buffer : out; auto len = length(in.pts[1] - in.pts[2]); auto r = len > 0.0f ? ROUNDED_POLYSTAR_MAGIC_NUMBER * std::min(len * 0.5f, this->r) / len : 0.0f; if (hasRoundness) { - out.cmds.grow((uint32_t)(1.5 * in.cmds.count)); - out.pts.grow((uint32_t)(4.5 * in.cmds.count)); + path.cmds.grow((uint32_t)(1.5 * in.cmds.count)); + path.pts.grow((uint32_t)(4.5 * in.cmds.count)); int start = 3 * tvg::zero(outerRoundness); - out.cmds.push(PathCommand::MoveTo); - out.pts.push(in.pts[start]); + path.cmds.push(PathCommand::MoveTo); + path.pts.push(in.pts[start]); for (uint32_t i = 1 + start; i < in.pts.count; i += 6) { auto& prev = in.pts[i]; @@ -256,21 +267,21 @@ bool LottieRoundnessModifier::modifyPolystar(RenderPath& in, RenderPath& out, fl auto p2 = curr - dNext; auto p3 = curr - 2.0f * dNext; - out.cmds.push(PathCommand::CubicTo); - out.pts.push(prev); out.pts.push(p0); out.pts.push(p0); - out.cmds.push(PathCommand::CubicTo); - out.pts.push(p1); out.pts.push(p2); out.pts.push(p3); - out.cmds.push(PathCommand::CubicTo); - out.pts.push(p3); out.pts.push(next); out.pts.push(nextCtrl); + path.cmds.push(PathCommand::CubicTo); + path.pts.push(prev); path.pts.push(p0); path.pts.push(p0); + path.cmds.push(PathCommand::CubicTo); + path.pts.push(p1); path.pts.push(p2); path.pts.push(p3); + path.cmds.push(PathCommand::CubicTo); + path.pts.push(p3); path.pts.push(next); path.pts.push(nextCtrl); } } else { - out.cmds.grow(2 * in.cmds.count); - out.pts.grow(4 * in.cmds.count); + path.cmds.grow(2 * in.cmds.count); + path.pts.grow(4 * in.cmds.count); auto dPrev = r * (in.pts[1] - in.pts[0]); auto p = in.pts[0] + 2.0f * dPrev; - out.cmds.push(PathCommand::MoveTo); - out.pts.push(p); + path.cmds.push(PathCommand::MoveTo); + path.pts.push(p); for (uint32_t i = 1; i < in.pts.count; ++i) { auto& curr = in.pts[i]; @@ -282,28 +293,33 @@ bool LottieRoundnessModifier::modifyPolystar(RenderPath& in, RenderPath& out, fl auto p2 = curr - dNext; auto p3 = curr - 2.0f * dNext; - out.cmds.push(PathCommand::LineTo); - out.pts.push(p0); - out.cmds.push(PathCommand::CubicTo); - out.pts.push(p1); out.pts.push(p2); out.pts.push(p3); + path.cmds.push(PathCommand::LineTo); + path.pts.push(p0); + path.cmds.push(PathCommand::CubicTo); + path.pts.push(p1); path.pts.push(p2); path.pts.push(p3); dPrev = -1.0f * dNext; } } - out.cmds.push(PathCommand::Close); + path.cmds.push(PathCommand::Close); + + if (next) return next->modifyPolystar(path, out, outerRoundness, hasRoundness); + return true; } -bool LottieRoundnessModifier::modifyRect(Point& size, float& r) const +bool LottieRoundnessModifier::modifyRect(Point& size, float& r) { r = std::min(this->r, std::max(size.x, size.y) * 0.5f); return true; } -bool LottieOffsetModifier::modifyPath(PathCommand* inCmds, uint32_t inCmdsCnt, Point* inPts, uint32_t inPtsCnt, RenderPath& out) const +bool LottieOffsetModifier::modifyPath(PathCommand* inCmds, uint32_t inCmdsCnt, Point* inPts, uint32_t inPtsCnt, TVG_UNUSED Matrix* transform, RenderPath& out) { + if (next) TVGERR("LOTTIE", "Offset has a next modifier?"); + out.cmds.reserve(inCmdsCnt * 2); out.pts.reserve(inPtsCnt * (join == StrokeJoin::Round ? 4 : 2)); @@ -376,18 +392,19 @@ bool LottieOffsetModifier::modifyPath(PathCommand* inCmds, uint32_t inCmdsCnt, P } -bool LottieOffsetModifier::modifyPolystar(RenderPath& in, RenderPath& out) const { - return modifyPath(in.cmds.data, in.cmds.count, in.pts.data, in.pts.count, out); -} - - -bool LottieOffsetModifier::modifyRect(RenderPath& in, RenderPath& out) const +bool LottieOffsetModifier::modifyPolystar(RenderPath& in, RenderPath& out, TVG_UNUSED float, TVG_UNUSED bool) { - return modifyPath(in.cmds.data, in.cmds.count, in.pts.data, in.pts.count, out); + return modifyPath(in.cmds.data, in.cmds.count, in.pts.data, in.pts.count, nullptr, out); } -bool LottieOffsetModifier::modifyEllipse(Point& radius) const +bool LottieOffsetModifier::modifyRect(RenderPath& in, RenderPath& out) +{ + return modifyPath(in.cmds.data, in.cmds.count, in.pts.data, in.pts.count, nullptr, out); +} + + +bool LottieOffsetModifier::modifyEllipse(Point& radius) { radius.x += offset; radius.y += offset; diff --git a/src/loaders/lottie/tvgLottieModifier.h b/src/loaders/lottie/tvgLottieModifier.h index 53a34f34..b9367431 100644 --- a/src/loaders/lottie/tvgLottieModifier.h +++ b/src/loaders/lottie/tvgLottieModifier.h @@ -28,31 +28,69 @@ #include "tvgMath.h" #include "tvgRender.h" -struct LottieRoundnessModifier + +struct LottieModifier +{ + enum Type : uint8_t {Roundness = 0, Offset}; + + LottieModifier* next = nullptr; + Type type; + + virtual ~LottieModifier() {} + + virtual bool modifyPath(PathCommand* inCmds, uint32_t inCmdsCnt, Point* inPts, uint32_t inPtsCnt, Matrix* transform, RenderPath& out) = 0; + virtual bool modifyPolystar(RenderPath& in, RenderPath& out, float outerRoundness, bool hasRoundness) = 0; + + LottieModifier* decorate(LottieModifier* next) + { + /* TODO: build the decorative chaining here. + currently we only have roundness and offset. */ + + //roundness -> offset + if (next->type == Roundness) { + next->next = this; + return next; + } + + //just in the order. + this->next = next; + return this; + } +}; + +struct LottieRoundnessModifier : LottieModifier { static constexpr float ROUNDNESS_EPSILON = 1.0f; + + RenderPath* buffer; float r; - LottieRoundnessModifier(float r) : r(r) {}; + LottieRoundnessModifier(RenderPath* buffer, float r) : buffer(buffer), r(r) + { + type = Roundness; + } - bool modifyPath(PathCommand* inCmds, uint32_t inCmdsCnt, Point* inPts, uint32_t inPtsCnt, Matrix* transform, RenderPath& out) const; - bool modifyPolystar(RenderPath& in, RenderPath& out, float outerRoundness, bool hasRoundness) const; - bool modifyRect(Point& size, float& r) const; + bool modifyPath(PathCommand* inCmds, uint32_t inCmdsCnt, Point* inPts, uint32_t inPtsCnt, Matrix* transform, RenderPath& out) override; + bool modifyPolystar(RenderPath& in, RenderPath& out, float outerRoundness, bool hasRoundness) override; + bool modifyRect(Point& size, float& r); }; -struct LottieOffsetModifier +struct LottieOffsetModifier : LottieModifier { float offset; float miterLimit; StrokeJoin join; - LottieOffsetModifier(float offset, float miter = 4.0f, StrokeJoin join = StrokeJoin::Round) : offset(offset), miterLimit(miter), join(join) {} + LottieOffsetModifier(float offset, float miter = 4.0f, StrokeJoin join = StrokeJoin::Round) : offset(offset), miterLimit(miter), join(join) + { + type = Offset; + } - bool modifyPath(PathCommand* inCmds, uint32_t inCmdsCnt, Point* inPts, uint32_t inPtsCnt, RenderPath& out) const; - bool modifyPolystar(RenderPath& in, RenderPath& out) const; - bool modifyRect(RenderPath& in, RenderPath& out) const; - bool modifyEllipse(Point& radius) const; + bool modifyPath(PathCommand* inCmds, uint32_t inCmdsCnt, Point* inPts, uint32_t inPtsCnt, Matrix* transform, RenderPath& out) override; + bool modifyPolystar(RenderPath& in, RenderPath& out, float outerRoundness, bool hasRoundness) override; + bool modifyRect(RenderPath& in, RenderPath& out); + bool modifyEllipse(Point& radius); private: struct State @@ -64,8 +102,8 @@ private: uint32_t movetoInIndex = 0; }; - void line(RenderPath& out, PathCommand* inCmds, uint32_t inCmdsCnt, Point* inPts, uint32_t& curPt, uint32_t curCmd, State& state, float offset, bool degenerated) const; - void corner(RenderPath& out, Line& line, Line& nextLine, uint32_t movetoIndex, bool nextClose) const; + void line(RenderPath& out, PathCommand* inCmds, uint32_t inCmdsCnt, Point* inPts, uint32_t& curPt, uint32_t curCmd, State& state, float offset, bool degenerated); + void corner(RenderPath& out, Line& line, Line& nextLine, uint32_t movetoIndex, bool nextClose); }; #endif \ No newline at end of file diff --git a/src/loaders/lottie/tvgLottieProperty.h b/src/loaders/lottie/tvgLottieProperty.h index 159c4a39..70f6f583 100644 --- a/src/loaders/lottie/tvgLottieProperty.h +++ b/src/loaders/lottie/tvgLottieProperty.h @@ -467,7 +467,7 @@ struct LottiePathSet : LottieProperty return true; } - bool modifiedPath(float frameNo, RenderPath& out, Matrix* transform, const LottieRoundnessModifier* roundness, const LottieOffsetModifier* offset) + bool modifiedPath(float frameNo, RenderPath& out, Matrix* transform, LottieModifier* modifier) { PathSet* path; LottieScalarFrame* frame; @@ -475,17 +475,7 @@ struct LottiePathSet : LottieProperty float t; if (dispatch(frameNo, path, frame, t)) { - if (roundness) { - if (offset) { - temp.cmds = Array(path->cmdsCnt); - temp.pts = Array(path->ptsCnt); - roundness->modifyPath(path->cmds, path->cmdsCnt, path->pts, path->ptsCnt, transform, temp); - return offset->modifyPath(temp.cmds.data, temp.cmds.count, temp.pts.data, temp.pts.count, out); - } - return roundness->modifyPath(path->cmds, path->cmdsCnt, path->pts, path->ptsCnt, transform, out); - } - if (offset) return offset->modifyPath(path->cmds, path->cmdsCnt, path->pts, path->ptsCnt, out); - + if (modifier) return modifier->modifyPath(path->cmds, path->cmdsCnt, path->pts, path->ptsCnt, transform, out); _copy(path, out.cmds); _copy(path, out.pts, transform); return true; @@ -502,12 +492,7 @@ struct LottiePathSet : LottieProperty if (transform) *p *= *transform; } - if (roundness) { - if (offset) { - roundness->modifyPath(frame->value.cmds, frame->value.cmdsCnt, interpPts, frame->value.ptsCnt, nullptr, temp); - offset->modifyPath(temp.cmds.data, temp.cmds.count, temp.pts.data, temp.pts.count, out); - } else roundness->modifyPath(frame->value.cmds, frame->value.cmdsCnt, interpPts, frame->value.ptsCnt, nullptr, out); - } else if (offset) offset->modifyPath(frame->value.cmds, frame->value.cmdsCnt, interpPts, frame->value.ptsCnt, out); + if (modifier) modifier->modifyPath(frame->value.cmds, frame->value.cmdsCnt, interpPts, frame->value.ptsCnt, nullptr, out); free(interpPts); @@ -539,15 +524,15 @@ struct LottiePathSet : LottieProperty return true; } - bool operator()(float frameNo, RenderPath& out, Matrix* transform, LottieExpressions* exps, LottieRoundnessModifier* roundness = nullptr, LottieOffsetModifier* offset = nullptr) + bool operator()(float frameNo, RenderPath& out, Matrix* transform, LottieExpressions* exps, LottieModifier* modifier = nullptr) { //overriding with expressions if (exps && exp) { frameNo = _loop(frames, frameNo, exp); - if (exps->result(frameNo, out, transform, roundness, offset, exp)) return true; + if (exps->result(frameNo, out, transform, modifier, exp)) return true; } - if (roundness || offset) return modifiedPath(frameNo, out, transform, roundness, offset); + if (modifier) return modifiedPath(frameNo, out, transform, modifier); else return defaultPath(frameNo, out, transform); }