diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index ae61aca9..60aeb37c 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -31,7 +31,7 @@ /* Internal Class Implementation */ /************************************************************************/ -static void _updateChildren(LottieGroup* parent, int32_t frameNo, Shape* baseShape); +static void _updateChildren(LottieGroup* parent, int32_t frameNo, Shape* baseShape, float roundedCorner); static void _updateLayer(LottieLayer* root, LottieLayer* layer, int32_t frameNo); static bool _buildPrecomp(LottieComposition* comp, LottieGroup* parent); @@ -108,7 +108,7 @@ static Shape* _updateTransform(Paint* paint, LottieTransform* transform, int32_t } -static Shape* _updateGroup(LottieGroup* parent, LottieGroup* group, int32_t frameNo, Shape* baseShape) +static Shape* _updateGroup(LottieGroup* parent, LottieGroup* group, int32_t frameNo, Shape* baseShape, float roundedCorner) { //Prepare render data group->scene = parent->scene; @@ -127,7 +127,7 @@ static Shape* _updateGroup(LottieGroup* parent, LottieGroup* group, int32_t fram #endif } - _updateChildren(group, frameNo, baseShape); + _updateChildren(group, frameNo, baseShape, roundedCorner); return nullptr; } @@ -185,21 +185,23 @@ static Shape* _updateStroke(LottieGradientStroke* stroke, int32_t frameNo, Shape } -static Shape* _updateRect(LottieGroup* parent, LottieRect* rect, int32_t frameNo, Shape* baseShape, Shape* mergingShape) +static Shape* _updateRect(LottieGroup* parent, LottieRect* rect, int32_t frameNo, Shape* baseShape, Shape* mergingShape, float roundedCorner) { auto position = rect->position(frameNo); auto size = rect->size(frameNo); - auto roundness = rect->roundness(frameNo); - if (roundness != 0) { - if (roundness > size.x * 0.5f) roundness = size.x * 0.5f; - if (roundness > size.y * 0.5f) roundness = size.y * 0.5f; + auto round = rect->radius(frameNo); + if (roundedCorner > round) round = roundedCorner; + + if (round > 0.0f) { + if (round > size.x * 0.5f) round = size.x * 0.5f; + if (round > size.y * 0.5f) round = size.y * 0.5f; } if (!mergingShape) { auto newShape = cast(baseShape->duplicate()); mergingShape = newShape.get(); parent->scene->push(std::move(newShape)); } - mergingShape->appendRect(position.x - size.x * 0.5f, position.y - size.y * 0.5f, size.x, size.y, roundness, roundness); + mergingShape->appendRect(position.x - size.x * 0.5f, position.y - size.y * 0.5f, size.x, size.y, round, round); return mergingShape; } @@ -218,7 +220,7 @@ static Shape* _updateEllipse(LottieGroup* parent, LottieEllipse* ellipse, int32_ } -static Shape* _updatePath(LottieGroup* parent, LottiePath* path, int32_t frameNo, Shape* baseShape, Shape* mergingShape) +static Shape* _updatePath(LottieGroup* parent, LottiePath* path, int32_t frameNo, Shape* baseShape, Shape* mergingShape, float roundedCorner) { if (!mergingShape) { auto newShape = cast(baseShape->duplicate()); @@ -228,6 +230,12 @@ static Shape* _updatePath(LottieGroup* parent, LottiePath* path, int32_t frameNo if (path->pathset(frameNo, P(mergingShape)->rs.path.cmds, P(mergingShape)->rs.path.pts)) { P(mergingShape)->update(RenderUpdateFlag::Path); } + + if (roundedCorner > 1.0f && P(mergingShape)->rs.stroke) { + TVGERR("LOTTIE", "FIXME: Path roundesss should be applied properly!"); + P(mergingShape)->rs.stroke->join = StrokeJoin::Round; + } + return mergingShape; } @@ -465,7 +473,15 @@ static void _updateImage(LottieGroup* parent, LottieImage* image, int32_t frameN } -static void _updateChildren(LottieGroup* parent, int32_t frameNo, Shape* baseShape) +static float _updateRoundedCorner(LottieRoundedCorner* roundedCorner, int32_t frameNo, float baseValue) +{ + auto round = roundedCorner->radius(frameNo); + if (baseValue > round) round = baseValue; + return round; +} + + +static void _updateChildren(LottieGroup* parent, int32_t frameNo, Shape* baseShape, float roundedCorner) { if (parent->children.empty()) return; @@ -479,7 +495,7 @@ static void _updateChildren(LottieGroup* parent, int32_t frameNo, Shape* baseSha for (auto child = parent->children.end() - 1; child >= parent->children.data; --child) { switch ((*child)->type) { case LottieObject::Group: { - mergingShape = _updateGroup(parent, static_cast(*child), frameNo, baseShape); + mergingShape = _updateGroup(parent, static_cast(*child), frameNo, baseShape, roundedCorner); break; } case LottieObject::Transform: { @@ -503,7 +519,7 @@ static void _updateChildren(LottieGroup* parent, int32_t frameNo, Shape* baseSha break; } case LottieObject::Rect: { - mergingShape = _updateRect(parent, static_cast(*child), frameNo, baseShape, mergingShape); + mergingShape = _updateRect(parent, static_cast(*child), frameNo, baseShape, mergingShape, roundedCorner); break; } case LottieObject::Ellipse: { @@ -511,13 +527,17 @@ static void _updateChildren(LottieGroup* parent, int32_t frameNo, Shape* baseSha break; } case LottieObject::Path: { - mergingShape = _updatePath(parent, static_cast(*child), frameNo, baseShape, mergingShape); + mergingShape = _updatePath(parent, static_cast(*child), frameNo, baseShape, mergingShape, roundedCorner); break; } case LottieObject::Polystar: { mergingShape = _updatePolystar(parent, static_cast(*child), frameNo, baseShape, mergingShape); break; } + case LottieObject::RoundedCorner: { + roundedCorner = _updateRoundedCorner(static_cast(*child), frameNo, roundedCorner); + break; + } case LottieObject::Image: { _updateImage(parent, static_cast(*child), frameNo, baseShape); break; @@ -615,7 +635,7 @@ static void _updateLayer(LottieLayer* root, LottieLayer* layer, int32_t frameNo) break; } default: { - _updateChildren(layer, rFrameNo, nullptr); + _updateChildren(layer, rFrameNo, nullptr, 0); break; } } diff --git a/src/loaders/lottie/tvgLottieModel.h b/src/loaders/lottie/tvgLottieModel.h index 9d9bd971..18d9551c 100644 --- a/src/loaders/lottie/tvgLottieModel.h +++ b/src/loaders/lottie/tvgLottieModel.h @@ -162,7 +162,6 @@ struct LottieRoundedCorner : LottieObject LottieObject::type = LottieObject::RoundedCorner; if (radius.frames) statical = false; } - LottieFloat radius = 0.0f; }; @@ -184,18 +183,12 @@ struct LottieRect : LottieShape void prepare() { LottieObject::type = LottieObject::Rect; - if (position.frames || size.frames || round.frames) statical = false; + if (position.frames || size.frames || radius.frames) statical = false; } - float roundness(int32_t frameNo) - { - return roundedCorner ? roundedCorner->radius(frameNo) : round(frameNo); - } - - LottieRoundedCorner* roundedCorner = nullptr; LottiePosition position = Point{0.0f, 0.0f}; LottiePoint size = Point{0.0f, 0.0f}; - LottieFloat round = 0.0f; + LottieFloat radius = 0.0f; //rounded corner radius }; diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index 20418556..1ffbbaee 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -40,24 +40,6 @@ static char* _int2str(int num) } -static void _updateRoundedCorner(LottieGroup* parent, LottieRoundedCorner* roundedCorner) -{ - for (auto child = parent->children.data; child < parent->children.end(); ++child) { - auto obj = *child; - if (obj->type == LottieObject::Rect) { - auto rect = static_cast(obj); - rect->roundedCorner = roundedCorner; - rect->statical &= roundedCorner->statical; - parent->statical &= roundedCorner->statical; - continue; - } - if (obj->type == LottieObject::Group || obj->type == LottieObject::Layer) { - _updateRoundedCorner(static_cast(obj), roundedCorner); - } - } -} - - CompositeMethod LottieParser::getMaskMethod(bool inversed) { switch (getString()[0]) { @@ -484,7 +466,7 @@ LottieRect* LottieParser::parseRect() if (!strcmp(key, "d")) rect->direction = getInt(); else if (!strcmp(key, "s")) parseProperty(rect->size); else if (!strcmp(key, "p")) parseProperty(rect->position); - else if (!strcmp(key, "r")) parseProperty(rect->round); + else if (!strcmp(key, "r")) parseProperty(rect->radius); else if (!strcmp(key, "nm")) rect->name = getStringCopy(); else if (!strcmp(key, "hd")) rect->hidden = getBool(); else skip(key); @@ -787,14 +769,10 @@ void LottieParser::parseObject(LottieGroup* parent) enterObject(); while (auto key = nextObjectKey()) { if (!strcmp(key, "ty")) { - auto child = parseObject(); - if (child && !child->hidden) { - //propagate the rounded corner properties. - if (child->type == LottieObject::RoundedCorner) { - _updateRoundedCorner(parent, static_cast(child)); - } - parent->children.push(child); - } else delete(child); + if (auto child = parseObject()) { + if (child->hidden) delete(child); + else parent->children.push(child); + } } else skip(key); } }