diff --git a/Telegram/ThirdParty/qtlottie b/Telegram/ThirdParty/qtlottie index 2fa825bfd9..f95d9f5260 160000 --- a/Telegram/ThirdParty/qtlottie +++ b/Telegram/ThirdParty/qtlottie @@ -1 +1 @@ -Subproject commit 2fa825bfd9384b864e79861e8fa41273da8ab973 +Subproject commit f95d9f5260af2dcf1e724d1d0814bd9176149b76 diff --git a/Telegram/ThirdParty/qtlottie_helper/QtBodymovin/private/bmproperty_p.h b/Telegram/ThirdParty/qtlottie_helper/QtBodymovin/private/bmproperty_p.h index 381a52b381..eea4a0ad83 100644 --- a/Telegram/ThirdParty/qtlottie_helper/QtBodymovin/private/bmproperty_p.h +++ b/Telegram/ThirdParty/qtlottie_helper/QtBodymovin/private/bmproperty_p.h @@ -69,7 +69,6 @@ struct EasingSegment { T startValue; T endValue; BezierEasing easing; - QPainterPath bezier; double bezierLength = 0.; struct BezierPoint { @@ -85,7 +84,7 @@ class BODYMOVIN_EXPORT BMProperty public: virtual ~BMProperty() = default; - virtual void construct(const QJsonObject &definition) + void construct(const QJsonObject &definition) { if (definition.value(QStringLiteral("s")).toVariant().toInt()) qCWarning(lcLottieQtBodymovinParser) @@ -210,7 +209,7 @@ protected: return m_currentEasing; } - virtual EasingSegment parseKeyframe(const QJsonObject keyframe) + EasingSegment parseKeyframe(const QJsonObject keyframe) { EasingSegment easing; @@ -251,23 +250,36 @@ protected: QJsonObject easingIn = keyframe.value(QStringLiteral("i")).toObject(); QJsonObject easingOut = keyframe.value(QStringLiteral("o")).toObject(); - qreal eix = easingIn.value(QStringLiteral("x")).toArray().at(0).toDouble(); - qreal eiy = easingIn.value(QStringLiteral("y")).toArray().at(0).toDouble(); + if (easingIn.value(QStringLiteral("x")).isArray()) { + qreal eix = easingIn.value(QStringLiteral("x")).toArray().at(0).toDouble(); + qreal eiy = easingIn.value(QStringLiteral("y")).toArray().at(0).toDouble(); - qreal eox = easingOut.value(QStringLiteral("x")).toArray().at(0).toDouble(); - qreal eoy = easingOut.value(QStringLiteral("y")).toArray().at(0).toDouble(); + qreal eox = easingOut.value(QStringLiteral("x")).toArray().at(0).toDouble(); + qreal eoy = easingOut.value(QStringLiteral("y")).toArray().at(0).toDouble(); - QPointF c1 = QPointF(eox, eoy); - QPointF c2 = QPointF(eix, eiy); + QPointF c1 = QPointF(eox, eoy); + QPointF c2 = QPointF(eix, eiy); - easing.easing.addCubicBezierSegment(c1, c2, QPointF(1.0, 1.0)); + easing.easing.addCubicBezierSegment(c1, c2, QPointF(1.0, 1.0)); + } else { + qreal eix = easingIn.value(QStringLiteral("x")).toDouble(); + qreal eiy = easingIn.value(QStringLiteral("y")).toDouble(); + + qreal eox = easingOut.value(QStringLiteral("x")).toDouble(); + qreal eoy = easingOut.value(QStringLiteral("y")).toDouble(); + + QPointF c1 = QPointF(eox, eoy); + QPointF c2 = QPointF(eix, eiy); + + easing.easing.addCubicBezierSegment(c1, c2, QPointF(1.0, 1.0)); + } return easing; } virtual void postprocessEasingCurve( EasingSegment &easing, - const QJsonObject keyframe) { + const QJsonObject &keyframe) { } virtual T getValue(const QJsonValue &value) @@ -302,10 +314,9 @@ protected: const EasingSegment *m_currentEasing = nullptr; int m_startFrame = INT_MAX; int m_endFrame = 0; - T m_value; + T m_value = T(); }; - template class BODYMOVIN_EXPORT BMProperty2D : public BMProperty { @@ -318,95 +329,6 @@ protected: else return T(); } - - EasingSegment parseKeyframe(const QJsonObject keyframe) override - { - QJsonArray startValues = keyframe.value(QStringLiteral("s")).toArray(); - QJsonArray endValues = keyframe.value(QStringLiteral("e")).toArray(); - int startTime = keyframe.value(QStringLiteral("t")).toVariant().toInt(); - - EasingSegment easingCurve; - easingCurve.startFrame = startTime; - - // AE exported Bodymovin file includes the last - // key frame but no other properties. - // No need to process in that case - if (startValues.isEmpty() && endValues.isEmpty()) { - // In this case start time is the last frame for the property - this->m_endFrame = startTime; - easingCurve.startFrame = startTime; - easingCurve.endFrame = startTime; - easingCurve.state = EasingSegmentState::Final; - if (this->m_easingCurves.length()) { - const EasingSegment &last = this->m_easingCurves.last(); - if (last.state == EasingSegmentState::Complete) { - easingCurve.startValue = last.endValue; - easingCurve.endValue = last.endValue; - } else { - qCWarning(lcLottieQtBodymovinParser()) - << "Last keyframe found after an incomplete one"; - } - } - return easingCurve; - } - - if (this->m_startFrame > startTime) - this->m_startFrame = startTime; - - qreal xs, ys; - xs = startValues.at(0).toDouble(); - ys = startValues.at(1).toDouble(); - T s(xs, ys); - - QJsonObject easingIn = keyframe.value(QStringLiteral("i")).toObject(); - QJsonObject easingOut = keyframe.value(QStringLiteral("o")).toObject(); - - easingCurve.startFrame = startTime; - easingCurve.startValue = s; - if (!endValues.isEmpty()) { - qreal xe, ye; - xe = endValues.at(0).toDouble(); - ye = endValues.at(1).toDouble(); - T e(xe, ye); - easingCurve.endValue = e; - easingCurve.state = EasingSegmentState::Complete; - } - - if (easingIn.value(QStringLiteral("x")).isArray()) { - QJsonArray eixArr = easingIn.value(QStringLiteral("x")).toArray(); - QJsonArray eiyArr = easingIn.value(QStringLiteral("y")).toArray(); - - QJsonArray eoxArr = easingOut.value(QStringLiteral("x")).toArray(); - QJsonArray eoyArr = easingOut.value(QStringLiteral("y")).toArray(); - - if (!eixArr.isEmpty() && !eiyArr.isEmpty()) { - qreal eix = eixArr.takeAt(0).toDouble(); - qreal eiy = eiyArr.takeAt(0).toDouble(); - - qreal eox = eoxArr.takeAt(0).toDouble(); - qreal eoy = eoyArr.takeAt(0).toDouble(); - - QPointF c1 = QPointF(eox, eoy); - QPointF c2 = QPointF(eix, eiy); - - easingCurve.easing.addCubicBezierSegment(c1, c2, QPointF(1.0, 1.0)); - } - } - else { - qreal eix = easingIn.value(QStringLiteral("x")).toDouble(); - qreal eiy = easingIn.value(QStringLiteral("y")).toDouble(); - - qreal eox = easingOut.value(QStringLiteral("x")).toDouble(); - qreal eoy = easingOut.value(QStringLiteral("y")).toDouble(); - - QPointF c1 = QPointF(eox, eoy); - QPointF c2 = QPointF(eix, eiy); - - easingCurve.easing.addCubicBezierSegment(c1, c2, QPointF(1.0, 1.0)); - } - - return easingCurve; - } }; template diff --git a/Telegram/ThirdParty/qtlottie_helper/QtBodymovin/private/bmspatialproperty_p.h b/Telegram/ThirdParty/qtlottie_helper/QtBodymovin/private/bmspatialproperty_p.h index 55c85e04d4..45bd7a9d0e 100644 --- a/Telegram/ThirdParty/qtlottie_helper/QtBodymovin/private/bmspatialproperty_p.h +++ b/Telegram/ThirdParty/qtlottie_helper/QtBodymovin/private/bmspatialproperty_p.h @@ -51,15 +51,9 @@ QT_BEGIN_NAMESPACE class BMSpatialProperty : public BMProperty2D { public: - virtual void construct(const QJsonObject &definition) override - { - qCDebug(lcLottieQtBodymovinParser) << "BMSpatialProperty::construct()"; - BMProperty2D::construct(definition); - } - virtual void postprocessEasingCurve( EasingSegment &easing, - const QJsonObject keyframe) override { + const QJsonObject &keyframe) override { // No need to parse further incomplete keyframes (i.e. last keyframes) if (easing.state != EasingSegmentState::Complete) { return; @@ -83,15 +77,14 @@ public: c1 += s; c2 += e; - easing.bezier.moveTo(s); - easing.bezier.cubicTo(c1, c2, e); + QBezier bezier = QBezier::fromPoints(s, c1, c2, e); const auto kCount = 150; easing.bezierPoints.reserve(kCount); for (auto k = 0; k < kCount; ++k) { const auto percent = double(k) / (kCount - 1.); auto point = EasingSegment::BezierPoint(); - point.point = easing.bezier.pointAtPercent(percent); + point.point = bezier.pointAt(percent); if (k > 0) { const auto delta = (point.point - easing.bezierPoints[k - 1].point); point.length = std::sqrt(QPointF::dotProduct(delta, delta));