From c10c713c0502abf64ce0e332397c001283dcd766 Mon Sep 17 00:00:00 2001 From: Jinny You Date: Wed, 18 Sep 2024 15:42:56 +0900 Subject: [PATCH] lottie/text: applied Text Range randomization. on each parse, if the `randomize` is enabled, the start and end of the Text Range are redefined with the same gap as the original range. issue: https://github.com/thorvg/thorvg/issues/2178 --- src/loaders/lottie/tvgLottieBuilder.cpp | 10 +++------- src/loaders/lottie/tvgLottieModel.cpp | 18 ++++++++++++++++++ src/loaders/lottie/tvgLottieModel.h | 4 +++- src/loaders/lottie/tvgLottieParser.cpp | 2 +- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index a4b7659a..672561ad 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -1069,14 +1069,10 @@ void LottieBuilder::updateText(LottieLayer* layer, float frameNo) //text range process for (auto s = text->ranges.begin(); s < text->ranges.end(); ++s) { + float start, end; + (*s)->range(frameNo, totalChars, start, end); + auto basedIdx = idx; - float divisor = (*s)->rangeUnit == LottieTextRange::Unit::Percent ? (100.0f / totalChars) : 1; - auto offset = (*s)->offset(frameNo) / divisor; - auto start = nearbyintf((*s)->start(frameNo) / divisor) + offset; - auto end = nearbyintf((*s)->end(frameNo) / divisor) + offset; - - if (start > end) std::swap(start, end); - if ((*s)->based == LottieTextRange::Based::CharsExcludingSpaces) basedIdx = idx - space; else if ((*s)->based == LottieTextRange::Based::Words) basedIdx = line + space; else if ((*s)->based == LottieTextRange::Based::Lines) basedIdx = line; diff --git a/src/loaders/lottie/tvgLottieModel.cpp b/src/loaders/lottie/tvgLottieModel.cpp index 658f8304..7572c769 100644 --- a/src/loaders/lottie/tvgLottieModel.cpp +++ b/src/loaders/lottie/tvgLottieModel.cpp @@ -110,6 +110,24 @@ void LottieSlot::assign(LottieObject* target) } +void LottieTextRange::range(float frameNo, size_t totalLen, float& start, float& end) +{ + float divisor = rangeUnit == Unit::Percent ? (100.0f / totalLen) : 1; + auto offset = this->offset(frameNo) / divisor; + start = nearbyintf(this->start(frameNo) / divisor) + offset; + end = nearbyintf(this->end(frameNo) / divisor) + offset; + + if (start > end) std::swap(start, end); + + if (random == 0) return; + + auto range = end - start; + auto len = rangeUnit == Unit::Percent ? 100 : totalLen; + start = random % int(len - range); + end = start + range; +} + + LottieImage::~LottieImage() { free(b64Data); diff --git a/src/loaders/lottie/tvgLottieModel.h b/src/loaders/lottie/tvgLottieModel.h index c1848cdd..241159eb 100644 --- a/src/loaders/lottie/tvgLottieModel.h +++ b/src/loaders/lottie/tvgLottieModel.h @@ -184,8 +184,10 @@ struct LottieTextRange Based based = Chars; Shape shape = Square; Unit rangeUnit = Percent; + uint8_t random = 0; bool expressible = false; - bool randomize = false; + + void range(float frameNo, size_t totalLen, float& start, float& end); }; diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index eda65ddc..14df4a9d 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -1123,7 +1123,7 @@ void LottieParser::parseTextRange(LottieText* text) else if (KEY_AS("ne")) parseProperty(selector->minEase); else if (KEY_AS("a")) parseProperty(selector->maxAmount); else if (KEY_AS("b")) selector->based = (LottieTextRange::Based) getInt(); - else if (KEY_AS("rn")) selector->randomize = (bool) getInt(); + else if (KEY_AS("rn") && getInt()) selector->random = rand(); else if (KEY_AS("sh")) selector->shape = (LottieTextRange::Shape) getInt(); else if (KEY_AS("o")) parseProperty(selector->offset); else if (KEY_AS("r")) selector->rangeUnit = (LottieTextRange::Unit) getInt();