Revision control
Copy as Markdown
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
// Qt-Security score:significant reason:default
#include "qlottieprecomplayer_p.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <QLoggingCategory>
#include <QString>
#include "qlottiebasictransform_p.h"
#include "qlottieprecomposition_p.h"
#include "qlottierenderer_p.h"
#include "qlottieroot_p.h"
QT_BEGIN_NAMESPACE
using namespace Qt::Literals::StringLiterals;
QLottiePrecompLayer::QLottiePrecompLayer(const QLottiePrecompLayer &other)
: QLottieLayer(other)
{
m_refId = other.m_refId;
m_timeRemap = other.m_timeRemap;
}
QLottieBase *QLottiePrecompLayer::clone() const
{
return new QLottiePrecompLayer(*this);
}
void QLottiePrecompLayer::updateProperties(int frame)
{
if (m_hasLinkedLayer)
resolveLinkedLayer();
m_isActive = active(frame);
if (!m_isActive)
return;
// Update first effects, as they are not children of the layer
if (m_effects) {
for (QLottieBase* effect : m_effects->children())
effect->updateProperties(frame);
}
if (m_layerTransform)
m_layerTransform->updateProperties(frame);
int adjFrame = frame;
if (m_timeRemap.isAnimated()) {
m_timeRemap.update(frame);
int frameRate = 30;
const QLottieBase *root = topRoot();
if (Q_LIKELY(root && root->type() == LOTTIE_ROOT_IX))
frameRate = static_cast<const QLottieRoot *>(root)->frameRate();
adjFrame = qRound(m_timeRemap.value() * frameRate);
} else if (m_startTime || m_stretch) {
if (m_stretch)
adjFrame = qRound((frame - m_startTime) / m_stretch);
else
adjFrame = qRound(frame - m_startTime);
}
QLottieBase::updateProperties(adjFrame);
}
void QLottiePrecompLayer::render(QLottieRenderer &renderer) const
{
if (!m_isActive)
return;
renderer.saveState();
QLottieLayer::render(renderer);
renderer.finish(*this);
renderer.restoreState();
}
int QLottiePrecompLayer::parse(const QJsonObject &definition)
{
m_type = LOTTIE_LAYER_PRECOMP_IX;
QLottieLayer::parse(definition);
if (m_hidden)
return 0;
qCDebug(lcLottieQtLottieParser) << "QLottiePrecompLayer::parse()" << m_name;
if (!checkRequiredKeys(definition, "Precomp Layer"_L1, { "refId"_L1 }, m_name))
return -1;
m_refId = definition.value("refId"_L1).toString();
m_startTime = definition.value("st"_L1).toDouble(); // only relevant for precomp layers
m_stretch = definition.value("sr"_L1).toDouble(); // only relevant for precomp layers
QJsonObject timeRemap = definition.value("tm"_L1).toObject();
timeRemap = resolveExpression(timeRemap);
m_timeRemap.construct(timeRemap);
m_size = QSize(definition.value("w"_L1).toInt(-1), definition.value("h"_L1).toInt(-1));
qCDebug(lcLottieQtLottieParser) << "QLottiePrecompLayer created for refId" << m_refId;
return 0;
}
QT_END_NAMESPACE