Revision control
Copy as Markdown
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
// Qt-Security score:significant reason:default
#include "qlottiepolystar_p.h"
#include <QJsonObject>
#include <QRectF>
#include <QString>
#include "qlottietrimpath_p.h"
QT_BEGIN_NAMESPACE
using namespace Qt::Literals::StringLiterals;
QLottiePolyStar::QLottiePolyStar(const QLottiePolyStar &other)
: QLottieShape(other)
{
m_position = other.m_position;
m_pointCount = other.m_pointCount;
m_outerRadius = other.m_outerRadius;
m_innerRadius = other.m_innerRadius;
m_startAngle = other.m_startAngle;
m_polygonMode = other.m_polygonMode;
}
QLottiePolyStar::QLottiePolyStar(QLottieBase *parent)
{
setParent(parent);
}
QLottieBase *QLottiePolyStar::clone() const
{
return new QLottiePolyStar(*this);
}
int QLottiePolyStar::parse(const QJsonObject &definition)
{
QLottieBase::parse(definition);
if (m_hidden)
return 0;
qCDebug(lcLottieQtLottieParser) << "QLottiePolyStar::parse():" << m_name;
if (!checkRequiredKeys(definition, "Polystar"_L1, {"p"_L1, "or"_L1, "os"_L1, "pt"_L1, "r"_L1}, m_name))
return -1;
QJsonObject position = definition.value("p"_L1).toObject();
position = resolveExpression(position);
m_position.construct(position);
QJsonObject outerRadius = definition.value("or"_L1).toObject();
outerRadius = resolveExpression(outerRadius);
m_outerRadius.construct(outerRadius);
if (definition.contains("ir"_L1)) {
QJsonObject innerRadius = definition.value("ir"_L1).toObject();
innerRadius = resolveExpression(innerRadius);
m_innerRadius.construct(innerRadius);
}
QJsonObject startAngle = definition.value("r"_L1).toObject();
startAngle = resolveExpression(startAngle);
m_startAngle.construct(startAngle);
QJsonObject pointCount = definition.value("pt"_L1).toObject();
pointCount = resolveExpression(pointCount);
m_pointCount.construct(pointCount);
m_polygonMode = (definition.value("sy"_L1).toInt() == 2);
m_direction = definition.value("d"_L1).toInt();
return 0;
}
bool QLottiePolyStar::acceptsTrim() const
{
return true;
}
void QLottiePolyStar::updateProperties(int frame)
{
m_position.update(frame);
m_outerRadius.update(frame);
m_innerRadius.update(frame);
m_startAngle.update(frame);
m_pointCount.update(frame);
buildPath();
}
void QLottiePolyStar::buildPath()
{
m_path.clear();
const int numPoints = m_pointCount.value();
if (numPoints < 1)
return;
const qreal angleStep = -360.0 / numPoints;
const qreal halfAngleStep = angleStep / 2;
qreal angle = 90 - m_startAngle.value();
const QPointF pos = m_position.value();
QLineF outLine(pos, QPointF(pos.x(), pos.y() - m_outerRadius.value()));
QLineF inLine(pos, QPointF(pos.x(), pos.y() - m_innerRadius.value()));
outLine.setAngle(angle);
const QPointF startPt = outLine.p2();
m_path.moveTo(startPt);
for (int i = 0; i < numPoints; i++) {
if (!m_polygonMode) {
inLine.setAngle(angle + halfAngleStep);
m_path.lineTo(inLine.p2());
}
angle += angleStep;
outLine.setAngle(angle);
m_path.lineTo(outLine.p2());
}
// Fix potential accuracy errors, ensuring path is closed:
m_path.setElementPositionAt(m_path.elementCount() - 1, startPt.x(), startPt.y());
if (hasReversedDirection())
m_path = m_path.toReversed();
}
void QLottiePolyStar::render(QLottieRenderer &renderer) const
{
renderer.render(*this);
}
QPointF QLottiePolyStar::position() const
{
return m_position.value();
}
qreal QLottiePolyStar::outerRadius() const
{
return m_outerRadius.value();
}
qreal QLottiePolyStar::innerRadius() const
{
return m_innerRadius.value();
}
qreal QLottiePolyStar::startAngle() const
{
return m_startAngle.value();
}
int QLottiePolyStar::pointCount() const
{
return m_pointCount.value();
}
bool QLottiePolyStar::isPolygonModeEnabled() const
{
return m_polygonMode;
}
QPainterPath QLottiePolyStar::fallbackPath() const
{
QLottiePolyStar copy(*this);
copy.m_outerRadius.setValue(0.5);
copy.m_innerRadius.setValue(0.5);
copy.buildPath();
return copy.path();
}
bool QLottiePolyStar::isAnimated() const
{
return m_outerRadius.isAnimated() || m_innerRadius.isAnimated()
|| m_position.isAnimated() || m_startAngle.isAnimated()
|| m_pointCount.isAnimated();
}
QT_END_NAMESPACE