mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
lottie: code refactoring
- removed unnecessary variables. - migrated the composition methods to the precomp layer.
This commit is contained in:
parent
828f8e0767
commit
3804bbec57
6 changed files with 54 additions and 60 deletions
|
@ -97,7 +97,7 @@ struct RenderContext
|
||||||
|
|
||||||
|
|
||||||
static void _updateChildren(LottieGroup* parent, float frameNo, Inlist<RenderContext>& contexts, LottieExpressions* exps);
|
static void _updateChildren(LottieGroup* parent, float frameNo, Inlist<RenderContext>& contexts, LottieExpressions* exps);
|
||||||
static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo, LottieExpressions* exps);
|
static void _updateLayer(LottieComposition* comp, Scene* scene, LottieLayer* layer, float frameNo, LottieExpressions* exps);
|
||||||
static bool _buildComposition(LottieComposition* comp, LottieLayer* parent);
|
static bool _buildComposition(LottieComposition* comp, LottieLayer* parent);
|
||||||
static bool _draw(LottieGroup* parent, LottieShape* shape, RenderContext* ctx);
|
static bool _draw(LottieGroup* parent, LottieShape* shape, RenderContext* ctx);
|
||||||
|
|
||||||
|
@ -1035,15 +1035,15 @@ static void _updateChildren(LottieGroup* parent, float frameNo, Inlist<RenderCon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _updatePrecomp(LottieLayer* precomp, float frameNo, LottieExpressions* exps)
|
static void _updatePrecomp(LottieComposition* comp, LottieLayer* precomp, float frameNo, LottieExpressions* exps)
|
||||||
{
|
{
|
||||||
if (precomp->children.empty()) return;
|
if (precomp->children.empty()) return;
|
||||||
|
|
||||||
frameNo = precomp->remap(frameNo, exps);
|
frameNo = precomp->remap(comp, frameNo, exps);
|
||||||
|
|
||||||
for (auto c = precomp->children.end() - 1; c >= precomp->children.begin(); --c) {
|
for (auto c = precomp->children.end() - 1; c >= precomp->children.begin(); --c) {
|
||||||
auto child = static_cast<LottieLayer*>(*c);
|
auto child = static_cast<LottieLayer*>(*c);
|
||||||
if (!child->matteSrc) _updateLayer(precomp, child, frameNo, exps);
|
if (!child->matteSrc) _updateLayer(comp, precomp->scene, child, frameNo, exps);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: remove the intermediate scene....
|
//TODO: remove the intermediate scene....
|
||||||
|
@ -1244,12 +1244,12 @@ static void _updateMaskings(LottieLayer* layer, float frameNo, LottieExpressions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool _updateMatte(LottieLayer* root, LottieLayer* layer, float frameNo, LottieExpressions* exps)
|
static bool _updateMatte(LottieComposition* comp, float frameNo, Scene* scene, LottieLayer* layer, LottieExpressions* exps)
|
||||||
{
|
{
|
||||||
auto target = layer->matteTarget;
|
auto target = layer->matteTarget;
|
||||||
if (!target) return true;
|
if (!target) return true;
|
||||||
|
|
||||||
_updateLayer(root, target, frameNo, exps);
|
_updateLayer(comp, scene, target, frameNo, exps);
|
||||||
|
|
||||||
if (target->scene) {
|
if (target->scene) {
|
||||||
layer->scene->composite(cast(target->scene), layer->matteType);
|
layer->scene->composite(cast(target->scene), layer->matteType);
|
||||||
|
@ -1263,7 +1263,7 @@ static bool _updateMatte(LottieLayer* root, LottieLayer* layer, float frameNo, L
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo, LottieExpressions* exps)
|
static void _updateLayer(LottieComposition* comp, Scene* scene, LottieLayer* layer, float frameNo, LottieExpressions* exps)
|
||||||
{
|
{
|
||||||
layer->scene = nullptr;
|
layer->scene = nullptr;
|
||||||
|
|
||||||
|
@ -1285,13 +1285,13 @@ static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo, L
|
||||||
|
|
||||||
if (layer->matteTarget && layer->masks.count > 0) TVGERR("LOTTIE", "FIXME: Matte + Masking??");
|
if (layer->matteTarget && layer->masks.count > 0) TVGERR("LOTTIE", "FIXME: Matte + Masking??");
|
||||||
|
|
||||||
if (!_updateMatte(root, layer, frameNo, exps)) return;
|
if (!_updateMatte(comp, frameNo, scene, layer, exps)) return;
|
||||||
|
|
||||||
_updateMaskings(layer, frameNo, exps);
|
_updateMaskings(layer, frameNo, exps);
|
||||||
|
|
||||||
switch (layer->type) {
|
switch (layer->type) {
|
||||||
case LottieLayer::Precomp: {
|
case LottieLayer::Precomp: {
|
||||||
_updatePrecomp(layer, frameNo, exps);
|
_updatePrecomp(comp, layer, frameNo, exps);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieLayer::Solid: {
|
case LottieLayer::Solid: {
|
||||||
|
@ -1320,7 +1320,7 @@ static void _updateLayer(LottieLayer* root, LottieLayer* layer, float frameNo, L
|
||||||
layer->scene->blend(layer->blendMethod);
|
layer->scene->blend(layer->blendMethod);
|
||||||
|
|
||||||
//the given matte source was composited by the target earlier.
|
//the given matte source was composited by the target earlier.
|
||||||
if (!layer->matteSrc) root->scene->push(cast(layer->scene));
|
if (!layer->matteSrc) scene->push(cast(layer->scene));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1431,9 +1431,9 @@ bool LottieBuilder::update(LottieComposition* comp, float frameNo)
|
||||||
{
|
{
|
||||||
if (comp->root->children.empty()) return false;
|
if (comp->root->children.empty()) return false;
|
||||||
|
|
||||||
frameNo += comp->startFrame;
|
frameNo += comp->root->inFrame;
|
||||||
if (frameNo < comp->startFrame) frameNo = comp->startFrame;
|
if (frameNo <comp->root->inFrame) frameNo = comp->root->inFrame;
|
||||||
if (frameNo >= comp->endFrame) frameNo = (comp->endFrame - 1);
|
if (frameNo >= comp->root->outFrame) frameNo = (comp->root->outFrame - 1);
|
||||||
|
|
||||||
//update children layers
|
//update children layers
|
||||||
auto root = comp->root;
|
auto root = comp->root;
|
||||||
|
@ -1443,7 +1443,7 @@ bool LottieBuilder::update(LottieComposition* comp, float frameNo)
|
||||||
|
|
||||||
for (auto child = root->children.end() - 1; child >= root->children.begin(); --child) {
|
for (auto child = root->children.end() - 1; child >= root->children.begin(); --child) {
|
||||||
auto layer = static_cast<LottieLayer*>(*child);
|
auto layer = static_cast<LottieLayer*>(*child);
|
||||||
if (!layer->matteSrc) _updateLayer(root, layer, frameNo, exps);
|
if (!layer->matteSrc) _updateLayer(comp, root->scene, layer, frameNo, exps);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1455,7 +1455,6 @@ void LottieBuilder::build(LottieComposition* comp)
|
||||||
if (!comp) return;
|
if (!comp) return;
|
||||||
|
|
||||||
comp->root->scene = Scene::gen().release();
|
comp->root->scene = Scene::gen().release();
|
||||||
if (!comp->root->scene) return;
|
|
||||||
|
|
||||||
_buildComposition(comp, comp->root);
|
_buildComposition(comp, comp->root);
|
||||||
|
|
||||||
|
@ -1463,6 +1462,6 @@ void LottieBuilder::build(LottieComposition* comp)
|
||||||
|
|
||||||
//viewport clip
|
//viewport clip
|
||||||
auto clip = Shape::gen();
|
auto clip = Shape::gen();
|
||||||
clip->appendRect(0, 0, static_cast<float>(comp->w), static_cast<float>(comp->h));
|
clip->appendRect(0, 0, comp->w, comp->h);
|
||||||
comp->root->scene->composite(std::move(clip), CompositeMethod::ClipPath);
|
comp->root->scene->composite(std::move(clip), CompositeMethod::ClipPath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -645,11 +645,11 @@ static jerry_value_t _layer(const jerry_call_info_t* info, const jerry_value_t a
|
||||||
//layer index
|
//layer index
|
||||||
if (jerry_value_is_number(args[0])) {
|
if (jerry_value_is_number(args[0])) {
|
||||||
auto idx = (uint16_t)jerry_value_as_int32(args[0]);
|
auto idx = (uint16_t)jerry_value_as_int32(args[0]);
|
||||||
layer = comp->layerByIdx(idx);
|
layer = comp->root->layerByIdx(idx);
|
||||||
jerry_value_free(idx);
|
jerry_value_free(idx);
|
||||||
//layer name
|
//layer name
|
||||||
} else {
|
} else {
|
||||||
layer = comp->layerById(_idByName(args[0]));
|
layer = comp->root->layerById(_idByName(args[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!layer) return jerry_undefined();
|
if (!layer) return jerry_undefined();
|
||||||
|
@ -1043,7 +1043,7 @@ static void _buildProperty(float frameNo, jerry_value_t context, LottieExpressio
|
||||||
static jerry_value_t _comp(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt)
|
static jerry_value_t _comp(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt)
|
||||||
{
|
{
|
||||||
auto comp = static_cast<LottieComposition*>(jerry_object_get_native_ptr(info->function, nullptr));
|
auto comp = static_cast<LottieComposition*>(jerry_object_get_native_ptr(info->function, nullptr));
|
||||||
auto layer = comp->asset(_idByName(args[0]));
|
auto layer = comp->root->layerById(_idByName(args[0]));
|
||||||
|
|
||||||
if (!layer) return jerry_undefined();
|
if (!layer) return jerry_undefined();
|
||||||
|
|
||||||
|
|
|
@ -413,7 +413,7 @@ void LottieLayer::prepare(RGB24* color)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float LottieLayer::remap(float frameNo, LottieExpressions* exp)
|
float LottieLayer::remap(LottieComposition* comp, float frameNo, LottieExpressions* exp)
|
||||||
{
|
{
|
||||||
if (timeRemap.frames || timeRemap.value) {
|
if (timeRemap.frames || timeRemap.value) {
|
||||||
frameNo = comp->frameAtTime(timeRemap(frameNo, exp));
|
frameNo = comp->frameAtTime(timeRemap(frameNo, exp));
|
||||||
|
|
|
@ -587,12 +587,12 @@ struct LottieLayer : LottieGroup, LottieRenderPooler<tvg::Shape>
|
||||||
bool mergeable() override { return false; }
|
bool mergeable() override { return false; }
|
||||||
|
|
||||||
void prepare(RGB24* color = nullptr);
|
void prepare(RGB24* color = nullptr);
|
||||||
float remap(float frameNo, LottieExpressions* exp);
|
float remap(LottieComposition* comp, float frameNo, LottieExpressions* exp);
|
||||||
|
|
||||||
char* name = nullptr;
|
char* name = nullptr;
|
||||||
LottieLayer* parent = nullptr;
|
LottieLayer* parent = nullptr;
|
||||||
LottieFloat timeRemap = 0.0f;
|
LottieFloat timeRemap = 0.0f;
|
||||||
LottieComposition* comp = nullptr;
|
LottieLayer* comp = nullptr; //Precompositor, current layer is belonges.
|
||||||
LottieTransform* transform = nullptr;
|
LottieTransform* transform = nullptr;
|
||||||
Array<LottieMask*> masks;
|
Array<LottieMask*> masks;
|
||||||
LottieLayer* matteTarget = nullptr;
|
LottieLayer* matteTarget = nullptr;
|
||||||
|
@ -619,9 +619,20 @@ struct LottieLayer : LottieGroup, LottieRenderPooler<tvg::Shape>
|
||||||
bool autoOrient = false;
|
bool autoOrient = false;
|
||||||
bool matteSrc = false;
|
bool matteSrc = false;
|
||||||
|
|
||||||
|
LottieLayer* layerById(unsigned long id)
|
||||||
|
{
|
||||||
|
for (auto child = children.begin(); child < children.end(); ++child) {
|
||||||
|
if ((*child)->type != LottieObject::Type::Layer) continue;
|
||||||
|
auto layer = static_cast<LottieLayer*>(*child);
|
||||||
|
if (layer->id == id) return layer;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
LottieLayer* layerByIdx(int16_t idx)
|
LottieLayer* layerByIdx(int16_t idx)
|
||||||
{
|
{
|
||||||
for (auto child = children.begin(); child < children.end(); ++child) {
|
for (auto child = children.begin(); child < children.end(); ++child) {
|
||||||
|
if ((*child)->type != LottieObject::Type::Layer) continue;
|
||||||
auto layer = static_cast<LottieLayer*>(*child);
|
auto layer = static_cast<LottieLayer*>(*child);
|
||||||
if (layer->idx == idx) return layer;
|
if (layer->idx == idx) return layer;
|
||||||
}
|
}
|
||||||
|
@ -679,30 +690,12 @@ struct LottieComposition
|
||||||
|
|
||||||
float timeAtFrame(float frameNo)
|
float timeAtFrame(float frameNo)
|
||||||
{
|
{
|
||||||
return (frameNo - startFrame) / frameRate;
|
return (frameNo - root->inFrame) / frameRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
float frameCnt() const
|
float frameCnt() const
|
||||||
{
|
{
|
||||||
return endFrame - startFrame;
|
return root->outFrame - root->inFrame;
|
||||||
}
|
|
||||||
|
|
||||||
LottieLayer* layerById(unsigned long id)
|
|
||||||
{
|
|
||||||
for (auto child = root->children.begin(); child < root->children.end(); ++child) {
|
|
||||||
auto layer = static_cast<LottieLayer*>(*child);
|
|
||||||
if (layer->id == id) return layer;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
LottieLayer* layerByIdx(int16_t idx)
|
|
||||||
{
|
|
||||||
for (auto child = root->children.begin(); child < root->children.end(); ++child) {
|
|
||||||
auto layer = static_cast<LottieLayer*>(*child);
|
|
||||||
if (layer->idx == idx) return layer;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LottieLayer* asset(unsigned long id)
|
LottieLayer* asset(unsigned long id)
|
||||||
|
@ -718,7 +711,6 @@ struct LottieComposition
|
||||||
char* version = nullptr;
|
char* version = nullptr;
|
||||||
char* name = nullptr;
|
char* name = nullptr;
|
||||||
float w, h;
|
float w, h;
|
||||||
float startFrame, endFrame;
|
|
||||||
float frameRate;
|
float frameRate;
|
||||||
Array<LottieObject*> assets;
|
Array<LottieObject*> assets;
|
||||||
Array<LottieInterpolator*> interpolators;
|
Array<LottieInterpolator*> interpolators;
|
||||||
|
|
|
@ -965,7 +965,7 @@ LottieObject* LottieParser::parseAsset()
|
||||||
id = _int2str(getInt());
|
id = _int2str(getInt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (KEY_AS("layers")) obj = parseLayers();
|
else if (KEY_AS("layers")) obj = parseLayers(comp->root);
|
||||||
else if (KEY_AS("u")) subPath = getString();
|
else if (KEY_AS("u")) subPath = getString();
|
||||||
else if (KEY_AS("p")) data = getString();
|
else if (KEY_AS("p")) data = getString();
|
||||||
else if (KEY_AS("w")) width = getFloat();
|
else if (KEY_AS("w")) width = getFloat();
|
||||||
|
@ -1236,11 +1236,11 @@ void LottieParser::parseMasks(LottieLayer* layer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LottieLayer* LottieParser::parseLayer()
|
LottieLayer* LottieParser::parseLayer(LottieLayer* precomp)
|
||||||
{
|
{
|
||||||
auto layer = new LottieLayer;
|
auto layer = new LottieLayer;
|
||||||
|
|
||||||
layer->comp = comp;
|
layer->comp = precomp;
|
||||||
context.layer = layer;
|
context.layer = layer;
|
||||||
|
|
||||||
auto ddd = false;
|
auto ddd = false;
|
||||||
|
@ -1295,20 +1295,20 @@ LottieLayer* LottieParser::parseLayer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LottieLayer* LottieParser::parseLayers()
|
LottieLayer* LottieParser::parseLayers(LottieLayer* root)
|
||||||
{
|
{
|
||||||
auto root = new LottieLayer;
|
auto precomp = new LottieLayer;
|
||||||
|
|
||||||
root->type = LottieLayer::Precomp;
|
precomp->type = LottieLayer::Precomp;
|
||||||
root->comp = comp;
|
precomp->comp = root;
|
||||||
|
|
||||||
enterArray();
|
enterArray();
|
||||||
while (nextArrayValue()) {
|
while (nextArrayValue()) {
|
||||||
root->children.push(parseLayer());
|
precomp->children.push(parseLayer(precomp));
|
||||||
}
|
}
|
||||||
|
|
||||||
root->prepare();
|
precomp->prepare();
|
||||||
return root;
|
return precomp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1396,16 +1396,19 @@ bool LottieParser::parse()
|
||||||
|
|
||||||
Array<LottieGlyph*> glyphs;
|
Array<LottieGlyph*> glyphs;
|
||||||
|
|
||||||
|
auto startFrame = 0.0f;
|
||||||
|
auto endFrame = 0.0f;
|
||||||
|
|
||||||
while (auto key = nextObjectKey()) {
|
while (auto key = nextObjectKey()) {
|
||||||
if (KEY_AS("v")) comp->version = getStringCopy();
|
if (KEY_AS("v")) comp->version = getStringCopy();
|
||||||
else if (KEY_AS("fr")) comp->frameRate = getFloat();
|
else if (KEY_AS("fr")) comp->frameRate = getFloat();
|
||||||
else if (KEY_AS("ip")) comp->startFrame = getFloat();
|
else if (KEY_AS("ip")) startFrame = getFloat();
|
||||||
else if (KEY_AS("op")) comp->endFrame = getFloat();
|
else if (KEY_AS("op")) endFrame = getFloat();
|
||||||
else if (KEY_AS("w")) comp->w = getFloat();
|
else if (KEY_AS("w")) comp->w = getFloat();
|
||||||
else if (KEY_AS("h")) comp->h = getFloat();
|
else if (KEY_AS("h")) comp->h = getFloat();
|
||||||
else if (KEY_AS("nm")) comp->name = getStringCopy();
|
else if (KEY_AS("nm")) comp->name = getStringCopy();
|
||||||
else if (KEY_AS("assets")) parseAssets();
|
else if (KEY_AS("assets")) parseAssets();
|
||||||
else if (KEY_AS("layers")) comp->root = parseLayers();
|
else if (KEY_AS("layers")) comp->root = parseLayers(comp->root);
|
||||||
else if (KEY_AS("fonts")) parseFonts();
|
else if (KEY_AS("fonts")) parseFonts();
|
||||||
else if (KEY_AS("chars")) parseChars(glyphs);
|
else if (KEY_AS("chars")) parseChars(glyphs);
|
||||||
else if (KEY_AS("markers")) parseMarkers();
|
else if (KEY_AS("markers")) parseMarkers();
|
||||||
|
@ -1417,8 +1420,8 @@ bool LottieParser::parse()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
comp->root->inFrame = comp->startFrame;
|
comp->root->inFrame = startFrame;
|
||||||
comp->root->outFrame = comp->endFrame;
|
comp->root->outFrame = endFrame;
|
||||||
|
|
||||||
postProcess(glyphs);
|
postProcess(glyphs);
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ private:
|
||||||
LottieObject* parseObject();
|
LottieObject* parseObject();
|
||||||
LottieObject* parseAsset();
|
LottieObject* parseAsset();
|
||||||
LottieImage* parseImage(const char* data, const char* subPath, bool embedded, float width, float height);
|
LottieImage* parseImage(const char* data, const char* subPath, bool embedded, float width, float height);
|
||||||
LottieLayer* parseLayer();
|
LottieLayer* parseLayer(LottieLayer* precomp);
|
||||||
LottieObject* parseGroup();
|
LottieObject* parseGroup();
|
||||||
LottieRect* parseRect();
|
LottieRect* parseRect();
|
||||||
LottieEllipse* parseEllipse();
|
LottieEllipse* parseEllipse();
|
||||||
|
@ -86,7 +86,7 @@ private:
|
||||||
LottiePolyStar* parsePolyStar();
|
LottiePolyStar* parsePolyStar();
|
||||||
LottieRoundedCorner* parseRoundedCorner();
|
LottieRoundedCorner* parseRoundedCorner();
|
||||||
LottieGradientFill* parseGradientFill();
|
LottieGradientFill* parseGradientFill();
|
||||||
LottieLayer* parseLayers();
|
LottieLayer* parseLayers(LottieLayer* root);
|
||||||
LottieMask* parseMask();
|
LottieMask* parseMask();
|
||||||
LottieTrimpath* parseTrimpath();
|
LottieTrimpath* parseTrimpath();
|
||||||
LottieRepeater* parseRepeater();
|
LottieRepeater* parseRepeater();
|
||||||
|
|
Loading…
Add table
Reference in a new issue