diff --git a/.bazelrc b/.bazelrc index 5325dfd50d..43ccf92e1f 100644 --- a/.bazelrc +++ b/.bazelrc @@ -11,8 +11,10 @@ build --per_file_copt="third-party/webrtc/.*\.cpp$","@-std=c++17" build --per_file_copt="third-party/webrtc/.*\.cc$","@-std=c++17" build --per_file_copt="third-party/webrtc/.*\.mm$","@-std=c++17" build --per_file_copt="submodules/LottieMeshSwift/LottieMeshBinding/Sources/.*\.mm$","@-std=c++17" -build --per_file_copt="submodules/TelegramUI/Components/LottieCpp/Sources/.*\.mm$","@-std=c++17" -build --per_file_copt="submodules/TelegramUI/Components/LottieCpp/Sources/.*\.cpp$","@-std=c++17" +build --per_file_copt="submodules/LottieCpp/lottiecpp/Sources/.*\.mm$","@-std=c++17" +build --per_file_copt="submodules/LottieCpp/lottiecpp/Sources/.*\.cpp$","@-std=c++17" +build --per_file_copt="submodules/LottieCpp/lottiecpp/PlatformSpecific/Darwin/Sources/.*\.mm$","@-std=c++17" +build --per_file_copt="submodules/LottieCpp/lottiecpp/PlatformSpecific/Darwin/Sources/.*\.cpp$","@-std=c++17" build --per_file_copt="Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/.*\.cpp$","@-std=c++17" build --per_file_copt="Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/.*\.mm$","@-std=c++17" diff --git a/Tests/LottieMetalTest/BUILD b/Tests/LottieMetalTest/BUILD index 1e9987af9f..bc5d916de6 100644 --- a/Tests/LottieMetalTest/BUILD +++ b/Tests/LottieMetalTest/BUILD @@ -49,7 +49,7 @@ swift_library( deps = [ "//submodules/Display", "//submodules/MetalEngine", - "//submodules/TelegramUI/Components/LottieCpp", + "//submodules/LottieCpp", "//submodules/TelegramUI/Components/LottieMetal", "//submodules/rlottie:RLottieBinding", "//Tests/LottieMetalTest/QOILoader", diff --git a/Tests/LottieMetalTest/SoftwareLottieRenderer/BUILD b/Tests/LottieMetalTest/SoftwareLottieRenderer/BUILD index 0aedc6e7b2..df62415519 100644 --- a/Tests/LottieMetalTest/SoftwareLottieRenderer/BUILD +++ b/Tests/LottieMetalTest/SoftwareLottieRenderer/BUILD @@ -23,7 +23,7 @@ objc_library( "PublicHeaders", ], deps = [ - "//submodules/TelegramUI/Components/LottieCpp", + "//submodules/LottieCpp", "//Tests/LottieMetalTest/thorvg", ], sdk_frameworks = [ diff --git a/Tests/LottieMetalTest/SoftwareLottieRenderer/PublicHeaders/SoftwareLottieRenderer/SoftwareLottieRenderer.h b/Tests/LottieMetalTest/SoftwareLottieRenderer/PublicHeaders/SoftwareLottieRenderer/SoftwareLottieRenderer.h index 4293902250..42615a7219 100644 --- a/Tests/LottieMetalTest/SoftwareLottieRenderer/PublicHeaders/SoftwareLottieRenderer/SoftwareLottieRenderer.h +++ b/Tests/LottieMetalTest/SoftwareLottieRenderer/PublicHeaders/SoftwareLottieRenderer/SoftwareLottieRenderer.h @@ -5,6 +5,7 @@ #import #import +#import #ifdef __cplusplus extern "C" { diff --git a/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/Canvas.h b/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/Canvas.h index 32a02bfc8a..ef420a5071 100644 --- a/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/Canvas.h +++ b/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/Canvas.h @@ -3,6 +3,8 @@ #include +#include + #include #include #include diff --git a/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/CoreGraphicsCanvasImpl.mm b/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/CoreGraphicsCanvasImpl.mm index 38f95beb72..a798d2feb7 100644 --- a/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/CoreGraphicsCanvasImpl.mm +++ b/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/CoreGraphicsCanvasImpl.mm @@ -1,5 +1,8 @@ #include "CoreGraphicsCanvasImpl.h" +#include +#include + namespace lottieRendering { namespace { diff --git a/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/SoftwareLottieRenderer.mm b/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/SoftwareLottieRenderer.mm index 8c0e3bc75c..a2f51e674a 100644 --- a/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/SoftwareLottieRenderer.mm +++ b/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/SoftwareLottieRenderer.mm @@ -6,6 +6,9 @@ #import "NullCanvasImpl.h" #include +#include +#include +#include namespace { diff --git a/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/ThorVGCanvasImpl.mm b/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/ThorVGCanvasImpl.mm index 4be6064df2..3405a31b3a 100644 --- a/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/ThorVGCanvasImpl.mm +++ b/Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/ThorVGCanvasImpl.mm @@ -1,5 +1,8 @@ #include "ThorVGCanvasImpl.h" +#include +#include + namespace lottieRendering { namespace { diff --git a/submodules/LottieCpp/BUILD b/submodules/LottieCpp/BUILD new file mode 100644 index 0000000000..8a1b9b096f --- /dev/null +++ b/submodules/LottieCpp/BUILD @@ -0,0 +1,56 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +objc_library( + name = "LottieCpp", + enable_modules = True, + module_name = "LottieCpp", + srcs = glob([ + "lottiecpp/Sources/**/*.m", + "lottiecpp/Sources/**/*.mm", + "lottiecpp/Sources/**/*.h", + "lottiecpp/Sources/**/*.c", + "lottiecpp/Sources/**/*.cpp", + "lottiecpp/Sources/**/*.hpp", + "lottiecpp/PlatformSpecific/Darwin/Sources/**/*.m", + "lottiecpp/PlatformSpecific/Darwin/Sources/**/*.mm", + "lottiecpp/PlatformSpecific/Darwin/Sources/**/*.h", + "lottiecpp/PlatformSpecific/Darwin/Sources/**/*.c", + "lottiecpp/PlatformSpecific/Darwin/Sources/**/*.cpp", + "lottiecpp/PlatformSpecific/Darwin/Sources/**/*.hpp", + ]), + copts = [ + "-Werror", + "-I{}/lottiecpp/Sources".format(package_name()), + ], + hdrs = glob([ + "lottiecpp/PublicHeaders/**/*.h", + "lottiecpp/PlatformSpecific/Darwin/PublicHeaders/**/*.h", + ]), + includes = [ + "lottiecpp/PublicHeaders", + "lottiecpp/PlatformSpecific/Darwin/PublicHeaders", + ], + deps = [ + ], + sdk_frameworks = [ + "Foundation", + ], + visibility = [ + "//visibility:public", + ], +) + +cc_library( + name = "LottieCppBinding", + srcs = [], + hdrs = glob([ + "lottiecpp/PublicHeaders/**/*.h", + "lottiecpp/PlatformSpecific/Darwin/PublicHeaders/**/*.h", + ]), + includes = [ + "PublicHeaders", + ], + copts = [], + visibility = ["//visibility:public"], + linkstatic = 1, +) diff --git a/submodules/LottieCpp/lottiecpp b/submodules/LottieCpp/lottiecpp index 61d31342c1..a540e0d91a 160000 --- a/submodules/LottieCpp/lottiecpp +++ b/submodules/LottieCpp/lottiecpp @@ -1 +1 @@ -Subproject commit 61d31342c1289854326cbb3d9dedfbb9b3513a5b +Subproject commit a540e0d91a9cbe91968798310d515496c85bc043 diff --git a/submodules/TelegramUI/Components/LottieCpp/BUILD b/submodules/TelegramUI/Components/LottieCpp/BUILD deleted file mode 100644 index 9743934e12..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/BUILD +++ /dev/null @@ -1,48 +0,0 @@ -load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") - -objc_library( - name = "LottieCpp", - enable_modules = True, - module_name = "LottieCpp", - srcs = glob([ - "Sources/**/*.m", - "Sources/**/*.mm", - "Sources/**/*.h", - "Sources/**/*.c", - "Sources/**/*.cpp", - "Sources/**/*.hpp", - ]), - copts = [ - "-Werror", - "-I{}/Sources".format(package_name()), - ], - hdrs = glob([ - "PublicHeaders/**/*.h", - ]), - includes = [ - "PublicHeaders", - ], - deps = [ - ], - sdk_frameworks = [ - "Foundation", - ], - visibility = [ - "//visibility:public", - ], -) - -cc_library( - name = "LottieCppBinding", - srcs = [], - hdrs = glob([ - "PublicHeaders/**/*.h", - ]), - includes = [ - "PublicHeaders", - ], - copts = [], - visibility = ["//visibility:public"], - linkstatic = 1, - tags = ["swift_module=LottieCppBinding"], -) diff --git a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/BezierPath.h b/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/BezierPath.h deleted file mode 100644 index b61a7ce1c2..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/BezierPath.h +++ /dev/null @@ -1,180 +0,0 @@ -#ifndef BezierPath_h -#define BezierPath_h - -#ifdef __cplusplus - -#include -#include -#include -#include - -#include - -namespace lottie { - -struct BezierTrimPathPosition { - float start; - float end; - - explicit BezierTrimPathPosition(float start_, float end_); -}; - -class BezierPathContents: public std::enable_shared_from_this { -public: - explicit BezierPathContents(CurveVertex const &startPoint); - - BezierPathContents(); - - explicit BezierPathContents(lottiejson11::Json const &jsonAny) noexcept(false); - - BezierPathContents(const BezierPathContents&) = delete; - BezierPathContents& operator=(BezierPathContents&) = delete; - - lottiejson11::Json toJson() const; - - std::shared_ptr cgPath() const; - -public: - std::vector elements; - std::optional closed; - - float length(); - -private: - std::optional _length; - -public: - void moveToStartPoint(CurveVertex const &vertex); - void addVertex(CurveVertex const &vertex); - - void reserveCapacity(size_t capacity); - void setElementCount(size_t count); - void invalidateLength(); - - void addCurve(Vector2D const &toPoint, Vector2D const &outTangent, Vector2D const &inTangent); - void addLine(Vector2D const &toPoint); - void close(); - void addElement(PathElement const &pathElement); - void updateVertex(CurveVertex const &vertex, int atIndex, bool remeasure); - - /// Trims a path fromLength toLength with an offset. - /// - /// Length and offset are defined in the length coordinate space. - /// If any argument is outside the range of this path, then it will be looped over the path from finish to start. - /// - /// Cutting the curve when fromLength is less than toLength - /// x x x x - /// ~~~~~~~~~~~~~~~ooooooooooooooooooooooooooooooooooooooooooooooooo------------------- - /// |Offset |fromLength toLength| | - /// - /// Cutting the curve when from Length is greater than toLength - /// x x x x x - /// oooooooooooooooooo--------------------~~~~~~~~~~~~~~~~ooooooooooooooooooooooooooooo - /// | toLength| |Offset |fromLength | - /// - std::vector> trim(float fromLength, float toLength, float offsetLength); - - // MARK: Private - - std::vector> trimPathAtLengths(std::vector const &positions); -}; - -class BezierPath { -public: - explicit BezierPath(CurveVertex const &startPoint); - BezierPath(); - explicit BezierPath(lottiejson11::Json const &jsonAny) noexcept(false); - - lottiejson11::Json toJson() const; - - float length(); - - void moveToStartPoint(CurveVertex const &vertex); - void addVertex(CurveVertex const &vertex); - void reserveCapacity(size_t capacity); - void setElementCount(size_t count); - void invalidateLength(); - void addCurve(Vector2D const &toPoint, Vector2D const &outTangent, Vector2D const &inTangent); - void addLine(Vector2D const &toPoint); - void close(); - void addElement(PathElement const &pathElement); - void updateVertex(CurveVertex const &vertex, int atIndex, bool remeasure); - - /// Trims a path fromLength toLength with an offset. - /// - /// Length and offset are defined in the length coordinate space. - /// If any argument is outside the range of this path, then it will be looped over the path from finish to start. - /// - /// Cutting the curve when fromLength is less than toLength - /// x x x x - /// ~~~~~~~~~~~~~~~ooooooooooooooooooooooooooooooooooooooooooooooooo------------------- - /// |Offset |fromLength toLength| | - /// - /// Cutting the curve when from Length is greater than toLength - /// x x x x x - /// oooooooooooooooooo--------------------~~~~~~~~~~~~~~~~ooooooooooooooooooooooooooooo - /// | toLength| |Offset |fromLength | - /// - std::vector trim(float fromLength, float toLength, float offsetLength); - - std::vector const &elements() const; - std::vector &mutableElements(); - std::optional const &closed() const; - void setClosed(std::optional const &closed); - std::shared_ptr cgPath() const; - BezierPath copyUsingTransform(Transform2D const &transform) const; - -public: - BezierPath(std::shared_ptr contents); - -public: - std::shared_ptr _contents; -}; - -class PathContents { -public: - struct Element { - Vector2D point; - Vector2D cp1; - Vector2D cp2; - - explicit Element(Vector2D const &point_, Vector2D const &cp1_, Vector2D const &cp2_) : - point(point_), - cp1(cp1_), - cp2(cp2_) { - } - }; - -public: - PathContents(BezierPathContents const &bezierPath); - ~PathContents(); - - std::shared_ptr bezierPath() const; - -private: - std::vector _elements; - bool _isClosed = false; -}; - -class BezierPathsBoundingBoxContext { -public: - BezierPathsBoundingBoxContext(); - ~BezierPathsBoundingBoxContext(); - -public: - float *pointsX = nullptr; - float *pointsY = nullptr; - int pointsSize = 0; -}; - -CGRect bezierPathsBoundingBox(std::vector const &paths); -CGRect bezierPathsBoundingBoxParallel(BezierPathsBoundingBoxContext &context, std::vector const &paths); -CGRect bezierPathsBoundingBoxParallel(BezierPathsBoundingBoxContext &context, BezierPath const &path); - -std::vector trimBezierPaths(std::vector &sourcePaths, float start, float end, float offset, TrimType type); - -} - -#endif - -#endif /* BezierPath_h */ diff --git a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/CGPath.h b/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/CGPath.h deleted file mode 100644 index 1ddeeb81ed..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/CGPath.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef CGPath_hpp -#define CGPath_hpp - -#ifdef __cplusplus - -#include - -#include -#include - -namespace lottie { - -struct CGPathItem { - enum class Type { - MoveTo, - LineTo, - CurveTo, - Close - }; - - Type type; - Vector2D points[3] = { Vector2D(0.0, 0.0), Vector2D(0.0, 0.0), Vector2D(0.0, 0.0) }; - - explicit CGPathItem(Type type_) : - type(type_) { - } - - bool operator==(const CGPathItem &rhs) const { - if (type != rhs.type) { - return false; - } - if (points[0] != rhs.points[0]) { - return false; - } - if (points[1] != rhs.points[1]) { - return false; - } - if (points[2] != rhs.points[2]) { - return false; - } - - return true; - } - - bool operator!=(const CGPathItem &rhs) const { - return !(*this == rhs); - } -}; - -class CGPath { -public: - static std::shared_ptr makePath(); - - virtual ~CGPath() = default; - - virtual CGRect boundingBox() const = 0; - - virtual bool empty() const = 0; - - virtual std::shared_ptr copyUsingTransform(Transform2D const &transform) const = 0; - - virtual void addLineTo(Vector2D const &point) = 0; - virtual void addCurveTo(Vector2D const &point, Vector2D const &control1, Vector2D const &control2) = 0; - virtual void moveTo(Vector2D const &point) = 0; - virtual void closeSubpath() = 0; - virtual void addRect(CGRect const &rect) = 0; - virtual void addPath(std::shared_ptr const &path) = 0; - - virtual void enumerate(std::function) = 0; - - virtual bool isEqual(CGPath *other) const = 0; -}; - -Vector2D transformVector(Vector2D const &v, Transform2D const &m); - -} - -#endif - -#endif /* CGPath_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/CGPathCocoa.h b/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/CGPathCocoa.h deleted file mode 100644 index af32f20bb5..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/CGPathCocoa.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef CGPathCocoa_h -#define CGPathCocoa_h - -#ifdef __cplusplus - -#include - -#include -#include - -CGRect calculatePathBoundingBox(CGPathRef path); - -namespace lottie { - -class CGPathCocoaImpl: public CGPath { -public: - CGPathCocoaImpl(); - explicit CGPathCocoaImpl(CGMutablePathRef path); - virtual ~CGPathCocoaImpl(); - - virtual CGRect boundingBox() const override; - - virtual bool empty() const override; - - virtual std::shared_ptr copyUsingTransform(Transform2D const &transform) const override; - - virtual void addLineTo(Vector2D const &point) override; - virtual void addCurveTo(Vector2D const &point, Vector2D const &control1, Vector2D const &control2) override; - virtual void moveTo(Vector2D const &point) override; - virtual void closeSubpath() override; - virtual void addRect(CGRect const &rect) override; - virtual void addPath(std::shared_ptr const &path) override; - virtual CGPathRef nativePath() const; - virtual bool isEqual(CGPath *other) const override; - virtual void enumerate(std::function) override; - - static void withNativePath(std::shared_ptr const &path, std::function f); - -private: - ::CGMutablePathRef _path = nil; -}; - -} - -#endif - -#endif /* CGPathCocoa_h */ diff --git a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/Color.h b/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/Color.h deleted file mode 100644 index 6e404f29ae..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/Color.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef LottieColor_h -#define LottieColor_h - -#ifdef __cplusplus - -#include -#include - -namespace lottie { - -enum class ColorFormatDenominator { - One, - OneHundred, - TwoFiftyFive -}; - -struct Color { - float r; - float g; - float b; - float a; - - bool operator==(Color const &rhs) const { - if (r != rhs.r) { - return false; - } - if (g != rhs.g) { - return false; - } - if (b != rhs.b) { - return false; - } - if (a != rhs.a) { - return false; - } - return true; - } - - bool operator!=(Color const &rhs) const { - return !(*this == rhs); - } - - explicit Color(float r_, float g_, float b_, float a_, ColorFormatDenominator denominator = ColorFormatDenominator::One); - explicit Color(lottiejson11::Json const &jsonAny) noexcept(false); - - lottiejson11::Json toJson() const; - - static Color fromString(std::string const &string); -}; - -} - -#endif - -#endif /* LottieColor_h */ diff --git a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/CurveVertex.h b/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/CurveVertex.h deleted file mode 100644 index 90e3ccf305..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/CurveVertex.h +++ /dev/null @@ -1,200 +0,0 @@ -#ifndef CurveVertex_h -#define CurveVertex_h - -#ifdef __cplusplus - -#include -#include - -#include - -namespace lottie { - -template -struct CurveVertexSplitResult { - T start; - T trimPoint; - T end; - - explicit CurveVertexSplitResult( - T const &start_, - T const &trimPoint_, - T const &end_ - ) : - start(start_), - trimPoint(trimPoint_), - end(end_) { - } -}; - -/// A single vertex with an in and out tangent -struct __attribute__((packed)) CurveVertex { -private: - /// Initializes a curve point with absolute or relative values - explicit CurveVertex(Vector2D const &point_, Vector2D const &inTangent_, Vector2D const &outTangent_, bool isRelative_) : - point(point_), - inTangent(isRelative_ ? (point_ + inTangent_) : inTangent_), - outTangent(isRelative_ ? (point_ + outTangent_) : outTangent_) { - } - -public: - static CurveVertex absolute(Vector2D const &point_, Vector2D const &inTangent_, Vector2D const &outTangent_) { - return CurveVertex(point_, inTangent_, outTangent_, false); - } - - static CurveVertex relative(Vector2D const &point_, Vector2D const &inTangent_, Vector2D const &outTangent_) { - return CurveVertex(point_, inTangent_, outTangent_, true); - } - - Vector2D inTangentRelative() const { - Vector2D result = inTangent - point; - return result; - } - - Vector2D outTangentRelative() const { - Vector2D result = outTangent - point; - return result; - } - - CurveVertex reversed() const { - return CurveVertex(point, outTangent, inTangent, false); - } - - CurveVertex translated(Vector2D const &translation) const { - return CurveVertex(point + translation, inTangent + translation, outTangent + translation, false); - } - - CurveVertex transformed(Transform2D const &transform) const { - return CurveVertex(transformVector(point, transform), transformVector(inTangent, transform), transformVector(outTangent, transform), false); - } - -public: - Vector2D point = Vector2D::Zero(); - Vector2D inTangent = Vector2D::Zero(); - Vector2D outTangent = Vector2D::Zero(); - - /// Trims a path defined by two Vertices at a specific position, from 0 to 1 - /// - /// The path can be visualized below. - /// - /// F is fromVertex. - /// V is the vertex of the receiver. - /// P is the position from 0-1. - /// O is the outTangent of fromVertex. - /// F====O=========P=======I====V - /// - /// After trimming the curve can be visualized below. - /// - /// S is the returned Start vertex. - /// E is the returned End vertex. - /// T is the trim point. - /// TI and TO are the new tangents for the trimPoint - /// NO and NI are the new tangents for the startPoint and endPoints - /// S==NO=========TI==T==TO=======NI==E - CurveVertexSplitResult splitCurve(CurveVertex const &toVertex, float position) const { - /// If position is less than or equal to 0, trim at start. - if (position <= 0.0) { - return CurveVertexSplitResult( - CurveVertex(point, inTangentRelative(), Vector2D::Zero(), true), - CurveVertex(point, Vector2D::Zero(), outTangentRelative(), true), - toVertex - ); - } - - /// If position is greater than or equal to 1, trim at end. - if (position >= 1.0) { - return CurveVertexSplitResult( - *this, - CurveVertex(toVertex.point, toVertex.inTangentRelative(), Vector2D::Zero(), true), - CurveVertex(toVertex.point, Vector2D::Zero(), toVertex.outTangentRelative(), true) - ); - } - - if (outTangentRelative().isZero() && toVertex.inTangentRelative().isZero()) { - /// If both tangents are zero, then span to be trimmed is a straight line. - Vector2D trimPoint = interpolate(point, toVertex.point, position); - return CurveVertexSplitResult( - *this, - CurveVertex(trimPoint, Vector2D::Zero(), Vector2D::Zero(), true), - toVertex - ); - } - /// Cutting by amount gives incorrect length.... - /// One option is to cut by a stride until it gets close then edge it down. - /// Measuring a percentage of the spans does not equal the same as measuring a percentage of length. - /// This is where the historical trim path bugs come from. - Vector2D a = interpolate(point, outTangent, position); - Vector2D b = interpolate(outTangent, toVertex.inTangent, position); - Vector2D c = interpolate(toVertex.inTangent, toVertex.point, position); - Vector2D d = interpolate(a, b, position); - Vector2D e = interpolate(b, c, position); - Vector2D f = interpolate(d, e, position); - return CurveVertexSplitResult( - CurveVertex::absolute(point, inTangent, a), - CurveVertex::absolute(f, d, e), - CurveVertex::absolute(toVertex.point, c, toVertex.outTangent) - ); - } - - /// Trims a curve of a known length to a specific length and returns the points. - /// - /// There is not a performant yet accurate way to cut a curve to a specific length. - /// This calls splitCurve(toVertex: position:) to split the curve and then measures - /// the length of the new curve. The function then iterates through the samples, - /// adjusting the position of the cut for a more precise cut. - /// Usually a single iteration is enough to get within 0.5 points of the desired - /// length. - /// - /// This function should probably live in PathElement, since it deals with curve - /// lengths. - CurveVertexSplitResult trimCurve(CurveVertex const &toVertex, float atLength, float curveLength, int maxSamples, float accuracy = 1.0f) const { - float currentPosition = atLength / curveLength; - auto results = splitCurve(toVertex, currentPosition); - - if (maxSamples == 0) { - return results; - } - - for (int i = 1; i <= maxSamples; i++) { - auto length = results.start.distanceTo(results.trimPoint); - auto lengthDiff = atLength - length; - /// Check if length is correct. - if (lengthDiff < accuracy) { - return results; - } - auto diffPosition = std::max(std::min((currentPosition / length) * lengthDiff, currentPosition * 0.5f), currentPosition * (-0.5f)); - currentPosition = diffPosition + currentPosition; - results = splitCurve(toVertex, currentPosition); - } - return results; - } - - /// The distance from the receiver to the provided vertex. - /// - /// For lines (zeroed tangents) the distance between the two points is measured. - /// For curves the curve is iterated over by sample count and the points are measured. - /// This is ~99% accurate at a sample count of 30 - float distanceTo(CurveVertex const &toVertex, int sampleCount = 25) const { - if (outTangentRelative().isZero() && toVertex.inTangentRelative().isZero()) { - /// Return a linear distance. - return point.distanceTo(toVertex.point); - } - - float distance = 0.0; - - auto previousPoint = point; - for (int i = 0; i < sampleCount; i++) { - auto pointOnCurve = splitCurve(toVertex, ((float)(i)) / ((float)(sampleCount))).trimPoint; - distance = distance + previousPoint.distanceTo(pointOnCurve.point); - previousPoint = pointOnCurve.point; - } - distance = distance + previousPoint.distanceTo(toVertex.point); - return distance; - } -}; - -} - -#endif - -#endif /* CurveVertex_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/LottieAnimation.h b/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/LottieAnimation.h deleted file mode 100644 index e7112776ed..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/LottieAnimation.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef LottieAnimation_h -#define LottieAnimation_h - -#import - -#import "LottieRenderTree.h" - -#ifdef __cplusplus -extern "C" { -#endif - -@interface LottieAnimation : NSObject - -@property (nonatomic, readonly) NSInteger frameCount; -@property (nonatomic, readonly) NSInteger framesPerSecond; -@property (nonatomic, readonly) CGSize size; - -- (instancetype _Nullable)initWithData:(NSData * _Nonnull)data; - -- (NSData * _Nonnull)toJson; - -@end - -#ifdef __cplusplus -} -#endif - -#endif /* LottieAnimation_h */ diff --git a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/LottieAnimationContainer.h b/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/LottieAnimationContainer.h deleted file mode 100644 index f4e936e77d..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/LottieAnimationContainer.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef LottieAnimationContainer_h -#define LottieAnimationContainer_h - -#ifdef __cplusplus - -#import "LottieAnimation.h" -#import "LottieRenderTree.h" -#import "LottieAnimationContainer.h" - -#include - -namespace lottie { - -class RenderTreeNode; - -} - -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - CGRect bounds; - CGPoint position; - CATransform3D transform; - float opacity; - bool masksToBounds; - bool isHidden; -} LottieRenderNodeLayerData; - -typedef struct { - int64_t internalId; - bool isValid; - LottieRenderNodeLayerData layer; - CGRect globalRect; - CGRect localRect; - CATransform3D globalTransform; - bool drawsContent; - bool hasSimpleContents; - int drawContentDescendants; - bool isInvertedMatte; - int64_t maskId; - int subnodeCount; -} LottieRenderNodeProxy; - -@interface LottieAnimationContainer : NSObject - -@property (nonatomic, strong, readonly) LottieAnimation * _Nonnull animation; - -- (instancetype _Nonnull)initWithAnimation:(LottieAnimation * _Nonnull)animation; - -- (void)update:(NSInteger)frame; -- (LottieRenderNode * _Nullable)getCurrentRenderTreeForSize:(CGSize)size; - -#ifdef __cplusplus -- (std::shared_ptr)internalGetRootRenderTreeNode; -#endif - -- (int64_t)getRootRenderNodeProxy; -- (LottieRenderNodeProxy)getRenderNodeProxyById:(int64_t)nodeId __attribute__((objc_direct)); -- (LottieRenderNodeProxy)getRenderNodeSubnodeProxyById:(int64_t)nodeId index:(int)index __attribute__((objc_direct)); - -@end - -#ifdef __cplusplus -} -#endif - -#endif /* LottieAnimationContainer_h */ diff --git a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/LottieCpp.h b/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/LottieCpp.h deleted file mode 100644 index 22091e064b..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/LottieCpp.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef LottieCpp_h -#define LottieCpp_h - -#import - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#endif /* LottieCpp_h */ diff --git a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/LottieRenderTree.h b/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/LottieRenderTree.h deleted file mode 100644 index e4158c3ccb..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/LottieRenderTree.h +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef LottieRenderTree_h -#define LottieRenderTree_h - -#import - -#ifdef __cplusplus -extern "C" { -#endif - -typedef NS_ENUM(NSUInteger, LottiePathItemType) { - LottiePathItemTypeMoveTo, - LottiePathItemTypeLineTo, - LottiePathItemTypeCurveTo, - LottiePathItemTypeClose -}; - -typedef struct { - LottiePathItemType type; - CGPoint points[4]; -} LottiePathItem; - -typedef struct { - CGFloat r; - CGFloat g; - CGFloat b; - CGFloat a; -} LottieColor; - -typedef NS_ENUM(NSUInteger, LottieFillRule) { - LottieFillRuleEvenOdd, - LottieFillRuleWinding -}; - -typedef NS_ENUM(NSUInteger, LottieGradientType) { - LottieGradientTypeLinear, - LottieGradientTypeRadial -}; - -@interface LottieColorStop : NSObject - -@property (nonatomic, readonly, direct) LottieColor color; -@property (nonatomic, readonly, direct) CGFloat location; - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithColor:(LottieColor)color location:(CGFloat)location __attribute__((objc_direct)); - -@end - -@interface LottiePath : NSObject - -- (void)enumerateItems:(void (^ _Nonnull)(LottiePathItem * _Nonnull))iterate __attribute__((objc_direct)); - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithCustomData:(NSData * _Nonnull)customData __attribute__((objc_direct)); - -@end - -@interface LottieRenderContentShading : NSObject - -@end - -@interface LottieRenderContentSolidShading : LottieRenderContentShading - -@property (nonatomic, readonly, direct) LottieColor color; -@property (nonatomic, readonly, direct) CGFloat opacity; - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithColor:(LottieColor)color opacity:(CGFloat)opacity __attribute__((objc_direct)); - -@end - -@interface LottieRenderContentGradientShading : LottieRenderContentShading - -@property (nonatomic, readonly, direct) CGFloat opacity; -@property (nonatomic, readonly, direct) LottieGradientType gradientType; -@property (nonatomic, strong, readonly, direct) NSArray * _Nonnull colorStops; -@property (nonatomic, readonly, direct) CGPoint start; -@property (nonatomic, readonly, direct) CGPoint end; - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithOpacity:(CGFloat)opacity gradientType:(LottieGradientType)gradientType colorStops:(NSArray * _Nonnull)colorStops start:(CGPoint)start end:(CGPoint)end __attribute__((objc_direct)); - -@end - -@interface LottieRenderContentFill : NSObject - -@property (nonatomic, strong, readonly, direct) LottieRenderContentShading * _Nonnull shading; -@property (nonatomic, readonly, direct) LottieFillRule fillRule; - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithShading:(LottieRenderContentShading * _Nonnull)shading fillRule:(LottieFillRule)fillRule __attribute__((objc_direct)); - -@end - -@interface LottieRenderContentStroke : NSObject - -@property (nonatomic, strong, readonly, direct) LottieRenderContentShading * _Nonnull shading; -@property (nonatomic, readonly, direct) CGFloat lineWidth; -@property (nonatomic, readonly, direct) CGLineJoin lineJoin; -@property (nonatomic, readonly, direct) CGLineCap lineCap; -@property (nonatomic, readonly, direct) CGFloat miterLimit; -@property (nonatomic, readonly, direct) CGFloat dashPhase; -@property (nonatomic, strong, readonly, direct) NSArray * _Nullable dashPattern; - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithShading:(LottieRenderContentShading * _Nonnull)shading lineWidth:(CGFloat)lineWidth lineJoin:(CGLineJoin)lineJoin lineCap:(CGLineCap)lineCap miterLimit:(CGFloat)miterLimit dashPhase:(CGFloat)dashPhase dashPattern:(NSArray * _Nullable)dashPattern __attribute__((objc_direct)); - -@end - -@interface LottieRenderContent : NSObject - -@property (nonatomic, strong, readonly, direct) LottiePath * _Nonnull path; -@property (nonatomic, strong, readonly, direct) LottieRenderContentStroke * _Nullable stroke; -@property (nonatomic, strong, readonly, direct) LottieRenderContentFill * _Nullable fill; - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithPath:(LottiePath * _Nonnull)path stroke:(LottieRenderContentStroke * _Nullable)stroke fill:(LottieRenderContentFill * _Nullable)fill __attribute__((objc_direct)); - -@end - -@interface LottieRenderNode : NSObject - -@property (nonatomic, readonly, direct) CGPoint position; -@property (nonatomic, readonly, direct) CGRect bounds; -@property (nonatomic, readonly, direct) CATransform3D transform; -@property (nonatomic, readonly, direct) CGFloat opacity; -@property (nonatomic, readonly, direct) bool masksToBounds; -@property (nonatomic, readonly, direct) bool isHidden; - -@property (nonatomic, readonly, direct) CGRect globalRect; -@property (nonatomic, readonly, direct) CATransform3D globalTransform; -@property (nonatomic, readonly, direct) LottieRenderContent * _Nullable renderContent; -@property (nonatomic, readonly, direct) bool hasSimpleContents; -@property (nonatomic, readonly, direct) bool isInvertedMatte; -@property (nonatomic, readonly, direct) NSArray * _Nonnull subnodes; -@property (nonatomic, readonly, direct) LottieRenderNode * _Nullable mask; - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithPosition:(CGPoint)position bounds:(CGRect)bounds transform:(CATransform3D)transform opacity:(CGFloat)opacity masksToBounds:(bool)masksToBounds isHidden:(bool)isHidden globalRect:(CGRect)globalRect globalTransform:(CATransform3D)globalTransform renderContent:(LottieRenderContent * _Nullable)renderContent hasSimpleContents:(bool)hasSimpleContents isInvertedMatte:(bool)isInvertedMatte subnodes:(NSArray * _Nonnull)subnodes mask:(LottieRenderNode * _Nullable)mask __attribute__((objc_direct)); - -@end - -#ifdef __cplusplus -} -#endif - -#endif /* LottieRenderTree_h */ diff --git a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/PathElement.h b/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/PathElement.h deleted file mode 100644 index bb8a8f578d..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/PathElement.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef PathElement_h -#define PathElement_h - -#ifdef __cplusplus - -#include - -namespace lottie { - -template -struct PathSplitResultSpan { - T start; - T end; - - explicit PathSplitResultSpan(T const &start_, T const &end_) : - start(start_), end(end_) { - } -}; - -template -struct PathSplitResult { - PathSplitResultSpan leftSpan; - PathSplitResultSpan rightSpan; - - explicit PathSplitResult(PathSplitResultSpan const &leftSpan_, PathSplitResultSpan const &rightSpan_) : - leftSpan(leftSpan_), rightSpan(rightSpan_) { - } -}; - -/// A path section, containing one point and its length to the previous point. -/// -/// The relationship between this path element and the previous is implicit. -/// Ideally a path section would be defined by two vertices and a length. -/// We don't do this however, as it would effectively double the memory footprint -/// of path data. -/// -struct __attribute__((packed)) PathElement { - /// Initializes a new path with length of 0 - explicit PathElement(CurveVertex const &vertex_) : - vertex(vertex_) { - } - - /// Initializes a new path with length - explicit PathElement(std::optional length_, CurveVertex const &vertex_) : - vertex(vertex_) { - } - - /// The vertex of the element - CurveVertex vertex; - - /// Returns a new path element define the span from the receiver to the new vertex. - PathElement pathElementTo(CurveVertex const &toVertex) const { - return PathElement(std::nullopt, toVertex); - } - - PathElement updateVertex(CurveVertex const &newVertex) const { - return PathElement(newVertex); - } - - /// Splits an element span defined by the receiver and fromElement to a position 0-1 - PathSplitResult splitElementAtPosition(PathElement const &fromElement, float atLength) { - /// Trim the span. Start and trim go into the first, trim and end go into second. - auto trimResults = fromElement.vertex.trimCurve(vertex, atLength, length(fromElement), 3); - - /// Create the elements for the break - auto spanAStart = PathElement( - std::nullopt, - CurveVertex::absolute( - fromElement.vertex.point, - fromElement.vertex.inTangent, - trimResults.start.outTangent - )); - /// Recalculating the length here is a waste as the trimCurve function also accurately calculates this length. - auto spanAEnd = spanAStart.pathElementTo(trimResults.trimPoint); - - auto spanBStart = PathElement(trimResults.trimPoint); - auto spanBEnd = spanBStart.pathElementTo(trimResults.end); - return PathSplitResult( - PathSplitResultSpan(spanAStart, spanAEnd), - PathSplitResultSpan(spanBStart, spanBEnd) - ); - } - - float length(PathElement const &previous) { - float result = previous.vertex.distanceTo(vertex); - return result; - } -}; - -} - -#endif - -#endif /* PathElement_h */ diff --git a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/RenderTreeNode.h b/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/RenderTreeNode.h deleted file mode 100644 index 7f022c49e9..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/RenderTreeNode.h +++ /dev/null @@ -1,471 +0,0 @@ -#ifndef RenderTreeNode_hpp -#define RenderTreeNode_hpp - -#ifdef __cplusplus - -#include -#include -#include -#include -#include - -#include - -namespace lottie { - -class ProcessedRenderTreeNodeData { -public: - ProcessedRenderTreeNodeData() { - } - - bool isValid = false; - bool isInvertedMatte = false; -}; - -class RenderableItem { -public: - enum class Type { - Shape, - GradientFill - }; - -public: - RenderableItem() { - } - - virtual ~RenderableItem() = default; - - virtual Type type() const = 0; - virtual CGRect boundingRect() const = 0; - - virtual bool isEqual(std::shared_ptr rhs) const = 0; -}; - -class ShapeRenderableItem: public RenderableItem { -public: - struct Fill { - Color color; - FillRule rule; - - Fill(Color color_, FillRule rule_) : - color(color_), rule(rule_) { - } - - bool operator==(Fill const &rhs) const { - if (color != rhs.color) { - return false; - } - if (rule != rhs.rule) { - return false; - } - return true; - } - - bool operator!=(Fill const &rhs) const { - return !(*this == rhs); - } - }; - - struct Stroke { - Color color; - float lineWidth = 0.0; - LineJoin lineJoin = LineJoin::Round; - LineCap lineCap = LineCap::Square; - float dashPhase = 0.0; - std::vector dashPattern; - - Stroke( - Color color_, - float lineWidth_, - LineJoin lineJoin_, - LineCap lineCap_, - float dashPhase_, - std::vector dashPattern_ - ) : - color(color_), - lineWidth(lineWidth_), - lineJoin(lineJoin_), - lineCap(lineCap_), - dashPhase(dashPhase_), - dashPattern(dashPattern_) { - } - - bool operator==(Stroke const &rhs) const { - if (color != rhs.color) { - return false; - } - if (lineWidth != rhs.lineWidth) { - return false; - } - if (lineJoin != rhs.lineJoin) { - return false; - } - if (lineCap != rhs.lineCap) { - return false; - } - if (dashPhase != rhs.dashPhase) { - return false; - } - if (dashPattern != rhs.dashPattern) { - return false; - } - return true; - } - - bool operator!=(Stroke const &rhs) const { - return !(*this == rhs); - } - }; - -public: - ShapeRenderableItem( - std::shared_ptr path_, - std::optional const &fill_, - std::optional const &stroke_ - ) : - path(path_), - fill(fill_), - stroke(stroke_) { - } - - virtual Type type() const override { - return Type::Shape; - } - - virtual CGRect boundingRect() const override { - if (path) { - CGRect shapeBounds = path->boundingBox(); - if (stroke) { - shapeBounds = shapeBounds.insetBy(-stroke->lineWidth / 2.0, -stroke->lineWidth / 2.0); - } - return shapeBounds; - } else { - return CGRect(0.0, 0.0, 0.0, 0.0); - } - } - - virtual bool isEqual(std::shared_ptr rhs) const override { - if (rhs->type() != type()) { - return false; - } - ShapeRenderableItem *other = (ShapeRenderableItem *)rhs.get(); - if ((path == nullptr) != (other->path == nullptr)) { - return false; - } else if (path) { - if (!path->isEqual(other->path.get())) { - return false; - } - } - if (fill != other->fill) { - return false; - } - if (stroke != other->stroke) { - return false; - } - return false; - } - -public: - std::shared_ptr path; - std::optional fill; - std::optional stroke; -}; - -class GradientFillRenderableItem: public RenderableItem { -public: - GradientFillRenderableItem( - std::shared_ptr path_, - FillRule pathFillRule_, - GradientType gradientType_, - std::vector const &colors_, - std::vector const &locations_, - Vector2D const &start_, - Vector2D const &end_, - CGRect bounds_ - ) : - path(path_), - pathFillRule(pathFillRule_), - gradientType(gradientType_), - colors(colors_), - locations(locations_), - start(start_), - end(end_), - bounds(bounds_) { - } - - virtual Type type() const override { - return Type::GradientFill; - } - - virtual CGRect boundingRect() const override { - return bounds; - } - - virtual bool isEqual(std::shared_ptr rhs) const override { - if (rhs->type() != type()) { - return false; - } - GradientFillRenderableItem *other = (GradientFillRenderableItem *)rhs.get(); - - if (gradientType != other->gradientType) { - return false; - } - if (colors != other->colors) { - return false; - } - if (locations != other->locations) { - return false; - } - if (start != other->start) { - return false; - } - if (end != other->end) { - return false; - } - if (bounds != other->bounds) { - return false; - } - - return true; - } - -public: - std::shared_ptr path; - FillRule pathFillRule; - GradientType gradientType; - std::vector colors; - std::vector locations; - Vector2D start; - Vector2D end; - CGRect bounds; -}; - -class RenderTreeNodeContentShadingVariant; - -struct RenderTreeNodeContentPath { -public: - explicit RenderTreeNodeContentPath(BezierPath path_) : - path(path_) { - } - - BezierPath path; - CGRect bounds = CGRect(0.0, 0.0, 0.0, 0.0); - bool needsBoundsRecalculation = true; -}; - -class RenderTreeNodeContentItem { -public: - enum class ShadingType { - Solid, - Gradient - }; - - class Shading { - public: - Shading() { - } - - virtual ~Shading() = default; - - virtual ShadingType type() const = 0; - }; - - class SolidShading: public Shading { - public: - SolidShading(Color const &color_, float opacity_) : - color(color_), - opacity(opacity_) { - } - - virtual ShadingType type() const override { - return ShadingType::Solid; - } - - public: - Color color; - float opacity = 0.0; - }; - - class GradientShading: public Shading { - public: - GradientShading( - float opacity_, - GradientType gradientType_, - std::vector const &colors_, - std::vector const &locations_, - Vector2D const &start_, - Vector2D const &end_ - ) : - opacity(opacity_), - gradientType(gradientType_), - colors(colors_), - locations(locations_), - start(start_), - end(end_) { - } - - virtual ShadingType type() const override { - return ShadingType::Gradient; - } - - public: - float opacity = 0.0; - GradientType gradientType; - std::vector colors; - std::vector locations; - Vector2D start; - Vector2D end; - }; - - struct Stroke { - std::shared_ptr shading; - float lineWidth = 0.0; - LineJoin lineJoin = LineJoin::Round; - LineCap lineCap = LineCap::Square; - float miterLimit = 4.0; - float dashPhase = 0.0; - std::vector dashPattern; - - Stroke( - std::shared_ptr shading_, - float lineWidth_, - LineJoin lineJoin_, - LineCap lineCap_, - float miterLimit_, - float dashPhase_, - std::vector dashPattern_ - ) : - shading(shading_), - lineWidth(lineWidth_), - lineJoin(lineJoin_), - lineCap(lineCap_), - miterLimit(miterLimit_), - dashPhase(dashPhase_), - dashPattern(dashPattern_) { - } - }; - - struct Fill { - std::shared_ptr shading; - FillRule rule; - - Fill( - std::shared_ptr shading_, - FillRule rule_ - ) : - shading(shading_), - rule(rule_) { - } - }; - -public: - RenderTreeNodeContentItem() { - } - -public: - bool isGroup = false; - Transform2D transform = Transform2D::identity(); - float alpha = 0.0; - std::optional trimParams; - std::shared_ptr path; - std::optional> trimmedPaths; - std::vector> shadings; - std::vector> subItems; - int drawContentCount = 0; - - ProcessedRenderTreeNodeData renderData; -}; - -class RenderTreeNodeContentShadingVariant { -public: - RenderTreeNodeContentShadingVariant() { - } - -public: - std::shared_ptr stroke; - std::shared_ptr fill; - - size_t subItemLimit = 0; -}; - -class RenderTreeNode { -public: - RenderTreeNode( - Vector2D size_, - Transform2D transform_, - float alpha_, - bool masksToBounds_, - bool isHidden_, - std::vector> subnodes_, - std::shared_ptr mask_, - bool invertMask_ - ) : - _size(size_), - _transform(transform_), - _alpha(alpha_), - _masksToBounds(masksToBounds_), - _isHidden(isHidden_), - _subnodes(subnodes_), - _mask(mask_), - _invertMask(invertMask_) { - for (const auto &subnode : _subnodes) { - drawContentCount += subnode->drawContentCount; - } - } - - ~RenderTreeNode() { - } - -public: - Vector2D const &size() const { - return _size; - } - - Transform2D const &transform() const { - return _transform; - } - - float alpha() const { - return _alpha; - } - - bool masksToBounds() const { - return _masksToBounds; - } - - bool isHidden() const { - return _isHidden; - } - - std::vector> const &subnodes() const { - return _subnodes; - } - - std::shared_ptr const &mask() const { - return _mask; - } - - bool invertMask() const { - return _invertMask; - } - -public: - Vector2D _size; - Transform2D _transform = Transform2D::identity(); - float _alpha = 1.0f; - bool _masksToBounds = false; - bool _isHidden = false; - std::shared_ptr _contentItem; - int drawContentCount = 0; - std::vector> _subnodes; - std::shared_ptr _mask; - bool _invertMask = false; - - ProcessedRenderTreeNodeData renderData; -}; - -} - -#endif - -#endif /* RenderTreeNode_h */ diff --git a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/ShapeAttributes.h b/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/ShapeAttributes.h deleted file mode 100644 index c3c6f9d809..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/ShapeAttributes.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef ShapeAttributes_h -#define ShapeAttributes_h - -#ifdef __cplusplus - -namespace lottie { - -enum class FillRule: int { - None = 0, - NonZeroWinding = 1, - EvenOdd = 2 -}; - -enum class LineCap: int { - None = 0, - Butt = 1, - Round = 2, - Square = 3 -}; - -enum class LineJoin: int { - None = 0, - Miter = 1, - Round = 2, - Bevel = 3 -}; - -enum class GradientType: int { - None = 0, - Linear = 1, - Radial = 2 -}; - -enum class TrimType: int { - Simultaneously = 1, - Individually = 2 -}; - -struct TrimParams { - float start = 0.0; - float end = 0.0; - float offset = 0.0; - TrimType type = TrimType::Simultaneously; - - TrimParams(float start_, float end_, float offset_, TrimType type_) : - start(start_), - end(end_), - offset(offset_), - type(type_) { - } -}; - -} - -#endif - -#endif /* LottieColor_h */ diff --git a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/Vectors.h b/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/Vectors.h deleted file mode 100644 index ffe5596872..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/Vectors.h +++ /dev/null @@ -1,278 +0,0 @@ -#ifndef Vectors_hpp -#define Vectors_hpp - -#ifdef __cplusplus - -#include -#include - -#include - -#import - -namespace lottie { - -struct Vector1D { - enum class InternalRepresentationType { - SingleNumber, - Array - }; - - explicit Vector1D(float value_) : - value(value_) { - } - - explicit Vector1D(lottiejson11::Json const &json) noexcept(false); - lottiejson11::Json toJson() const; - - float value; - - float distanceTo(Vector1D const &to) const { - return abs(to.value - value); - } -}; - -float interpolate(float value, float to, float amount); - -Vector1D interpolate( - Vector1D const &from, - Vector1D const &to, - float amount -); - -struct __attribute__((packed)) Vector2D { - static Vector2D Zero() { - return Vector2D(0.0, 0.0); - } - - Vector2D() : - x(0.0), - y(0.0) { - } - - explicit Vector2D(float x_, float y_) : - x(x_), - y(y_) { - } - - explicit Vector2D(lottiejson11::Json const &json) noexcept(false); - lottiejson11::Json toJson() const; - - float x; - float y; - - Vector2D operator+(Vector2D const &rhs) const { - return Vector2D(x + rhs.x, y + rhs.y); - } - - Vector2D operator-(Vector2D const &rhs) const { - return Vector2D(x - rhs.x, y - rhs.y); - } - - Vector2D operator*(float scalar) const { - return Vector2D(x * scalar, y * scalar); - } - - bool operator==(Vector2D const &rhs) const { - return x == rhs.x && y == rhs.y; - } - - bool operator!=(Vector2D const &rhs) const { - return !(*this == rhs); - } - - bool isZero() const { - return x == 0.0 && y == 0.0; - } - - float distanceTo(Vector2D const &to) const { - auto deltaX = to.x - x; - auto deltaY = to.y - y; - return sqrt(deltaX * deltaX + deltaY * deltaY); - } - - bool colinear(Vector2D const &a, Vector2D const &b) const { - float area = x * (a.y - b.y) + a.x * (b.y - y) + b.x * (y - a.y); - float accuracy = 0.05; - if (area < accuracy && area > -accuracy) { - return true; - } - return false; - } - - Vector2D pointOnPath(Vector2D const &to, Vector2D const &outTangent, Vector2D const &inTangent, float amount) const; - - Vector2D interpolate(Vector2D const &to, float amount) const; - - Vector2D interpolate( - Vector2D const &to, - Vector2D const &outTangent, - Vector2D const &inTangent, - float amount, - int maxIterations = 3, - int samples = 20, - float accuracy = 1.0 - ) const; -}; - -Vector2D interpolate( - Vector2D const &from, - Vector2D const &to, - float amount -); - -struct Vector3D { - explicit Vector3D(float x_, float y_, float z_) : - x(x_), - y(y_), - z(z_) { - } - - explicit Vector3D(lottiejson11::Json const &json) noexcept(false); - lottiejson11::Json toJson() const; - - float x = 0.0; - float y = 0.0; - float z = 0.0; -}; - -Vector3D interpolate( - Vector3D const &from, - Vector3D const &to, - float amount -); - -inline float degreesToRadians(float value) { - return value * M_PI / 180.0f; -} - -inline float radiansToDegrees(float value) { - return value * 180.0f / M_PI; -} - -struct Transform2D { - static Transform2D const &identity() { - return _identity; - } - - explicit Transform2D(simd_float3x3 const &rows_) : - _rows(rows_) { - } - - Transform2D operator*(Transform2D const &other) const { - return Transform2D(simd_mul(other._rows, _rows)); - } - - bool isInvertible() const { - return simd_determinant(_rows) > 0.00000001; - } - - Transform2D inverted() const { - return Transform2D(simd_inverse(_rows)); - } - - bool isIdentity() const { - return (*this) == identity(); - } - - static Transform2D makeTranslation(float tx, float ty); - static Transform2D makeScale(float sx, float sy); - static Transform2D makeRotation(float radians); - static Transform2D makeSkew(float skew, float skewAxis); - static Transform2D makeTransform( - Vector2D const &anchor, - Vector2D const &position, - Vector2D const &scale, - float rotation, - std::optional skew, - std::optional skewAxis - ); - - Transform2D rotated(float degrees) const; - Transform2D translated(Vector2D const &translation) const; - Transform2D scaled(Vector2D const &scale) const; - Transform2D skewed(float skew, float skewAxis) const; - - bool operator==(Transform2D const &rhs) const { - return simd_equal(_rows, rhs._rows); - } - - bool operator!=(Transform2D const &rhs) const { - return !((*this) == rhs); - } - - simd_float3x3 const &rows() const { - return _rows; - } -private: - static Transform2D _identity; - - simd_float3x3 _rows; -}; - -struct CGRect { - explicit CGRect(float x_, float y_, float width_, float height_) : - x(x_), y(y_), width(width_), height(height_) { - } - - float x = 0.0f; - float y = 0.0f; - float width = 0.0f; - float height = 0.0f; - - static CGRect veryLarge() { - return CGRect( - -100000000.0f, - -100000000.0f, - 200000000.0f, - 200000000.0f - ); - } - - bool operator==(CGRect const &rhs) const { - return x == rhs.x && y == rhs.y && width == rhs.width && height == rhs.height; - } - - bool operator!=(CGRect const &rhs) const { - return !(*this == rhs); - } - - bool empty() const { - return width <= 0.0 || height <= 0.0; - } - - CGRect insetBy(float dx, float dy) const { - CGRect result = *this; - - result.x += dx; - result.y += dy; - result.width -= dx * 2.0f; - result.height -= dy * 2.0f; - - return result; - } - - bool intersects(CGRect const &other) const; - bool contains(CGRect const &other) const; - - CGRect intersection(CGRect const &other) const; - CGRect unionWith(CGRect const &other) const; - - CGRect applyingTransform(Transform2D const &transform) const; -}; - -inline bool isInRangeOrEqual(float value, float from, float to) { - return from <= value && value <= to; -} - -inline bool isInRange(float value, float from, float to) { - return from < value && value < to; -} - -float cubicBezierInterpolate(float value, Vector2D const &P0, Vector2D const &P1, Vector2D const &P2, Vector2D const &P3); - -} - -#endif - -#endif /* Vectors_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/VectorsCocoa.h b/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/VectorsCocoa.h deleted file mode 100644 index ef77ad9966..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/VectorsCocoa.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef VectorsCocoa_h -#define VectorsCocoa_h - -#ifdef __cplusplus - -#import - -namespace lottie { - -::CATransform3D nativeTransform(Transform2D const &value); -Transform2D fromNativeTransform(::CATransform3D const &value); - -} - -#endif - -#endif /* VectorsCocoa_h */ diff --git a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/lottiejson11.hpp b/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/lottiejson11.hpp deleted file mode 100644 index aa188f366b..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/PublicHeaders/LottieCpp/lottiejson11.hpp +++ /dev/null @@ -1,236 +0,0 @@ -/* json11 - * - * json11 is a tiny JSON library for C++11, providing JSON parsing and serialization. - * - * The core object provided by the library is json11::Json. A Json object represents any JSON - * value: null, bool, number (int or double), string (std::string), array (std::vector), or - * object (std::map). - * - * Json objects act like values: they can be assigned, copied, moved, compared for equality or - * order, etc. There are also helper methods Json::dump, to serialize a Json to a string, and - * Json::parse (static) to parse a std::string as a Json object. - * - * Internally, the various types of Json object are represented by the JsonValue class - * hierarchy. - * - * A note on numbers - JSON specifies the syntax of number formatting but not its semantics, - * so some JSON implementations distinguish between integers and floating-point numbers, while - * some don't. In json11, we choose the latter. Because some JSON implementations (namely - * Javascript itself) treat all numbers as the same type, distinguishing the two leads - * to JSON that will be *silently* changed by a round-trip through those implementations. - * Dangerous! To avoid that risk, json11 stores all numbers as double internally, but also - * provides integer helpers. - * - * Fortunately, double-precision IEEE754 ('double') can precisely store any integer in the - * range +/-2^53, which includes every 'int' on most systems. (Timestamps often use int64 - * or long long to avoid the Y2038K problem; a double storing microseconds since some epoch - * will be exact for +/- 275 years.) - */ - -/* Copyright (c) 2013 Dropbox, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#pragma once - -#ifdef __cplusplus - -#include -#include -#include -#include -#include - -#ifdef _MSC_VER - #if _MSC_VER <= 1800 // VS 2013 - #ifndef noexcept - #define noexcept throw() - #endif - - #ifndef snprintf - #define snprintf _snprintf_s - #endif - #endif -#endif - -namespace lottiejson11 { - -enum JsonParse { - STANDARD, COMMENTS -}; - -class JsonValue; - -class Json final { -public: - // Types - enum Type { - NUL, NUMBER, BOOL, STRING, ARRAY, OBJECT - }; - - // Array and object typedefs - typedef std::vector array; - typedef std::map object; - - // Constructors for the various types of JSON value. - Json() noexcept; // NUL - Json(std::nullptr_t) noexcept; // NUL - Json(double value); // NUMBER - Json(int value); // NUMBER - Json(bool value); // BOOL - Json(const std::string &value); // STRING - Json(std::string &&value); // STRING - Json(const char * value); // STRING - Json(const array &values); // ARRAY - Json(array &&values); // ARRAY - Json(const object &values); // OBJECT - Json(object &&values); // OBJECT - - // Implicit constructor: anything with a to_json() function. - template - Json(const T & t) : Json(t.to_json()) {} - - // Implicit constructor: map-like objects (std::map, std::unordered_map, etc) - template ().begin()->first)>::value - && std::is_constructible().begin()->second)>::value, - int>::type = 0> - Json(const M & m) : Json(object(m.begin(), m.end())) {} - - // Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc) - template ().begin())>::value, - int>::type = 0> - Json(const V & v) : Json(array(v.begin(), v.end())) {} - - // This prevents Json(some_pointer) from accidentally producing a bool. Use - // Json(bool(some_pointer)) if that behavior is desired. - Json(void *) = delete; - - // Accessors - Type type() const; - - bool is_null() const { return type() == NUL; } - bool is_number() const { return type() == NUMBER; } - bool is_bool() const { return type() == BOOL; } - bool is_string() const { return type() == STRING; } - bool is_array() const { return type() == ARRAY; } - bool is_object() const { return type() == OBJECT; } - - // Return the enclosed value if this is a number, 0 otherwise. Note that json11 does not - // distinguish between integer and non-integer numbers - number_value() and int_value() - // can both be applied to a NUMBER-typed object. - double number_value() const; - int int_value() const; - - // Return the enclosed value if this is a boolean, false otherwise. - bool bool_value() const; - // Return the enclosed string if this is a string, "" otherwise. - const std::string &string_value() const; - // Return the enclosed std::vector if this is an array, or an empty vector otherwise. - const array &array_items() const; - // Return the enclosed std::map if this is an object, or an empty map otherwise. - const object &object_items() const; - - // Return a reference to arr[i] if this is an array, Json() otherwise. - const Json & operator[](size_t i) const; - // Return a reference to obj[key] if this is an object, Json() otherwise. - const Json & operator[](const std::string &key) const; - - // Serialize. - void dump(std::string &out) const; - std::string dump() const { - std::string out; - dump(out); - return out; - } - - // Parse. If parse fails, return Json() and assign an error message to err. - static Json parse(const std::string & in, - std::string & err, - JsonParse strategy = JsonParse::STANDARD); - static Json parse(const char * in, - std::string & err, - JsonParse strategy = JsonParse::STANDARD) { - if (in) { - return parse(std::string(in), err, strategy); - } else { - err = "null input"; - return nullptr; - } - } - // Parse multiple objects, concatenated or separated by whitespace - static std::vector parse_multi( - const std::string & in, - std::string::size_type & parser_stop_pos, - std::string & err, - JsonParse strategy = JsonParse::STANDARD); - - static inline std::vector parse_multi( - const std::string & in, - std::string & err, - JsonParse strategy = JsonParse::STANDARD) { - std::string::size_type parser_stop_pos; - return parse_multi(in, parser_stop_pos, err, strategy); - } - - bool operator== (const Json &rhs) const; - bool operator< (const Json &rhs) const; - bool operator!= (const Json &rhs) const { return !(*this == rhs); } - bool operator<= (const Json &rhs) const { return !(rhs < *this); } - bool operator> (const Json &rhs) const { return (rhs < *this); } - bool operator>= (const Json &rhs) const { return !(*this < rhs); } - - /* has_shape(types, err) - * - * Return true if this is a JSON object and, for each item in types, has a field of - * the given type. If not, return false and set err to a descriptive message. - */ - typedef std::initializer_list> shape; - bool has_shape(const shape & types, std::string & err) const; - -private: - std::shared_ptr m_ptr; -}; - -// Internal class hierarchy - JsonValue objects are not exposed to users of this API. -class JsonValue { -protected: - friend class Json; - friend class JsonInt; - friend class JsonDouble; - virtual Json::Type type() const = 0; - virtual bool equals(const JsonValue * other) const = 0; - virtual bool less(const JsonValue * other) const = 0; - virtual void dump(std::string &out) const = 0; - virtual double number_value() const; - virtual int int_value() const; - virtual bool bool_value() const; - virtual const std::string &string_value() const; - virtual const Json::array &array_items() const; - virtual const Json &operator[](size_t i) const; - virtual const Json::object &object_items() const; - virtual const Json &operator[](const std::string &key) const; - virtual ~JsonValue() {} -}; - -} // namespace lottiejson11 - -#endif \ No newline at end of file diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.cpp deleted file mode 100644 index 53f850f090..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "CompositionLayer.hpp" - -namespace lottie { - -InvertedMatteLayer::InvertedMatteLayer(std::shared_ptr inputMatte) : -_inputMatte(inputMatte) { - setSize(inputMatte->size()); - - addSublayer(_inputMatte); -} - -std::shared_ptr makeInvertedMatteLayer(std::shared_ptr compositionLayer) { - auto result = std::make_shared(compositionLayer); - return result; -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.hpp deleted file mode 100644 index e82b9c8b33..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.hpp +++ /dev/null @@ -1,201 +0,0 @@ -#ifndef CompositionLayer_hpp -#define CompositionLayer_hpp - -#include -#include "Lottie/Public/Primitives/CALayer.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.hpp" -#include "Lottie/Private/Model/Layers/LayerModel.hpp" -#include "Lottie/Private/MainThread/LayerContainers/Utility/LayerTransformNode.hpp" -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.hpp" - -#include - -namespace lottie { - -class CompositionLayer; -class InvertedMatteLayer; - -/// A layer that inverses the alpha output of its input layer. -class InvertedMatteLayer: public CALayer { -public: - InvertedMatteLayer(std::shared_ptr inputMatte); - - std::shared_ptr _inputMatte; - - virtual bool isInvertedMatte() const override { - return true; - } -}; - -std::shared_ptr makeInvertedMatteLayer(std::shared_ptr compositionLayer); - -/// The base class for a child layer of CompositionContainer -class CompositionLayer: public CALayer, public KeypathSearchable { -public: - CompositionLayer(std::shared_ptr const &layer, Vector2D size) { - _contentsLayer = std::make_shared(); - - _transformNode = std::make_shared(layer->transform); - - if (layer->masks.has_value()) { - _maskLayer = std::make_shared(layer->masks.value()); - } else { - _maskLayer = nullptr; - } - - _matteType = layer->matte; - - _inFrame = layer->inFrame; - _outFrame = layer->outFrame; - _timeStretch = layer->timeStretch(); - _startFrame = layer->startTime; - if (layer->name.has_value()) { - _keypathName = layer->name.value(); - } else { - _keypathName = "Layer"; - } - - _childKeypaths.push_back(_transformNode->transformProperties()); - - _contentsLayer->setSize(size); - - if (layer->blendMode.has_value() && layer->blendMode.value() != BlendMode::Normal) { - setCompositingFilter(layer->blendMode); - } - - addSublayer(_contentsLayer); - - if (_maskLayer) { - _contentsLayer->setMask(_maskLayer); - } - } - - virtual std::string keypathName() const override { - return _keypathName; - } - - virtual std::map> keypathProperties() const override { - return {}; - } - - virtual std::shared_ptr keypathLayer() const override { - return _contentsLayer; - } - - void displayWithFrame(float frame, bool forceUpdates, BezierPathsBoundingBoxContext &boundingBoxContext) { - bool layerVisible = isInRangeOrEqual(frame, _inFrame, _outFrame); - - if (_transformNode->updateTree(frame, forceUpdates) || _contentsLayer->isHidden() != !layerVisible) { - _contentsLayer->setTransform(_transformNode->globalTransform()); - _contentsLayer->setOpacity(_transformNode->opacity()); - _contentsLayer->setIsHidden(!layerVisible); - - updateContentsLayerParameters(); - } - - /// Only update contents if current time is within the layers time bounds. - if (layerVisible) { - displayContentsWithFrame(frame, forceUpdates, boundingBoxContext); - if (_maskLayer) { - _maskLayer->updateWithFrame(frame, forceUpdates); - } - } - } - - virtual void updateContentsLayerParameters() { - } - - virtual void displayContentsWithFrame(float frame, bool forceUpdates, BezierPathsBoundingBoxContext &boundingBoxContext) { - /// To be overridden by subclass - } - - - virtual std::vector> const &childKeypaths() const override { - return _childKeypaths; - } - - std::shared_ptr _matteLayer; - void setMatteLayer(std::shared_ptr matteLayer) { - _matteLayer = matteLayer; - if (matteLayer) { - if (_matteType.has_value() && _matteType.value() == MatteType::Invert) { - setMask(makeInvertedMatteLayer(matteLayer)); - } else { - setMask(matteLayer); - } - } else { - setMask(nullptr); - } - } - - std::shared_ptr const &contentsLayer() const { - return _contentsLayer; - } - - std::shared_ptr const &maskLayer() const { - return _maskLayer; - } - void setMaskLayer(std::shared_ptr const &maskLayer) { - _maskLayer = maskLayer; - } - - std::optional const &matteType() const { - return _matteType; - } - - float inFrame() const { - return _inFrame; - } - float outFrame() const { - return _outFrame; - } - float startFrame() const { - return _startFrame; - } - float timeStretch() const { - return _timeStretch; - } - - virtual std::shared_ptr renderTreeNode(BezierPathsBoundingBoxContext &boundingBoxContext) { - return nullptr; - } - -public: - std::shared_ptr const transformNode() const { - return _transformNode; - } - -protected: - std::shared_ptr _contentsLayer; - std::optional _matteType; - -private: - std::shared_ptr _transformNode; - - std::shared_ptr _maskLayer; - - float _inFrame = 0.0; - float _outFrame = 0.0; - float _startFrame = 0.0; - float _timeStretch = 0.0; - - // MARK: Keypath Searchable - - std::string _keypathName; - -public: - virtual bool isImageCompositionLayer() const { - return false; - } - - virtual bool isTextCompositionLayer() const { - return false; - } - -protected: - std::vector> _childKeypaths; -}; - -} - -#endif /* CompositionLayer_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ImageCompositionLayer.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ImageCompositionLayer.cpp deleted file mode 100644 index ad3b669b24..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ImageCompositionLayer.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "ImageCompositionLayer.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ImageCompositionLayer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ImageCompositionLayer.hpp deleted file mode 100644 index ff6dc769fa..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ImageCompositionLayer.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef ImageCompositionLayer_hpp -#define ImageCompositionLayer_hpp - -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.hpp" -#include "Lottie/Private/Model/Assets/ImageAsset.hpp" -#include "Lottie/Private/Model/Layers/ImageLayerModel.hpp" - -namespace lottie { - -class ImageCompositionLayer: public CompositionLayer { -public: - ImageCompositionLayer(std::shared_ptr const &imageLayer, Vector2D const &size) : - CompositionLayer(imageLayer, size) { - _imageReferenceID = imageLayer->referenceID; - - contentsLayer()->setMasksToBounds(true); - } - - std::shared_ptr image() { - return _image; - } - void setImage(std::shared_ptr image) { - _image = image; - //contentsLayer()->setContents(image); - } - - std::string const &imageReferenceID() { - return _imageReferenceID; - } - -public: - virtual bool isImageCompositionLayer() const override { - return true; - } - -private: - std::string _imageReferenceID; - std::shared_ptr _image; -}; - -} - -#endif /* ImageCompositionLayer_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.cpp deleted file mode 100644 index 398d52d57c..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "MaskContainerLayer.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.hpp deleted file mode 100644 index 95bdb3f093..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.hpp +++ /dev/null @@ -1,178 +0,0 @@ -#ifndef MaskContainerLayer_hpp -#define MaskContainerLayer_hpp - -#include "Lottie/Private/Model/Objects/Mask.hpp" -#include "Lottie/Public/Primitives/CALayer.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/NodeProperty.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.hpp" - -namespace lottie { - -inline MaskMode usableMaskMode(MaskMode mode) { - switch (mode) { - case MaskMode::Add: - return MaskMode::Add; - case MaskMode::Subtract: - return MaskMode::Subtract; - case MaskMode::Intersect: - return MaskMode::Intersect; - case MaskMode::Lighten: - return MaskMode::Add; - case MaskMode::Darken: - return MaskMode::Darken; - case MaskMode::Difference: - return MaskMode::Intersect; - case MaskMode::None: - return MaskMode::None; - } -} - -class MaskNodeProperties: public NodePropertyMap { -public: - MaskNodeProperties(std::shared_ptr const &mask) : - _mode(mask->mode()), - _inverted(mask->inverted) { - _opacity = std::make_shared>(std::make_shared>(mask->opacity->keyframes)); - _shape = std::make_shared>(std::make_shared>(mask->shape.keyframes)); - _expansion = std::make_shared>(std::make_shared>(mask->expansion->keyframes)); - - _propertyMap.insert(std::make_pair("Opacity", _opacity)); - _propertyMap.insert(std::make_pair("Shape", _shape)); - _propertyMap.insert(std::make_pair("Expansion", _expansion)); - - for (const auto &it : _propertyMap) { - _properties.push_back(it.second); - } - } - - virtual std::vector> &properties() override { - return _properties; - } - - virtual std::vector> const &childKeypaths() const override { - return _childKeypaths; - } - - std::shared_ptr> const &opacity() const { - return _opacity; - } - - std::shared_ptr> const &shape() const { - return _shape; - } - - std::shared_ptr> const &expansion() const { - return _expansion; - } - - MaskMode mode() const { - return _mode; - } - - bool inverted() const { - return _inverted; - } - -private: - std::map> _propertyMap; - std::vector> _childKeypaths; - - std::vector> _properties; - - MaskMode _mode = MaskMode::Add; - bool _inverted = false; - - std::shared_ptr> _opacity; - std::shared_ptr> _shape; - std::shared_ptr> _expansion; -}; - -class MaskLayer: public CALayer { -public: - MaskLayer(std::shared_ptr const &mask) : - _properties(mask) { - _maskLayer = std::make_shared(); - - addSublayer(_maskLayer); - - if (mask->mode() == MaskMode::Add) { - _maskLayer->setFillColor(Color(1.0, 0.0, 0.0, 1.0)); - } else { - _maskLayer->setFillColor(Color(0.0, 1.0, 0.0, 1.0)); - } - _maskLayer->setFillRule(FillRule::EvenOdd); - } - - virtual ~MaskLayer() = default; - - void updateWithFrame(float frame, bool forceUpdates) { - if (_properties.opacity()->needsUpdate(frame) || forceUpdates) { - _properties.opacity()->update(frame); - setOpacity(_properties.opacity()->value().value); - } - - if (_properties.shape()->needsUpdate(frame) || forceUpdates) { - _properties.shape()->update(frame); - _properties.expansion()->update(frame); - - auto path = _properties.shape()->value().cgPath(); - auto usableMode = usableMaskMode(_properties.mode()); - if ((usableMode == MaskMode::Subtract && !_properties.inverted()) || - (usableMode == MaskMode::Add && _properties.inverted())) { - /// Add a bounds rect to invert the mask - auto newPath = CGPath::makePath(); - newPath->addRect(CGRect::veryLarge()); - newPath->addPath(path); - path = std::static_pointer_cast(newPath); - } - _maskLayer->setPath(path); - } - } - -private: - MaskNodeProperties _properties; - - std::shared_ptr _maskLayer; -}; - -class MaskContainerLayer: public CALayer { -public: - MaskContainerLayer(std::vector> const &masks) { - auto containerLayer = std::make_shared(); - bool firstObject = true; - for (const auto &mask : masks) { - auto maskLayer = std::make_shared(mask); - _maskLayers.push_back(maskLayer); - - auto usableMode = usableMaskMode(mask->mode()); - if (usableMode == MaskMode::None) { - continue; - } else if (usableMode == MaskMode::Add || firstObject) { - firstObject = false; - containerLayer->addSublayer(maskLayer); - } else { - containerLayer->setMask(maskLayer); - auto newContainer = std::make_shared(); - newContainer->addSublayer(containerLayer); - containerLayer = newContainer; - } - } - addSublayer(containerLayer); - } - - // MARK: Internal - - void updateWithFrame(float frame, bool forceUpdates) { - for (const auto &maskLayer : _maskLayers) { - maskLayer->updateWithFrame(frame, forceUpdates); - } - } - -private: - std::vector> _maskLayers; -}; - -} - -#endif /* MaskContainerLayer_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/NullCompositionLayer.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/NullCompositionLayer.cpp deleted file mode 100644 index 6c5345cfd6..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/NullCompositionLayer.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "NullCompositionLayer.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/NullCompositionLayer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/NullCompositionLayer.hpp deleted file mode 100644 index c3d3dea5cc..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/NullCompositionLayer.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef NullCompositionLayer_hpp -#define NullCompositionLayer_hpp - -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.hpp" - -namespace lottie { - -class NullCompositionLayer: public CompositionLayer { -public: - NullCompositionLayer(std::shared_ptr const &layer) : - CompositionLayer(layer, Vector2D::Zero()) { - } -}; - -} - -#endif /* NullCompositionLayer_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.cpp deleted file mode 100644 index d3428a9b1b..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "PreCompositionLayer.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.hpp deleted file mode 100644 index c170f21a58..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.hpp +++ /dev/null @@ -1,202 +0,0 @@ -#ifndef PreCompositionLayer_hpp -#define PreCompositionLayer_hpp - -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.hpp" -#include "Lottie/Private/Model/Layers/PreCompLayerModel.hpp" -#include "Lottie/Private/Model/Assets/PrecompAsset.hpp" -#include "Lottie/Private/MainThread/LayerContainers/Utility/LayerImageProvider.hpp" -#include "Lottie/Public/TextProvider/AnimationTextProvider.hpp" -#include "Lottie/Public/FontProvider/AnimationFontProvider.hpp" -#include "Lottie/Private/Model/Assets/AssetLibrary.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/NodeProperty.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.hpp" -#include "Lottie/Private/MainThread/LayerContainers/Utility/CompositionLayersInitializer.hpp" - -namespace lottie { - -class PreCompositionLayer: public CompositionLayer { -public: - PreCompositionLayer( - std::shared_ptr const &precomp, - PrecompAsset const &asset, - std::shared_ptr const &layerImageProvider, - std::shared_ptr const &textProvider, - std::shared_ptr const &fontProvider, - std::shared_ptr const &assetLibrary, - float frameRate - ) : CompositionLayer(precomp, Vector2D(precomp->width, precomp->height)) { - if (precomp->timeRemapping) { - _remappingNode = std::make_shared>(std::make_shared>(precomp->timeRemapping->keyframes)); - } - _frameRate = frameRate; - - setSize(Vector2D(precomp->width, precomp->height)); - contentsLayer()->setMasksToBounds(true); - contentsLayer()->setSize(size()); - - auto layers = initializeCompositionLayers( - asset.layers, - assetLibrary, - layerImageProvider, - textProvider, - fontProvider, - frameRate - ); - - std::vector> imageLayers; - - std::shared_ptr mattedLayer; - - for (auto layerIt = layers.rbegin(); layerIt != layers.rend(); layerIt++) { - std::shared_ptr layer = *layerIt; - layer->setSize(size()); - _animationLayers.push_back(layer); - - if (layer->isImageCompositionLayer()) { - imageLayers.push_back(std::static_pointer_cast(layer)); - } - if (mattedLayer) { - /// The previous layer requires this layer to be its matte - mattedLayer->setMatteLayer(layer); - mattedLayer = nullptr; - continue; - } - if (layer->matteType().has_value() && (layer->matteType().value() == MatteType::Add || layer->matteType().value() == MatteType::Invert)) { - /// We have a layer that requires a matte. - mattedLayer = layer; - } - contentsLayer()->addSublayer(layer); - } - - for (const auto &layer : layers) { - _childKeypaths.push_back(layer); - } - - layerImageProvider->addImageLayers(imageLayers); - } - - virtual std::map> keypathProperties() const override { - if (!_remappingNode) { - return {}; - } - - std::map> result; - result.insert(std::make_pair("Time Remap", _remappingNode)); - - return result; - } - - virtual void displayContentsWithFrame(float frame, bool forceUpdates, BezierPathsBoundingBoxContext &boundingBoxContext) override { - float localFrame = 0.0; - if (_remappingNode) { - _remappingNode->update(frame); - localFrame = _remappingNode->value().value * _frameRate; - } else { - localFrame = (frame - startFrame()) / timeStretch(); - } - - for (const auto &animationLayer : _animationLayers) { - animationLayer->displayWithFrame(localFrame, forceUpdates, boundingBoxContext); - } - } - - virtual std::shared_ptr renderTreeNode(BezierPathsBoundingBoxContext &boundingBoxContext) override { - if (!_renderTreeNode) { - std::vector> renderTreeSubnodes; - for (const auto &animationLayer : _animationLayers) { - bool found = false; - for (const auto &sublayer : contentsLayer()->sublayers()) { - if (animationLayer == sublayer) { - found = true; - break; - } - } - if (found) { - auto node = animationLayer->renderTreeNode(boundingBoxContext); - if (node) { - renderTreeSubnodes.push_back(node); - } - } - } - - std::vector> renderTreeValue; - auto renderTreeContentItem = std::make_shared( - Vector2D(0.0, 0.0), - Transform2D::identity(), - 1.0, - false, - false, - renderTreeSubnodes, - nullptr, - false - ); - if (renderTreeContentItem) { - renderTreeValue.push_back(renderTreeContentItem); - } - - _contentsTreeNode = std::make_shared( - Vector2D(0.0, 0.0), - Transform2D::identity(), - 1.0, - false, - false, - renderTreeValue, - nullptr, - false - ); - - std::vector> subnodes; - subnodes.push_back(_contentsTreeNode); - - std::shared_ptr maskNode; - bool invertMask = false; - if (_matteLayer) { - maskNode = _matteLayer->renderTreeNode(boundingBoxContext); - if (maskNode && _matteType.has_value() && _matteType.value() == MatteType::Invert) { - invertMask = true; - } - } - - _renderTreeNode = std::make_shared( - Vector2D(0.0, 0.0), - Transform2D::identity(), - 1.0, - false, - false, - subnodes, - maskNode, - invertMask - ); - } - - _contentsTreeNode->_size = _contentsLayer->size(); - _contentsTreeNode->_masksToBounds = _contentsLayer->masksToBounds(); - - _renderTreeNode->_size = size(); - _renderTreeNode->_transform = transform(); - _renderTreeNode->_alpha = opacity(); - _renderTreeNode->_masksToBounds = masksToBounds(); - _renderTreeNode->_isHidden = isHidden(); - - return _renderTreeNode; - } - - virtual void updateContentsLayerParameters() override { - _contentsTreeNode->_transform = _contentsLayer->transform(); - _contentsTreeNode->_alpha = _contentsLayer->opacity(); - _contentsTreeNode->_isHidden = _contentsLayer->isHidden(); - } - -private: - float _frameRate = 0.0; - std::shared_ptr> _remappingNode; - - std::vector> _animationLayers; - - std::shared_ptr _renderTreeNode; - std::shared_ptr _contentsTreeNode; -}; - -} - -#endif /* PreCompositionLayer_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.cpp deleted file mode 100644 index 39ad7ead6e..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.cpp +++ /dev/null @@ -1,1356 +0,0 @@ -#include "ShapeCompositionLayer.hpp" - -#include "Lottie/Private/Model/ShapeItems/Group.hpp" -#include "Lottie/Private/Model/ShapeItems/Ellipse.hpp" -#include "Lottie/Private/Model/ShapeItems/Rectangle.hpp" -#include "Lottie/Private/Model/ShapeItems/Star.hpp" -#include "Lottie/Private/Model/ShapeItems/Shape.hpp" -#include "Lottie/Private/Model/ShapeItems/Trim.hpp" -#include "Lottie/Private/Model/ShapeItems/Stroke.hpp" -#include "Lottie/Private/Model/ShapeItems/GradientStroke.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/RenderLayers/GetGradientParameters.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/DashPatternInterpolator.hpp" -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeUtils/BezierPathUtils.hpp" -#include "Lottie/Private/Model/ShapeItems/ShapeTransform.hpp" - -namespace lottie { - -class ShapeLayerPresentationTree { -public: - class FillOutput { - public: - FillOutput() { - } - ~FillOutput() = default; - - virtual void update(AnimationFrameTime frameTime) = 0; - virtual std::shared_ptr fill() = 0; - }; - - class SolidFillOutput : public FillOutput { - public: - explicit SolidFillOutput(Fill const &fill) : - rule(fill.fillRule.value_or(FillRule::NonZeroWinding)), - color(fill.color.keyframes), - opacity(fill.opacity.keyframes) { - auto solid = std::make_shared(Color(0.0, 0.0, 0.0, 0.0), 0.0); - _fill = std::make_shared( - solid, - rule - ); - } - - virtual ~SolidFillOutput() = default; - - virtual void update(AnimationFrameTime frameTime) override { - bool hasUpdates = false; - - if (color.hasUpdate(frameTime)) { - hasUpdates = true; - colorValue = color.value(frameTime); - } - - if (opacity.hasUpdate(frameTime)) { - hasUpdates = true; - opacityValue = opacity.value(frameTime).value; - } - - if (hasUpdates) { - RenderTreeNodeContentItem::SolidShading *solid = (RenderTreeNodeContentItem::SolidShading *)_fill->shading.get(); - solid->color = colorValue; - solid->opacity = opacityValue * 0.01; - } - } - - virtual std::shared_ptr fill() override { - return _fill; - } - - private: - FillRule rule; - - KeyframeInterpolator color; - Color colorValue = Color(0.0, 0.0, 0.0, 0.0); - - KeyframeInterpolator opacity; - float opacityValue = 0.0; - - std::shared_ptr _fill; - }; - - class GradientFillOutput : public FillOutput { - public: - explicit GradientFillOutput(GradientFill const &gradientFill) : - rule(FillRule::NonZeroWinding), - numberOfColors(gradientFill.numberOfColors), - gradientType(gradientFill.gradientType), - colors(gradientFill.colors.keyframes), - startPoint(gradientFill.startPoint.keyframes), - endPoint(gradientFill.endPoint.keyframes), - opacity(gradientFill.opacity.keyframes) { - auto gradient = std::make_shared( - 0.0, - gradientType, - std::vector(), - std::vector(), - Vector2D(0.0, 0.0), - Vector2D(0.0, 0.0) - ); - _fill = std::make_shared( - gradient, - rule - ); - } - - virtual ~GradientFillOutput() = default; - - virtual void update(AnimationFrameTime frameTime) override { - bool hasUpdates = false; - - if (colors.hasUpdate(frameTime)) { - hasUpdates = true; - colorsValue = colors.value(frameTime); - } - - if (startPoint.hasUpdate(frameTime)) { - hasUpdates = true; - startPointValue = startPoint.value(frameTime); - } - - if (endPoint.hasUpdate(frameTime)) { - hasUpdates = true; - endPointValue = endPoint.value(frameTime); - } - - if (opacity.hasUpdate(frameTime)) { - hasUpdates = true; - opacityValue = opacity.value(frameTime).value; - } - - if (hasUpdates) { - std::vector colors; - std::vector locations; - getGradientParameters(numberOfColors, colorsValue, colors, locations); - - RenderTreeNodeContentItem::GradientShading *gradient = ((RenderTreeNodeContentItem::GradientShading *)_fill->shading.get()); - gradient->opacity = opacityValue * 0.01; - gradient->colors = colors; - gradient->locations = locations; - gradient->start = Vector2D(startPointValue.x, startPointValue.y); - gradient->end = Vector2D(endPointValue.x, endPointValue.y); - } - } - - virtual std::shared_ptr fill() override { - return _fill; - } - - private: - FillRule rule; - int numberOfColors = 0; - GradientType gradientType; - - KeyframeInterpolator colors; - GradientColorSet colorsValue; - - KeyframeInterpolator startPoint; - Vector3D startPointValue = Vector3D(0.0, 0.0, 0.0); - - KeyframeInterpolator endPoint; - Vector3D endPointValue = Vector3D(0.0, 0.0, 0.0); - - KeyframeInterpolator opacity; - float opacityValue = 0.0; - - std::shared_ptr _fill; - }; - - class StrokeOutput { - public: - StrokeOutput() { - } - ~StrokeOutput() = default; - - virtual void update(AnimationFrameTime frameTime) = 0; - virtual std::shared_ptr stroke() = 0; - }; - - class SolidStrokeOutput : public StrokeOutput { - public: - SolidStrokeOutput(Stroke const &stroke) : - lineJoin(stroke.lineJoin), - lineCap(stroke.lineCap), - miterLimit(stroke.miterLimit.value_or(4.0)), - color(stroke.color.keyframes), - opacity(stroke.opacity.keyframes), - width(stroke.width.keyframes) { - if (stroke.dashPattern.has_value()) { - StrokeShapeDashConfiguration dashConfiguration(stroke.dashPattern.value()); - dashPattern = std::make_unique(dashConfiguration.dashPatterns); - - if (!dashConfiguration.dashPhase.empty()) { - dashPhase = std::make_unique>(dashConfiguration.dashPhase); - } - } - - auto solid = std::make_shared(Color(0.0, 0.0, 0.0, 0.0), 0.0); - _stroke = std::make_shared( - solid, - 0.0, - lineJoin, - lineCap, - miterLimit, - 0.0, - std::vector() - ); - } - - virtual ~SolidStrokeOutput() = default; - - virtual void update(AnimationFrameTime frameTime) override { - bool hasUpdates = false; - - if (color.hasUpdate(frameTime)) { - hasUpdates = true; - colorValue = color.value(frameTime); - } - - if (opacity.hasUpdate(frameTime)) { - hasUpdates = true; - opacityValue = opacity.value(frameTime).value; - } - - if (width.hasUpdate(frameTime)) { - hasUpdates = true; - widthValue = width.value(frameTime).value; - } - - if (dashPattern) { - if (dashPattern->hasUpdate(frameTime)) { - hasUpdates = true; - dashPatternValue = dashPattern->value(frameTime); - } - } - - if (dashPhase) { - if (dashPhase->hasUpdate(frameTime)) { - hasUpdates = true; - dashPhaseValue = dashPhase->value(frameTime).value; - } - } - - if (hasUpdates) { - bool hasNonZeroDashes = false; - if (!dashPatternValue.values.empty()) { - for (const auto &value : dashPatternValue.values) { - if (value != 0) { - hasNonZeroDashes = true; - break; - } - } - } - - RenderTreeNodeContentItem::SolidShading *solid = (RenderTreeNodeContentItem::SolidShading *)_stroke->shading.get(); - solid->color = colorValue; - solid->opacity = opacityValue * 0.01; - - _stroke->lineWidth = widthValue; - _stroke->dashPhase = hasNonZeroDashes ? dashPhaseValue : 0.0; - _stroke->dashPattern = hasNonZeroDashes ? dashPatternValue.values : std::vector(); - } - } - - virtual std::shared_ptr stroke() override { - return _stroke; - } - - private: - LineJoin lineJoin; - LineCap lineCap; - float miterLimit = 4.0; - - KeyframeInterpolator color; - Color colorValue = Color(0.0, 0.0, 0.0, 0.0); - - KeyframeInterpolator opacity; - float opacityValue = 0.0; - - KeyframeInterpolator width; - float widthValue = 0.0; - - std::unique_ptr dashPattern; - DashPattern dashPatternValue = DashPattern({}); - - std::unique_ptr> dashPhase; - float dashPhaseValue = 0.0; - - std::shared_ptr _stroke; - }; - - class GradientStrokeOutput : public StrokeOutput { - public: - GradientStrokeOutput(GradientStroke const &gradientStroke) : - lineJoin(gradientStroke.lineJoin), - lineCap(gradientStroke.lineCap), - miterLimit(gradientStroke.miterLimit.value_or(4.0)), - numberOfColors(gradientStroke.numberOfColors), - gradientType(gradientStroke.gradientType), - colors(gradientStroke.colors.keyframes), - startPoint(gradientStroke.startPoint.keyframes), - endPoint(gradientStroke.endPoint.keyframes), - opacity(gradientStroke.opacity.keyframes), - width(gradientStroke.width.keyframes) { - if (gradientStroke.dashPattern.has_value()) { - StrokeShapeDashConfiguration dashConfiguration(gradientStroke.dashPattern.value()); - dashPattern = std::make_unique(dashConfiguration.dashPatterns); - - if (!dashConfiguration.dashPhase.empty()) { - dashPhase = std::make_unique>(dashConfiguration.dashPhase); - } - } - - auto gradient = std::make_shared( - 0.0, - gradientType, - std::vector(), - std::vector(), - Vector2D(0.0, 0.0), - Vector2D(0.0, 0.0) - ); - _stroke = std::make_shared( - gradient, - 0.0, - lineJoin, - lineCap, - miterLimit, - 0.0, - std::vector() - ); - } - - virtual ~GradientStrokeOutput() = default; - - virtual void update(AnimationFrameTime frameTime) override { - bool hasUpdates = false; - - if (colors.hasUpdate(frameTime)) { - hasUpdates = true; - colorsValue = colors.value(frameTime); - } - - if (startPoint.hasUpdate(frameTime)) { - hasUpdates = true; - startPointValue = startPoint.value(frameTime); - } - - if (endPoint.hasUpdate(frameTime)) { - hasUpdates = true; - endPointValue = endPoint.value(frameTime); - } - - if (opacity.hasUpdate(frameTime)) { - hasUpdates = true; - opacityValue = opacity.value(frameTime).value; - } - - if (width.hasUpdate(frameTime)) { - hasUpdates = true; - widthValue = width.value(frameTime).value; - } - - if (dashPattern) { - if (dashPattern->hasUpdate(frameTime)) { - hasUpdates = true; - dashPatternValue = dashPattern->value(frameTime); - } - } - - if (dashPhase) { - if (dashPhase->hasUpdate(frameTime)) { - hasUpdates = true; - dashPhaseValue = dashPhase->value(frameTime).value; - } - } - - if (hasUpdates) { - bool hasNonZeroDashes = false; - if (!dashPatternValue.values.empty()) { - for (const auto &value : dashPatternValue.values) { - if (value != 0) { - hasNonZeroDashes = true; - break; - } - } - } - - std::vector colors; - std::vector locations; - getGradientParameters(numberOfColors, colorsValue, colors, locations); - - RenderTreeNodeContentItem::GradientShading *gradient = ((RenderTreeNodeContentItem::GradientShading *)_stroke->shading.get()); - gradient->opacity = opacityValue * 0.01; - gradient->colors = colors; - gradient->locations = locations; - gradient->start = Vector2D(startPointValue.x, startPointValue.y); - gradient->end = Vector2D(endPointValue.x, endPointValue.y); - - _stroke->lineWidth = widthValue; - _stroke->dashPhase = hasNonZeroDashes ? dashPhaseValue : 0.0; - _stroke->dashPattern = hasNonZeroDashes ? dashPatternValue.values : std::vector(); - } - } - - virtual std::shared_ptr stroke() override { - return _stroke; - } - - private: - LineJoin lineJoin; - LineCap lineCap; - float miterLimit = 4.0; - - int numberOfColors = 0; - GradientType gradientType; - - KeyframeInterpolator colors; - GradientColorSet colorsValue; - - KeyframeInterpolator startPoint; - Vector3D startPointValue = Vector3D(0.0, 0.0, 0.0); - - KeyframeInterpolator endPoint; - Vector3D endPointValue = Vector3D(0.0, 0.0, 0.0); - - KeyframeInterpolator opacity; - float opacityValue = 0.0; - - KeyframeInterpolator width; - float widthValue = 0.0; - - std::unique_ptr dashPattern; - DashPattern dashPatternValue = DashPattern({}); - - std::unique_ptr> dashPhase; - float dashPhaseValue = 0.0; - - std::shared_ptr _stroke; - }; - - class TrimParamsOutput { - public: - TrimParamsOutput(Trim const &trim) : - type(trim.trimType), - start(trim.start.keyframes), - end(trim.end.keyframes), - offset(trim.offset.keyframes) { - } - - void update(AnimationFrameTime frameTime) { - if (start.hasUpdate(frameTime)) { - startValue = start.value(frameTime).value; - } - - if (end.hasUpdate(frameTime)) { - endValue = end.value(frameTime).value; - } - - if (offset.hasUpdate(frameTime)) { - offsetValue = offset.value(frameTime).value; - } - } - - TrimParams trimParams() { - float resolvedStartValue = startValue * 0.01; - float resolvedEndValue = endValue * 0.01; - float resolvedStart = std::min(resolvedStartValue, resolvedEndValue); - float resolvedEnd = std::max(resolvedStartValue, resolvedEndValue); - - float resolvedOffset = fmod(offsetValue, 360.0) / 360.0; - - return TrimParams(resolvedStart, resolvedEnd, resolvedOffset, type); - } - - private: - TrimType type; - - KeyframeInterpolator start; - float startValue = 0.0; - - KeyframeInterpolator end; - float endValue = 0.0; - - KeyframeInterpolator offset; - float offsetValue = 0.0; - }; - - struct ShadingVariant { - std::shared_ptr fill; - std::shared_ptr stroke; - size_t subItemLimit = 0; - }; - - struct TransformedPath { - BezierPath path; - Transform2D transform; - - TransformedPath(BezierPath const &path_, Transform2D const &transform_) : - path(path_), - transform(transform_) { - } - }; - - class PathOutput { - public: - PathOutput() { - } - virtual ~PathOutput() = default; - - virtual void update(AnimationFrameTime frameTime) = 0; - virtual std::shared_ptr ¤tPath() = 0; - }; - - class StaticPathOutput : public PathOutput { - public: - explicit StaticPathOutput(BezierPath const &path) : - resolvedPath(std::make_shared(path)) { - } - - virtual void update(AnimationFrameTime frameTime) override { - } - - virtual std::shared_ptr ¤tPath() override { - return resolvedPath; - } - - private: - std::shared_ptr resolvedPath; - }; - - class ShapePathOutput : public PathOutput { - public: - explicit ShapePathOutput(Shape const &shape) : - path(shape.path.keyframes), - resolvedPath(std::make_shared(BezierPath())) { - } - - virtual void update(AnimationFrameTime frameTime) override { - if (!hasValidData || path.hasUpdate(frameTime)) { - path.update(frameTime, resolvedPath->path); - resolvedPath->needsBoundsRecalculation = true; - } - hasValidData = true; - } - - virtual std::shared_ptr ¤tPath() override { - return resolvedPath; - } - - private: - bool hasValidData = false; - - BezierPathKeyframeInterpolator path; - - std::shared_ptr resolvedPath; - }; - - class RectanglePathOutput : public PathOutput { - public: - explicit RectanglePathOutput(Rectangle const &rectangle) : - direction(rectangle.direction.value_or(PathDirection::Clockwise)), - position(rectangle.position.keyframes), - size(rectangle.size.keyframes), - cornerRadius(rectangle.cornerRadius.keyframes), - resolvedPath(std::make_shared(BezierPath())) { - } - - virtual void update(AnimationFrameTime frameTime) override { - bool hasUpdates = false; - - if (!hasValidData || position.hasUpdate(frameTime)) { - hasUpdates = true; - positionValue = position.value(frameTime); - } - if (!hasValidData || size.hasUpdate(frameTime)) { - hasUpdates = true; - sizeValue = size.value(frameTime); - } - if (!hasValidData || cornerRadius.hasUpdate(frameTime)) { - hasUpdates = true; - cornerRadiusValue = cornerRadius.value(frameTime).value; - } - - if (hasUpdates) { - ValueInterpolator::setInplace(makeRectangleBezierPath(Vector2D(positionValue.x, positionValue.y), Vector2D(sizeValue.x, sizeValue.y), cornerRadiusValue, direction), resolvedPath->path); - resolvedPath->needsBoundsRecalculation = true; - } - - hasValidData = true; - } - - virtual std::shared_ptr ¤tPath() override { - return resolvedPath; - } - - private: - bool hasValidData = false; - - PathDirection direction; - - KeyframeInterpolator position; - Vector3D positionValue = Vector3D(0.0, 0.0, 0.0); - - KeyframeInterpolator size; - Vector3D sizeValue = Vector3D(0.0, 0.0, 0.0); - - KeyframeInterpolator cornerRadius; - float cornerRadiusValue = 0.0; - - std::shared_ptr resolvedPath; - }; - - class EllipsePathOutput : public PathOutput { - public: - explicit EllipsePathOutput(Ellipse const &ellipse) : - direction(ellipse.direction.value_or(PathDirection::Clockwise)), - position(ellipse.position.keyframes), - size(ellipse.size.keyframes), - resolvedPath(std::make_shared(BezierPath())) { - } - - virtual void update(AnimationFrameTime frameTime) override { - bool hasUpdates = false; - - if (!hasValidData || position.hasUpdate(frameTime)) { - hasUpdates = true; - positionValue = position.value(frameTime); - } - if (!hasValidData || size.hasUpdate(frameTime)) { - hasUpdates = true; - sizeValue = size.value(frameTime); - } - - if (hasUpdates) { - ValueInterpolator::setInplace(makeEllipseBezierPath(Vector2D(sizeValue.x, sizeValue.y), Vector2D(positionValue.x, positionValue.y), direction), resolvedPath->path); - resolvedPath->needsBoundsRecalculation = true; - } - - hasValidData = true; - } - - virtual std::shared_ptr ¤tPath() override { - return resolvedPath; - } - - private: - bool hasValidData = false; - - PathDirection direction; - - KeyframeInterpolator position; - Vector3D positionValue = Vector3D(0.0, 0.0, 0.0); - - KeyframeInterpolator size; - Vector3D sizeValue = Vector3D(0.0, 0.0, 0.0); - - std::shared_ptr resolvedPath; - }; - - class StarPathOutput : public PathOutput { - public: - explicit StarPathOutput(Star const &star) : - direction(star.direction.value_or(PathDirection::Clockwise)), - position(star.position.keyframes), - outerRadius(star.outerRadius.keyframes), - outerRoundedness(star.outerRoundness.keyframes), - rotation(star.rotation.keyframes), - points(star.points.keyframes), - resolvedPath(std::make_shared(BezierPath())) { - if (star.innerRadius.has_value()) { - innerRadius = std::make_unique>(std::make_shared>(star.innerRadius->keyframes)); - } else { - innerRadius = std::make_unique>(std::make_shared>(Vector1D(0.0))); - } - - if (star.innerRoundness.has_value()) { - innerRoundedness = std::make_unique>(std::make_shared>(star.innerRoundness->keyframes)); - } else { - innerRoundedness = std::make_unique>(std::make_shared>(Vector1D(0.0))); - } - } - - virtual void update(AnimationFrameTime frameTime) override { - bool hasUpdates = false; - - if (!hasValidData || position.hasUpdate(frameTime)) { - hasUpdates = true; - positionValue = position.value(frameTime); - } - - if (!hasValidData || outerRadius.hasUpdate(frameTime)) { - hasUpdates = true; - outerRadiusValue = outerRadius.value(frameTime).value; - } - - innerRadius->update(frameTime); - if (!hasValidData || innerRadiusValue != innerRadius->value().value) { - hasUpdates = true; - innerRadiusValue = innerRadius->value().value; - } - - if (!hasValidData || outerRoundedness.hasUpdate(frameTime)) { - hasUpdates = true; - outerRoundednessValue = outerRoundedness.value(frameTime).value; - } - - innerRoundedness->update(frameTime); - if (!hasValidData || innerRoundednessValue != innerRoundedness->value().value) { - hasUpdates = true; - innerRoundednessValue = innerRoundedness->value().value; - } - - if (!hasValidData || points.hasUpdate(frameTime)) { - hasUpdates = true; - pointsValue = points.value(frameTime).value; - } - - if (!hasValidData || rotation.hasUpdate(frameTime)) { - hasUpdates = true; - rotationValue = rotation.value(frameTime).value; - } - - if (hasUpdates) { - ValueInterpolator::setInplace(makeStarBezierPath(Vector2D(positionValue.x, positionValue.y), outerRadiusValue, innerRadiusValue, outerRoundednessValue, innerRoundednessValue, pointsValue, rotationValue, direction), resolvedPath->path); - resolvedPath->needsBoundsRecalculation = true; - } - - hasValidData = true; - } - - virtual std::shared_ptr ¤tPath() override { - return resolvedPath; - } - - private: - bool hasValidData = false; - - PathDirection direction; - - KeyframeInterpolator position; - Vector3D positionValue = Vector3D(0.0, 0.0, 0.0); - - KeyframeInterpolator outerRadius; - float outerRadiusValue = 0.0; - - KeyframeInterpolator outerRoundedness; - float outerRoundednessValue = 0.0; - - std::unique_ptr> innerRadius; - float innerRadiusValue = 0.0; - - std::unique_ptr> innerRoundedness; - float innerRoundednessValue = 0.0; - - KeyframeInterpolator rotation; - float rotationValue = 0.0; - - KeyframeInterpolator points; - float pointsValue = 0.0; - - std::shared_ptr resolvedPath; - }; - - class TransformOutput { - public: - TransformOutput(std::shared_ptr shapeTransform) { - if (shapeTransform->anchor) { - _anchor = std::make_unique>(shapeTransform->anchor->keyframes); - } - if (shapeTransform->position) { - _position = std::make_unique>(shapeTransform->position->keyframes); - } - if (shapeTransform->scale) { - _scale = std::make_unique>(shapeTransform->scale->keyframes); - } - if (shapeTransform->rotation) { - _rotation = std::make_unique>(shapeTransform->rotation->keyframes); - } - if (shapeTransform->skew) { - _skew = std::make_unique>(shapeTransform->skew->keyframes); - } - if (shapeTransform->skewAxis) { - _skewAxis = std::make_unique>(shapeTransform->skewAxis->keyframes); - } - if (shapeTransform->opacity) { - _opacity = std::make_unique>(shapeTransform->opacity->keyframes); - } - } - - void update(AnimationFrameTime frameTime) { - bool hasUpdates = false; - - if (!hasValidData) { - hasUpdates = true; - } - if (_anchor && _anchor->hasUpdate(frameTime)) { - hasUpdates = true; - } - if (_position && _position->hasUpdate(frameTime)) { - hasUpdates = true; - } - if (_scale && _scale->hasUpdate(frameTime)) { - hasUpdates = true; - } - if (_rotation && _rotation->hasUpdate(frameTime)) { - hasUpdates = true; - } - if (_skew && _skew->hasUpdate(frameTime)) { - hasUpdates = true; - } - if (_skewAxis && _skewAxis->hasUpdate(frameTime)) { - hasUpdates = true; - } - if (_opacity && _opacity->hasUpdate(frameTime)) { - hasUpdates = true; - } - - if (hasUpdates) { - //TODO:optimize by storing components - - Vector3D anchorValue(0.0, 0.0, 0.0); - if (_anchor) { - anchorValue = _anchor->value(frameTime); - } - - Vector3D positionValue(0.0, 0.0, 0.0); - if (_position) { - positionValue = _position->value(frameTime); - } - - Vector3D scaleValue(100.0, 100.0, 100.0); - if (_scale) { - scaleValue = _scale->value(frameTime); - } - - float rotationValue = 0.0; - if (_rotation) { - rotationValue = _rotation->value(frameTime).value; - } - - float skewValue = 0.0; - if (_skew) { - skewValue = _skew->value(frameTime).value; - } - - float skewAxisValue = 0.0; - if (_skewAxis) { - skewAxisValue = _skewAxis->value(frameTime).value; - } - - if (_opacity) { - _opacityValue = _opacity->value(frameTime).value * 0.01; - } else { - _opacityValue = 1.0; - } - - _transformValue = Transform2D::identity().translated(Vector2D(positionValue.x, positionValue.y)).rotated(rotationValue).skewed(-skewValue, skewAxisValue).scaled(Vector2D(scaleValue.x * 0.01, scaleValue.y * 0.01)).translated(Vector2D(-anchorValue.x, -anchorValue.y)); - - hasValidData = true; - } - } - - Transform2D const &transform() { - return _transformValue; - } - - float opacity() { - return _opacityValue; - } - - private: - bool hasValidData = false; - - std::unique_ptr> _anchor; - std::unique_ptr> _position; - std::unique_ptr> _scale; - std::unique_ptr> _rotation; - std::unique_ptr> _skew; - std::unique_ptr> _skewAxis; - std::unique_ptr> _opacity; - - Transform2D _transformValue = Transform2D::identity(); - float _opacityValue = 1.0; - }; - - class ContentItem { - public: - ContentItem() { - } - - public: - bool isGroup = false; - - void setPath(std::unique_ptr &&path_) { - path = std::move(path_); - } - - void setTransform(std::unique_ptr &&transform_) { - transform = std::move(transform_); - } - - private: - std::unique_ptr path; - std::unique_ptr transform; - - std::vector shadings; - std::shared_ptr trim; - - public: - std::vector> subItems; - std::shared_ptr _contentItem; - - private: - std::vector collectPaths(size_t subItemLimit, Transform2D const &parentTransform, bool skipApplyTransform) { - std::vector mappedPaths; - - //TODO:remove skipApplyTransform - Transform2D effectiveTransform = parentTransform; - if (!skipApplyTransform && isGroup && transform) { - effectiveTransform = transform->transform() * effectiveTransform; - } - - size_t maxSubitem = std::min(subItems.size(), subItemLimit); - - if (_contentItem->path) { - mappedPaths.emplace_back(_contentItem->path->path, effectiveTransform); - } - - for (size_t i = 0; i < maxSubitem; i++) { - auto &subItem = subItems[i]; - - std::optional currentTrim; - if (trim) { - currentTrim = trim->trimParams(); - } - - auto subItemPaths = subItem->collectPaths(INT32_MAX, effectiveTransform, false); - - if (currentTrim) { - CompoundBezierPath tempPath; - for (auto &path : subItemPaths) { - tempPath.appendPath(path.path.copyUsingTransform(path.transform)); - } - CompoundBezierPath trimmedPath = trimCompoundPath(tempPath, currentTrim->start, currentTrim->end, currentTrim->offset, currentTrim->type); - for (auto &path : trimmedPath.paths) { - mappedPaths.emplace_back(path, Transform2D::identity()); - } - } else { - for (auto &path : subItemPaths) { - mappedPaths.emplace_back(path.path, path.transform); - } - } - } - - return mappedPaths; - } - - public: - void addSubItem(std::shared_ptr const &subItem) { - subItems.push_back(subItem); - } - - void addFill(std::shared_ptr fill) { - ShadingVariant shading; - shading.subItemLimit = subItems.size(); - shading.fill = fill; - shadings.insert(shadings.begin(), shading); - } - - void addStroke(std::shared_ptr stroke) { - ShadingVariant shading; - shading.subItemLimit = subItems.size(); - shading.stroke = stroke; - shadings.insert(shadings.begin(), shading); - } - - void setTrim(Trim const &trim_) { - trim = std::make_shared(trim_); - } - - public: - void initializeRenderChildren() { - _contentItem = std::make_shared(); - _contentItem->isGroup = isGroup; - - if (path) { - _contentItem->path = path->currentPath(); - } - - if (!shadings.empty()) { - for (int i = 0; i < shadings.size(); i++) { - auto &shadingVariant = shadings[i]; - - if (!(shadingVariant.fill || shadingVariant.stroke)) { - continue; - } - - _contentItem->drawContentCount++; - - auto itemShadingVariant = std::make_shared(); - if (shadingVariant.fill) { - itemShadingVariant->fill = shadingVariant.fill->fill(); - } - if (shadingVariant.stroke) { - itemShadingVariant->stroke = shadingVariant.stroke->stroke(); - } - itemShadingVariant->subItemLimit = shadingVariant.subItemLimit; - - _contentItem->shadings.push_back(itemShadingVariant); - } - } - - if (isGroup && !subItems.empty()) { - std::vector> subItemNodes; - for (const auto &subItem : subItems) { - subItem->initializeRenderChildren(); - _contentItem->drawContentCount += subItem->_contentItem->drawContentCount; - _contentItem->subItems.push_back(subItem->_contentItem); - } - } - } - - public: - void updateFrame(AnimationFrameTime frameTime, BezierPathsBoundingBoxContext &boundingBoxContext) { - if (transform) { - transform->update(frameTime); - } - - if (path) { - path->update(frameTime); - } - if (trim) { - trim->update(frameTime); - } - - for (const auto &shadingVariant : shadings) { - if (shadingVariant.fill) { - shadingVariant.fill->update(frameTime); - } - if (shadingVariant.stroke) { - shadingVariant.stroke->update(frameTime); - } - } - - for (const auto &subItem : subItems) { - subItem->updateFrame(frameTime, boundingBoxContext); - } - } - - bool hasTrims() { - if (trim) { - return true; - } - - for (const auto &subItem : subItems) { - if (subItem->hasTrims()) { - return true; - } - } - - return false; - } - - bool hasNestedTrims() { - for (const auto &subItem : subItems) { - if (subItem->hasTrims()) { - return true; - } - } - - return false; - } - - void updateContents(std::optional parentTrim) { - Transform2D containerTransform = Transform2D::identity(); - float containerOpacity = 1.0; - if (transform) { - containerTransform = transform->transform(); - containerOpacity = transform->opacity(); - } - _contentItem->transform = containerTransform; - _contentItem->alpha = containerOpacity; - - if (parentTrim) { - _contentItem->trimParams = parentTrim; - - CompoundBezierPath compoundPath; - auto paths = collectPaths(INT32_MAX, Transform2D::identity(), true); - for (const auto &path : paths) { - compoundPath.appendPath(path.path.copyUsingTransform(path.transform)); - } - - compoundPath = trimCompoundPath(compoundPath, parentTrim->start, parentTrim->end, parentTrim->offset, parentTrim->type); - - std::vector resultPaths; - for (const auto &path : compoundPath.paths) { - resultPaths.push_back(path); - } - - _contentItem->trimmedPaths = resultPaths; - } - - if (isGroup && !subItems.empty()) { - for (int i = (int)subItems.size() - 1; i >= 0; i--) { - std::optional childTrim = parentTrim; - if (trim) { - childTrim = trim->trimParams(); - } - - subItems[i]->updateContents(childTrim); - } - } - } - }; - -public: - ShapeLayerPresentationTree(std::vector> const &items) { - itemTree = std::make_shared(); - itemTree->isGroup = true; - ShapeLayerPresentationTree::renderTreeContent(items, itemTree); - } - - ShapeLayerPresentationTree(std::shared_ptr const &solidLayer) { - itemTree = std::make_shared(); - itemTree->isGroup = true; - - std::vector> items; - items.push_back(std::make_shared( - std::nullopt, - std::nullopt, - std::nullopt, - std::nullopt, - solidLayer->hidden, - std::nullopt, - std::nullopt, - std::nullopt, - std::nullopt, - KeyframeGroup(Vector3D(0.0, 0.0, 0.0)), - KeyframeGroup(Vector3D(solidLayer->width, solidLayer->height, 0.0)), - KeyframeGroup(Vector1D(0.0)) - )); - ShapeLayerPresentationTree::renderTreeContent(items, itemTree); - } - - virtual ~ShapeLayerPresentationTree() = default; - -private: - static void renderTreeContent(std::vector> const &items, std::shared_ptr &itemTree) { - for (const auto &item : items) { - if (item->hidden()) { - continue; - } - - switch (item->type) { - case ShapeType::Fill: { - Fill const &fill = *((Fill *)item.get()); - - itemTree->addFill(std::make_shared(fill)); - - break; - } - case ShapeType::GradientFill: { - GradientFill const &gradientFill = *((GradientFill *)item.get()); - - itemTree->addFill(std::make_shared(gradientFill)); - - break; - } - case ShapeType::Stroke: { - Stroke const &stroke = *((Stroke *)item.get()); - - itemTree->addStroke(std::make_shared(stroke)); - - break; - } - case ShapeType::GradientStroke: { - GradientStroke const &gradientStroke = *((GradientStroke *)item.get()); - - itemTree->addStroke(std::make_shared(gradientStroke)); - - break; - } - case ShapeType::Group: { - Group const &group = *((Group *)item.get()); - - auto groupItem = std::make_shared(); - groupItem->isGroup = true; - - ShapeLayerPresentationTree::renderTreeContent(group.items, groupItem); - - itemTree->addSubItem(groupItem); - - break; - } - case ShapeType::Shape: { - Shape const &shape = *((Shape *)item.get()); - - auto shapeItem = std::make_shared(); - shapeItem->setPath(std::make_unique(shape)); - itemTree->addSubItem(shapeItem); - - break; - } - case ShapeType::Trim: { - Trim const &trim = *((Trim *)item.get()); - - auto groupItem = std::make_shared(); - groupItem->isGroup = true; - groupItem->setTrim(trim); - - for (const auto &subItem : itemTree->subItems) { - groupItem->addSubItem(subItem); - } - itemTree->subItems.clear(); - itemTree->addSubItem(groupItem); - - break; - } - case ShapeType::Transform: { - auto transform = std::static_pointer_cast(item); - - itemTree->setTransform(std::make_unique(transform)); - - break; - } - case ShapeType::Ellipse: { - Ellipse const &ellipse = *((Ellipse *)item.get()); - - auto shapeItem = std::make_shared(); - shapeItem->setPath(std::make_unique(ellipse)); - itemTree->addSubItem(shapeItem); - - break; - } - case ShapeType::Merge: { - //assert(false); - break; - } - case ShapeType::Rectangle: { - Rectangle const &rectangle = *((Rectangle *)item.get()); - - auto shapeItem = std::make_shared(); - shapeItem->setPath(std::make_unique(rectangle)); - itemTree->addSubItem(shapeItem); - - break; - } - case ShapeType::Repeater: { - assert(false); - break; - } - case ShapeType::Star: { - Star const &star = *((Star *)item.get()); - - auto shapeItem = std::make_shared(); - shapeItem->setPath(std::make_unique(star)); - itemTree->addSubItem(shapeItem); - - break; - } - case ShapeType::RoundedRectangle: { - //TODO:restore - break; - } - default: { - break; - } - } - } - - itemTree->initializeRenderChildren(); - } - -public: - std::shared_ptr itemTree; -}; - -ShapeCompositionLayer::ShapeCompositionLayer(std::shared_ptr const &shapeLayer) : -CompositionLayer(shapeLayer, Vector2D::Zero()) { - _contentTree = std::make_shared(shapeLayer->items); -} - -ShapeCompositionLayer::ShapeCompositionLayer(std::shared_ptr const &solidLayer) : -CompositionLayer(solidLayer, Vector2D::Zero()) { - _contentTree = std::make_shared(solidLayer); -} - -void ShapeCompositionLayer::displayContentsWithFrame(float frame, bool forceUpdates, BezierPathsBoundingBoxContext &boundingBoxContext) { - _frameTime = frame; - _frameTimeInitialized = true; - _contentTree->itemTree->updateFrame(_frameTime, boundingBoxContext); - _contentTree->itemTree->updateContents(std::nullopt); -} - -std::shared_ptr ShapeCompositionLayer::renderTreeNode(BezierPathsBoundingBoxContext &boundingBoxContext) { - if (!_frameTimeInitialized) { - _frameTime = 0.0; - _frameTimeInitialized = true; - _contentTree->itemTree->updateFrame(_frameTime, boundingBoxContext); - _contentTree->itemTree->updateContents(std::nullopt); - } - - if (!_renderTreeNode) { - _contentRenderTreeNode = std::make_shared( - Vector2D(0.0, 0.0), - Transform2D::identity(), - 1.0, - false, - false, - std::vector>(), - nullptr, - false - ); - _contentRenderTreeNode->_contentItem = _contentTree->itemTree->_contentItem; - _contentRenderTreeNode->drawContentCount = _contentTree->itemTree->_contentItem->drawContentCount; - - std::vector> subnodes; - subnodes.push_back(_contentRenderTreeNode); - - std::shared_ptr maskNode; - bool invertMask = false; - if (_matteLayer) { - maskNode = _matteLayer->renderTreeNode(boundingBoxContext); - if (maskNode && _matteType.has_value() && _matteType.value() == MatteType::Invert) { - invertMask = true; - } - } - - _renderTreeNode = std::make_shared( - Vector2D(0.0, 0.0), - Transform2D::identity(), - 1.0, - false, - false, - subnodes, - maskNode, - invertMask - ); - } - - _contentRenderTreeNode->_size = _contentsLayer->size(); - _contentRenderTreeNode->_masksToBounds = _contentsLayer->masksToBounds(); - - _renderTreeNode->_masksToBounds = masksToBounds(); - - _renderTreeNode->_size = size(); - - return _renderTreeNode; -} - -void ShapeCompositionLayer::updateContentsLayerParameters() { - _contentRenderTreeNode->_transform = _contentsLayer->transform(); - _contentRenderTreeNode->_alpha = _contentsLayer->opacity(); - _contentRenderTreeNode->_isHidden = _contentsLayer->isHidden(); -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.hpp deleted file mode 100644 index 8aff5c77a6..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef ShapeCompositionLayer_hpp -#define ShapeCompositionLayer_hpp - -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.hpp" -#include "Lottie/Private/Model/Layers/ShapeLayerModel.hpp" -#include "Lottie/Private/Model/Layers/SolidLayerModel.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/Protocols/AnimatorNode.hpp" - -namespace lottie { - -class ShapeLayerPresentationTree; - -/// A CompositionLayer responsible for initializing and rendering shapes -class ShapeCompositionLayer: public CompositionLayer { -public: - ShapeCompositionLayer(std::shared_ptr const &shapeLayer); - ShapeCompositionLayer(std::shared_ptr const &solidLayer); - - virtual void displayContentsWithFrame(float frame, bool forceUpdates, BezierPathsBoundingBoxContext &boundingBoxContext) override; - virtual std::shared_ptr renderTreeNode(BezierPathsBoundingBoxContext &boundingBoxContext) override; - void initializeContentsLayerParameters(); - virtual void updateContentsLayerParameters() override; - -private: - std::shared_ptr _contentTree; - - AnimationFrameTime _frameTime = 0.0; - bool _frameTimeInitialized = false; - - std::shared_ptr _renderTreeNode; - std::shared_ptr _contentRenderTreeNode; -}; - -} - -#endif /* ShapeCompositionLayer_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeUtils/BezierPathUtils.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeUtils/BezierPathUtils.cpp deleted file mode 100644 index 71fc3cc1d7..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeUtils/BezierPathUtils.cpp +++ /dev/null @@ -1,487 +0,0 @@ -#include "BezierPathUtils.hpp" - -namespace lottie { - -BezierPath makeEllipseBezierPath( - Vector2D const &size, - Vector2D const ¢er, - PathDirection direction -) { - const float ControlPointConstant = 0.55228; - - Vector2D half = size * 0.5; - if (direction == PathDirection::CounterClockwise) { - half.x = half.x * -1.0; - } - - Vector2D q1(center.x, center.y - half.y); - Vector2D q2(center.x + half.x, center.y); - Vector2D q3(center.x, center.y + half.y); - Vector2D q4(center.x - half.x, center.y); - - Vector2D cp = half * ControlPointConstant; - - BezierPath path(CurveVertex::relative( - q1, - Vector2D(-cp.x, 0), - Vector2D(cp.x, 0))); - path.addVertex(CurveVertex::relative( - q2, - Vector2D(0, -cp.y), - Vector2D(0, cp.y))); - - path.addVertex(CurveVertex::relative( - q3, - Vector2D(cp.x, 0), - Vector2D(-cp.x, 0))); - - path.addVertex(CurveVertex::relative( - q4, - Vector2D(0, cp.y), - Vector2D(0, -cp.y))); - - path.addVertex(CurveVertex::relative( - q1, - Vector2D(-cp.x, 0), - Vector2D(cp.x, 0))); - path.close(); - return path; -} - -BezierPath makeRectangleBezierPath( - Vector2D const &position, - Vector2D const &inputSize, - float cornerRadius, - PathDirection direction -) { - const float ControlPointConstant = 0.55228; - - Vector2D size = inputSize * 0.5; - float radius = std::min(std::min(cornerRadius, (float)size.x), (float)size.y); - - BezierPath bezierPath; - std::vector points; - - if (radius <= 0.0) { - /// No Corners - points = { - /// Lead In - CurveVertex::relative( - Vector2D(size.x, -size.y), - Vector2D::Zero(), - Vector2D::Zero()) - .translated(position), - /// Corner 1 - CurveVertex::relative( - Vector2D(size.x, size.y), - Vector2D::Zero(), - Vector2D::Zero()) - .translated(position), - /// Corner 2 - CurveVertex::relative( - Vector2D(-size.x, size.y), - Vector2D::Zero(), - Vector2D::Zero()) - .translated(position), - /// Corner 3 - CurveVertex::relative( - Vector2D(-size.x, -size.y), - Vector2D::Zero(), - Vector2D::Zero()) - .translated(position), - /// Corner 4 - CurveVertex::relative( - Vector2D(size.x, -size.y), - Vector2D::Zero(), - Vector2D::Zero()) - .translated(position) - }; - } else { - float controlPoint = radius * ControlPointConstant; - points = { - /// Lead In - CurveVertex::absolute( - Vector2D(radius, 0), - Vector2D(radius, 0), - Vector2D(radius, 0)) - .translated(Vector2D(-radius, radius)) - .translated(Vector2D(size.x, -size.y)) - .translated(position), - /// Corner 1 - CurveVertex::absolute( - Vector2D(radius, 0), // Point - Vector2D(radius, 0), // In tangent - Vector2D(radius, controlPoint)) - .translated(Vector2D(-radius, -radius)) - .translated(Vector2D(size.x, size.y)) - .translated(position), - CurveVertex::absolute( - Vector2D(0, radius), // Point - Vector2D(controlPoint, radius), // In tangent - Vector2D(0, radius)) // Out Tangent - .translated(Vector2D(-radius, -radius)) - .translated(Vector2D(size.x, size.y)) - .translated(position), - /// Corner 2 - CurveVertex::absolute( - Vector2D(0, radius), // Point - Vector2D(0, radius), // In tangent - Vector2D(-controlPoint, radius))// Out tangent - .translated(Vector2D(radius, -radius)) - .translated(Vector2D(-size.x, size.y)) - .translated(position), - CurveVertex::absolute( - Vector2D(-radius, 0), // Point - Vector2D(-radius, controlPoint), // In tangent - Vector2D(-radius, 0)) // Out tangent - .translated(Vector2D(radius, -radius)) - .translated(Vector2D(-size.x, size.y)) - .translated(position), - /// Corner 3 - CurveVertex::absolute( - Vector2D(-radius, 0), // Point - Vector2D(-radius, 0), // In tangent - Vector2D(-radius, -controlPoint)) // Out tangent - .translated(Vector2D(radius, radius)) - .translated(Vector2D(-size.x, -size.y)) - .translated(position), - CurveVertex::absolute( - Vector2D(0, -radius), // Point - Vector2D(-controlPoint, -radius), // In tangent - Vector2D(0, -radius)) // Out tangent - .translated(Vector2D(radius, radius)) - .translated(Vector2D(-size.x, -size.y)) - .translated(position), - /// Corner 4 - CurveVertex::absolute( - Vector2D(0, -radius), // Point - Vector2D(0, -radius), // In tangent - Vector2D(controlPoint, -radius)) // Out tangent - .translated(Vector2D(-radius, radius)) - .translated(Vector2D(size.x, -size.y)) - .translated(position), - CurveVertex::absolute( - Vector2D(radius, 0), // Point - Vector2D(radius, -controlPoint), // In tangent - Vector2D(radius, 0)) // Out tangent - .translated(Vector2D(-radius, radius)) - .translated(Vector2D(size.x, -size.y)) - .translated(position) - }; - } - bool reversed = direction == PathDirection::CounterClockwise; - if (reversed) { - for (auto vertexIt = points.rbegin(); vertexIt != points.rend(); vertexIt++) { - bezierPath.addVertex((*vertexIt).reversed()); - } - } else { - for (auto vertexIt = points.begin(); vertexIt != points.end(); vertexIt++) { - bezierPath.addVertex(*vertexIt); - } - } - bezierPath.close(); - return bezierPath; -} - -/// Magic number needed for building path data -static constexpr float StarNodePolystarConstant = 0.47829; - -BezierPath makeStarBezierPath( - Vector2D const &position, - float outerRadius, - float innerRadius, - float inputOuterRoundedness, - float inputInnerRoundedness, - float numberOfPoints, - float rotation, - PathDirection direction -) { - float currentAngle = degreesToRadians(rotation - 90.0); - float anglePerPoint = (2.0 * M_PI) / numberOfPoints; - float halfAnglePerPoint = anglePerPoint / 2.0; - float partialPointAmount = numberOfPoints - floor(numberOfPoints); - float outerRoundedness = inputOuterRoundedness * 0.01; - float innerRoundedness = inputInnerRoundedness * 0.01; - - Vector2D point = Vector2D::Zero(); - - float partialPointRadius = 0.0; - if (partialPointAmount != 0.0) { - currentAngle += halfAnglePerPoint * (1 - partialPointAmount); - partialPointRadius = innerRadius + partialPointAmount * (outerRadius - innerRadius); - point.x = (partialPointRadius * cos(currentAngle)); - point.y = (partialPointRadius * sin(currentAngle)); - currentAngle += anglePerPoint * partialPointAmount / 2; - } else { - point.x = (outerRadius * cos(currentAngle)); - point.y = (outerRadius * sin(currentAngle)); - currentAngle += halfAnglePerPoint; - } - - std::vector vertices; - vertices.push_back(CurveVertex::relative(point + position, Vector2D::Zero(), Vector2D::Zero())); - - Vector2D previousPoint = point; - bool longSegment = false; - int numPoints = (int)(ceil(numberOfPoints) * 2.0); - for (int i = 0; i < numPoints; i++) { - float radius = longSegment ? outerRadius : innerRadius; - float dTheta = halfAnglePerPoint; - if (partialPointRadius != 0.0 && i == numPoints - 2) { - dTheta = anglePerPoint * partialPointAmount / 2; - } - if (partialPointRadius != 0.0 && i == numPoints - 1) { - radius = partialPointRadius; - } - previousPoint = point; - point.x = (radius * cos(currentAngle)); - point.y = (radius * sin(currentAngle)); - - if (innerRoundedness == 0.0 && outerRoundedness == 0.0) { - vertices.push_back(CurveVertex::relative(point + position, Vector2D::Zero(), Vector2D::Zero())); - } else { - float cp1Theta = (atan2(previousPoint.y, previousPoint.x) - M_PI / 2.0); - float cp1Dx = cos(cp1Theta); - float cp1Dy = sin(cp1Theta); - - float cp2Theta = (atan2(point.y, point.x) - M_PI / 2.0); - float cp2Dx = cos(cp2Theta); - float cp2Dy = sin(cp2Theta); - - float cp1Roundedness = longSegment ? innerRoundedness : outerRoundedness; - float cp2Roundedness = longSegment ? outerRoundedness : innerRoundedness; - float cp1Radius = longSegment ? innerRadius : outerRadius; - float cp2Radius = longSegment ? outerRadius : innerRadius; - - Vector2D cp1( - cp1Radius * cp1Roundedness * StarNodePolystarConstant * cp1Dx, - cp1Radius * cp1Roundedness * StarNodePolystarConstant * cp1Dy - ); - Vector2D cp2( - cp2Radius * cp2Roundedness * StarNodePolystarConstant * cp2Dx, - cp2Radius * cp2Roundedness * StarNodePolystarConstant * cp2Dy - ); - if (partialPointAmount != 0.0) { - if (i == 0) { - cp1 = cp1 * partialPointAmount; - } else if (i == numPoints - 1) { - cp2 = cp2 * partialPointAmount; - } - } - auto previousVertex = vertices[vertices.size() - 1]; - vertices[vertices.size() - 1] = CurveVertex::absolute( - previousVertex.point, - previousVertex.inTangent, - previousVertex.point - cp1 - ); - vertices.push_back(CurveVertex::relative(point + position, cp2, Vector2D::Zero())); - } - currentAngle += dTheta; - longSegment = !longSegment; - } - - bool reverse = direction == PathDirection::CounterClockwise; - BezierPath path; - if (reverse) { - for (auto vertexIt = vertices.rbegin(); vertexIt != vertices.rend(); vertexIt++) { - path.addVertex((*vertexIt).reversed()); - } - } else { - for (auto vertexIt = vertices.begin(); vertexIt != vertices.end(); vertexIt++) { - path.addVertex(*vertexIt); - } - } - path.close(); - return path; -} - -CompoundBezierPath trimCompoundPath(CompoundBezierPath sourcePath, float start, float end, float offset, TrimType type) { - /// No need to trim, it's a full path - if (start == 0.0 && end == 1.0) { - return sourcePath; - } - - /// All paths are empty. - if (start == end) { - return CompoundBezierPath(); - } - - if (type == TrimType::Simultaneously) { - CompoundBezierPath result; - - for (BezierPath &path : sourcePath.paths) { - CompoundBezierPath tempPath; - tempPath.appendPath(path); - - auto subPaths = tempPath.trim(start, end, offset); - - for (const auto &subPath : subPaths->paths) { - result.appendPath(subPath); - } - } - - return result; - } - - /// Individual path trimming. - - /// Brace yourself for the below code. - - /// Normalize lengths with offset. - float startPosition = fmod(start + offset, 1.0); - float endPosition = fmod(end + offset, 1.0); - - if (startPosition < 0.0) { - startPosition = 1.0 + startPosition; - } - - if (endPosition < 0.0) { - endPosition = 1.0 + endPosition; - } - if (startPosition == 1.0) { - startPosition = 0.0; - } - if (endPosition == 0.0) { - endPosition = 1.0; - } - - /// First get the total length of all paths. - float totalLength = 0.0; - for (auto &upstreamPath : sourcePath.paths) { - totalLength += upstreamPath.length(); - } - - /// Now determine the start and end cut lengths - float startLength = startPosition * totalLength; - float endLength = endPosition * totalLength; - float pathStart = 0.0; - - CompoundBezierPath result; - - /// Now loop through all path containers - for (auto &pathContainer : sourcePath.paths) { - auto pathEnd = pathStart + pathContainer.length(); - - if (!isInRange(startLength, pathStart, pathEnd) && - isInRange(endLength, pathStart, pathEnd)) { - // pathStart|=======E----------------------|pathEnd - // Cut path components, removing after end. - - float pathCutLength = endLength - pathStart; - float subpathStart = 0.0; - float subpathEnd = subpathStart + pathContainer.length(); - if (pathCutLength < subpathEnd) { - /// This is the subpath that needs to be cut. - float cutLength = pathCutLength - subpathStart; - - CompoundBezierPath tempPath; - tempPath.appendPath(pathContainer); - auto newPaths = tempPath.trim(0, cutLength / pathContainer.length(), 0); - for (const auto &newPath : newPaths->paths) { - result.appendPath(newPath); - } - } else { - /// Add to container and move on - result.appendPath(pathContainer); - } - /*if (pathCutLength == subpathEnd) { - /// Right on the end. The next subpath is not included. Break. - break; - } - subpathStart = subpathEnd;*/ - } else if (!isInRange(endLength, pathStart, pathEnd) && - isInRange(startLength, pathStart, pathEnd)) { - // pathStart|-------S======================|pathEnd - // - - // Cut path components, removing before beginning. - float pathCutLength = startLength - pathStart; - // Clear paths from container - float subpathStart = 0.0; - float subpathEnd = subpathStart + pathContainer.length(); - - if (subpathStart < pathCutLength && pathCutLength < subpathEnd) { - /// This is the subpath that needs to be cut. - float cutLength = pathCutLength - subpathStart; - CompoundBezierPath tempPath; - tempPath.appendPath(pathContainer); - auto newPaths = tempPath.trim(cutLength / pathContainer.length(), 1, 0); - for (const auto &newPath : newPaths->paths) { - result.appendPath(newPath); - } - } else if (pathCutLength <= subpathStart) { - result.appendPath(pathContainer); - } - //subpathStart = subpathEnd; - } else if (isInRange(endLength, pathStart, pathEnd) && - isInRange(startLength, pathStart, pathEnd)) { - // pathStart|-------S============E---------|endLength - // pathStart|=====E----------------S=======|endLength - // trim from path beginning to endLength. - - // Cut path components, removing before beginnings. - float startCutLength = startLength - pathStart; - float endCutLength = endLength - pathStart; - - float subpathStart = 0.0; - - float subpathEnd = subpathStart + pathContainer.length(); - - if (!isInRange(startCutLength, subpathStart, subpathEnd) && - !isInRange(endCutLength, subpathStart, subpathEnd)) - { - // The whole path is included. Add - // S|==============================|E - result.appendPath(pathContainer); - } else if (isInRange(startCutLength, subpathStart, subpathEnd) && - !isInRange(endCutLength, subpathStart, subpathEnd)) { - /// The start of the path needs to be trimmed - // |-------S======================|E - float cutLength = startCutLength - subpathStart; - CompoundBezierPath tempPath; - tempPath.appendPath(pathContainer); - auto newPaths = tempPath.trim(cutLength / pathContainer.length(), 1, 0); - for (const auto &newPath : newPaths->paths) { - result.appendPath(newPath); - } - } else if (!isInRange(startCutLength, subpathStart, subpathEnd) && - isInRange(endCutLength, subpathStart, subpathEnd)) { - // S|=======E----------------------| - float cutLength = endCutLength - subpathStart; - CompoundBezierPath tempPath; - tempPath.appendPath(pathContainer); - auto newPaths = tempPath.trim(0, cutLength / pathContainer.length(), 0); - for (const auto &newPath : newPaths->paths) { - result.appendPath(newPath); - } - } else if (isInRange(startCutLength, subpathStart, subpathEnd) && - isInRange(endCutLength, subpathStart, subpathEnd)) { - // |-------S============E---------| - float cutFromLength = startCutLength - subpathStart; - float cutToLength = endCutLength - subpathStart; - CompoundBezierPath tempPath; - tempPath.appendPath(pathContainer); - auto newPaths = tempPath.trim( - cutFromLength / pathContainer.length(), - cutToLength / pathContainer.length(), - 0 - ); - for (const auto &newPath : newPaths->paths) { - result.appendPath(newPath); - } - } - } else if ((endLength <= pathStart && pathEnd <= startLength) || - (startLength <= pathStart && endLength <= pathStart) || - (pathEnd <= startLength && pathEnd <= endLength)) { - /// The Path needs to be cleared - } else { - result.appendPath(pathContainer); - } - - pathStart = pathEnd; - } - - return result; -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeUtils/BezierPathUtils.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeUtils/BezierPathUtils.hpp deleted file mode 100644 index 677dbe96bd..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeUtils/BezierPathUtils.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef BezierPaths_h -#define BezierPaths_h - -#include "Lottie/Private/Model/ShapeItems/Ellipse.hpp" -#include -#include "Lottie/Private/Utility/Primitives/CompoundBezierPath.hpp" -#include "Lottie/Private/Model/ShapeItems/Trim.hpp" - -namespace lottie { - -BezierPath makeEllipseBezierPath( - Vector2D const &size, - Vector2D const ¢er, - PathDirection direction -); - -BezierPath makeRectangleBezierPath( - Vector2D const &position, - Vector2D const &inputSize, - float cornerRadius, - PathDirection direction -); - -BezierPath makeStarBezierPath( - Vector2D const &position, - float outerRadius, - float innerRadius, - float inputOuterRoundedness, - float inputInnerRoundedness, - float numberOfPoints, - float rotation, - PathDirection direction -); - -CompoundBezierPath trimCompoundPath(CompoundBezierPath sourcePath, float start, float end, float offset, TrimType type); - -} - -#endif /* BezierPaths_h */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.cpp deleted file mode 100644 index 5e773d361b..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "TextCompositionLayer.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.hpp deleted file mode 100644 index 98d7edbbc2..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef TextCompositionLayer_hpp -#define TextCompositionLayer_hpp - -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.hpp" -#include "Lottie/Private/Model/Layers/TextLayerModel.hpp" -#include "Lottie/Public/TextProvider/AnimationTextProvider.hpp" -#include "Lottie/Public/FontProvider/AnimationFontProvider.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/Nodes/Text/TextAnimatorNode.hpp" - -namespace lottie { - -class TextCompositionLayer: public CompositionLayer { -public: - TextCompositionLayer(std::shared_ptr const &textLayer, std::shared_ptr textProvider, std::shared_ptr fontProvider) : - CompositionLayer(textLayer, Vector2D::Zero()) { - std::shared_ptr rootNode; - for (const auto &animator : textLayer->animators) { - rootNode = std::make_shared(rootNode, animator); - } - _rootNode = rootNode; - _textDocument = std::make_shared>(textLayer->text.keyframes); - - _textProvider = textProvider; - _fontProvider = fontProvider; - - if (_rootNode) { - _childKeypaths.push_back(rootNode); - } - } - - std::shared_ptr const &textProvider() const { - return _textProvider; - } - void setTextProvider(std::shared_ptr const &textProvider) { - _textProvider = textProvider; - } - - std::shared_ptr const &fontProvider() const { - return _fontProvider; - } - void setFontProvider(std::shared_ptr const &fontProvider) { - _fontProvider = fontProvider; - } - - virtual void displayContentsWithFrame(float frame, bool forceUpdates, BezierPathsBoundingBoxContext &boundingBoxContext) override { - if (!_textDocument) { - return; - } - - bool documentUpdate = _textDocument->hasUpdate(frame); - - bool animatorUpdate = false; - if (_rootNode) { - animatorUpdate = _rootNode->updateContents(frame, forceUpdates); - } - - if (!(documentUpdate || animatorUpdate)) { - return; - } - - if (_rootNode) { - _rootNode->rebuildOutputs(frame); - } - } - -public: - virtual bool isTextCompositionLayer() const override { - return true; - } - -private: - std::shared_ptr _rootNode; - std::shared_ptr> _textDocument; - - std::shared_ptr _textProvider; - std::shared_ptr _fontProvider; -}; - -} - -#endif /* TextCompositionLayer_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/MainThreadAnimationLayer.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/MainThreadAnimationLayer.cpp deleted file mode 100644 index a205f16eba..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/MainThreadAnimationLayer.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "MainThreadAnimationLayer.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/MainThreadAnimationLayer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/MainThreadAnimationLayer.hpp deleted file mode 100644 index b9e47a7a60..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/MainThreadAnimationLayer.hpp +++ /dev/null @@ -1,279 +0,0 @@ -#ifndef MainThreadAnimationLayer_hpp -#define MainThreadAnimationLayer_hpp - -#include "Lottie/Public/Primitives/CALayer.hpp" -#include "Lottie/Public/ImageProvider/AnimationImageProvider.hpp" -#include "Lottie/Private/Model/Animation.hpp" -#include "Lottie/Public/TextProvider/AnimationTextProvider.hpp" -#include "Lottie/Public/FontProvider/AnimationFontProvider.hpp" -#include "Lottie/Private/MainThread/LayerContainers/Utility/LayerImageProvider.hpp" -#include "Lottie/Private/MainThread/LayerContainers/Utility/LayerTextProvider.hpp" -#include "Lottie/Private/MainThread/LayerContainers/Utility/CompositionLayersInitializer.hpp" -#include "Lottie/Private/MainThread/LayerContainers/Utility/LayerFontProvider.hpp" -#include "Lottie/Public/DynamicProperties/AnyValueProvider.hpp" -#include "Lottie/Public/DynamicProperties/AnimationKeypath.hpp" - -namespace lottie { - -class BlankImageProvider: public AnimationImageProvider { -public: - virtual ~BlankImageProvider() = default; - - std::shared_ptr imageForAsset(ImageAsset const &asset) { - return nullptr; - } -}; - -class MainThreadAnimationLayer: public CALayer { -public: - MainThreadAnimationLayer( - Animation const &animation, - std::shared_ptr const &imageProvider, - std::shared_ptr const &textProvider, - std::shared_ptr const &fontProvider - ) { - if (animation.assetLibrary) { - _layerImageProvider = std::make_shared(imageProvider, animation.assetLibrary->imageAssets); - } else { - std::map> imageAssets; - _layerImageProvider = std::make_shared(imageProvider, imageAssets); - } - - _layerTextProvider = std::make_shared(textProvider); - _layerFontProvider = std::make_shared(fontProvider); - - setSize(Vector2D(animation.width, animation.height)); - - auto layers = initializeCompositionLayers( - animation.layers, - animation.assetLibrary, - _layerImageProvider, - textProvider, - fontProvider, - animation.framerate - ); - - std::vector> imageLayers; - std::vector> textLayers; - - std::shared_ptr mattedLayer; - - for (auto layerIt = layers.rbegin(); layerIt != layers.rend(); layerIt++) { - std::shared_ptr const &layer = *layerIt; - layer->setSize(size()); - _animationLayers.push_back(layer); - - if (layer->isImageCompositionLayer()) { - imageLayers.push_back(std::static_pointer_cast(layer)); - } - if (layer->isTextCompositionLayer()) { - textLayers.push_back(std::static_pointer_cast(layer)); - } - - if (mattedLayer) { - /// The previous layer requires this layer to be its matte - mattedLayer->setMatteLayer(layer); - mattedLayer = nullptr; - continue; - } - if (layer->matteType().has_value() && (layer->matteType() == MatteType::Add || layer->matteType() == MatteType::Invert)) { - /// We have a layer that requires a matte. - mattedLayer = layer; - } - addSublayer(layer); - } - - _layerImageProvider->addImageLayers(imageLayers); - _layerImageProvider->reloadImages(); - _layerTextProvider->addTextLayers(textLayers); - _layerTextProvider->reloadTexts(); - _layerFontProvider->addTextLayers(textLayers); - _layerFontProvider->reloadTexts(); - - renderTreeNode(); - } - - void setRespectAnimationFrameRate(bool respectAnimationFrameRate) { - _respectAnimationFrameRate = respectAnimationFrameRate; - } - - void display() { - float newFrame = currentFrame(); - if (_respectAnimationFrameRate) { - newFrame = floor(newFrame); - } - for (const auto &layer : _animationLayers) { - layer->displayWithFrame(newFrame, false, _boundingBoxContext); - } - } - - std::vector> const &animationLayers() const { - return _animationLayers; - } - - void reloadImages() { - _layerImageProvider->reloadImages(); - } - - /// Forces the view to update its drawing. - void forceDisplayUpdate() { - for (const auto &layer : _animationLayers) { - layer->displayWithFrame(currentFrame(), true, _boundingBoxContext); - } - } - - void logHierarchyKeypaths() { - printf("Lottie: Logging Animation Keypaths\n"); - assert(false); - //animationLayers.forEach({ $0.logKeypaths(for: nil) }) - } - - void setValueProvider(std::shared_ptr const &valueProvider, AnimationKeypath const &keypath) { - /*for (const auto &layer : _animationLayers) { - assert(false); - if let foundProperties = layer.nodeProperties(for: keypath) { - for property in foundProperties { - property.setProvider(provider: valueProvider) - } - layer.displayWithFrame(frame: presentation()?.currentFrame ?? currentFrame, forceUpdates: true) - } - }*/ - } - - std::optional getValue(AnimationKeypath const &keypath, std::optional atFrame) { - /*for (const auto &layer : _animationLayers) { - assert(false); - if - let foundProperties = layer.nodeProperties(for: keypath), - let first = foundProperties.first - { - return first.valueProvider.value(frame: atFrame ?? currentFrame) - } - }*/ - return std::nullopt; - } - - std::optional getOriginalValue(AnimationKeypath const &keypath, std::optional atFrame) { - /*for (const auto &layer : _animationLayers) { - assert(false); - if - let foundProperties = layer.nodeProperties(for: keypath), - let first = foundProperties.first - { - return first.originalValueProvider.value(frame: atFrame ?? currentFrame) - } - }*/ - return std::nullopt; - } - - std::shared_ptr layerForKeypath(AnimationKeypath const &keyPath) { - assert(false); - /*for layer in animationLayers { - if let foundLayer = layer.layer(for: keypath) { - return foundLayer - } - }*/ - return nullptr; - } - - std::vector> animatorNodesForKeypath(AnimationKeypath const &keypath) { - std::vector> results; - /*for (const auto &layer : _animationLayers) { - if let nodes = layer.animatorNodes(for: keypath) { - results.append(contentsOf: nodes) - } - }*/ - return results; - } - - float currentFrame() const { - return _currentFrame; - } - void setCurrentFrame(float currentFrame) { - _currentFrame = currentFrame; - - for (size_t i = 0; i < _animationLayers.size(); i++) { - _animationLayers[i]->displayWithFrame(_currentFrame, false, _boundingBoxContext); - } - } - - std::shared_ptr imageProvider() const { - return _layerImageProvider->imageProvider(); - } - void setImageProvider(std::shared_ptr const &imageProvider) { - _layerImageProvider->setImageProvider(imageProvider); - } - - std::shared_ptr textProvider() const { - return _layerTextProvider->textProvider(); - } - void setTextProvider(std::shared_ptr const &textProvider) { - _layerTextProvider->setTextProvider(textProvider); - } - - std::shared_ptr fontProvider() const { - return _layerFontProvider->fontProvider(); - } - void setFontProvider(std::shared_ptr const &fontProvider) { - _layerFontProvider->setFontProvider(fontProvider); - } - - virtual std::shared_ptr renderTreeNode() { - if (!_renderTreeNode) { - std::vector> subnodes; - for (const auto &animationLayer : _animationLayers) { - bool found = false; - for (const auto &sublayer : sublayers()) { - if (animationLayer == sublayer) { - found = true; - break; - } - } - if (found) { - auto node = animationLayer->renderTreeNode(_boundingBoxContext); - if (node) { - subnodes.push_back(node); - } - } - } - _renderTreeNode = std::make_shared( - size(), - Transform2D::identity(), - 1.0, - false, - false, - subnodes, - nullptr, - false - ); - } - - return _renderTreeNode; - } - -private: - // MARK: Internal - - /// The animatable Current Frame Property - float _currentFrame = 0.0; - - std::shared_ptr _imageProvider; - std::shared_ptr _textProvider; - std::shared_ptr _fontProvider; - - bool _respectAnimationFrameRate = true; - - std::vector> _animationLayers; - - std::shared_ptr _layerImageProvider; - std::shared_ptr _layerTextProvider; - std::shared_ptr _layerFontProvider; - - std::shared_ptr _renderTreeNode; - - BezierPathsBoundingBoxContext _boundingBoxContext; -}; - -} - -#endif /* MainThreadAnimationLayer_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/CompositionLayersInitializer.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/CompositionLayersInitializer.cpp deleted file mode 100644 index 8a98548bd3..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/CompositionLayersInitializer.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "CompositionLayersInitializer.hpp" - -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/NullCompositionLayer.hpp" -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.hpp" -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.hpp" -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/ImageCompositionLayer.hpp" -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.hpp" - -namespace lottie { - -std::vector> initializeCompositionLayers( - std::vector> const &layers, - std::shared_ptr const &assetLibrary, - std::shared_ptr const &layerImageProvider, - std::shared_ptr const &textProvider, - std::shared_ptr const &fontProvider, - float frameRate -) { - std::vector> compositionLayers; - std::map> layerMap; - - std::vector> childLayers; - - for (const auto &layer : layers) { - if (layer->hidden) { - auto genericLayer = std::make_shared(layer); - compositionLayers.push_back(genericLayer); - if (layer->index) { - layerMap.insert(std::make_pair(layer->index.value(), genericLayer)); - } - } else if (layer->type == LayerType::Shape) { - auto shapeContainer = std::make_shared(std::static_pointer_cast(layer)); - compositionLayers.push_back(shapeContainer); - if (layer->index) { - layerMap.insert(std::make_pair(layer->index.value(), shapeContainer)); - } - } else if (layer->type == LayerType::Solid) { - auto shapeContainer = std::make_shared(std::static_pointer_cast(layer)); - compositionLayers.push_back(shapeContainer); - if (layer->index) { - layerMap.insert(std::make_pair(layer->index.value(), shapeContainer)); - } - } else if (layer->type == LayerType::Precomp && assetLibrary) { - auto precompLayer = std::static_pointer_cast(layer); - auto precompAssetIt = assetLibrary->precompAssets.find(precompLayer->referenceID); - if (precompAssetIt != assetLibrary->precompAssets.end()) { - auto precompContainer = std::make_shared( - precompLayer, - *(precompAssetIt->second), - layerImageProvider, - textProvider, - fontProvider, - assetLibrary, - frameRate - ); - compositionLayers.push_back(precompContainer); - if (layer->index) { - layerMap.insert(std::make_pair(layer->index.value(), precompContainer)); - } - } - } else if (layer->type == LayerType::Image && assetLibrary) { - auto imageLayer = std::static_pointer_cast(layer); - auto imageAssetIt = assetLibrary->imageAssets.find(imageLayer->referenceID); - if (imageAssetIt != assetLibrary->imageAssets.end()) { - auto imageContainer = std::make_shared( - imageLayer, - Vector2D((*imageAssetIt->second).width, (*imageAssetIt->second).height) - ); - compositionLayers.push_back(imageContainer); - if (layer->index) { - layerMap.insert(std::make_pair(layer->index.value(), imageContainer)); - } - } - } else if (layer->type == LayerType::Text) { - auto textContainer = std::make_shared(std::static_pointer_cast(layer), textProvider, fontProvider); - compositionLayers.push_back(textContainer); - if (layer->index) { - layerMap.insert(std::make_pair(layer->index.value(), textContainer)); - } - } else { - auto genericLayer = std::make_shared(layer); - compositionLayers.push_back(genericLayer); - if (layer->index) { - layerMap.insert(std::make_pair(layer->index.value(), genericLayer)); - } - } - if (layer->parent) { - childLayers.push_back(layer); - } - } - - /// Now link children with their parents - for (const auto &layerModel : childLayers) { - if (!layerModel->index.has_value()) { - continue; - } - if (const auto parentID = layerModel->parent) { - auto childLayerIt = layerMap.find(layerModel->index.value()); - if (childLayerIt != layerMap.end()) { - auto parentLayerIt = layerMap.find(parentID.value()); - if (parentLayerIt != layerMap.end()) { - childLayerIt->second->transformNode()->setParentNode(parentLayerIt->second->transformNode()); - } - } - } - } - - return compositionLayers; -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/CompositionLayersInitializer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/CompositionLayersInitializer.hpp deleted file mode 100644 index 74df3529d3..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/CompositionLayersInitializer.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef CompositionLayersInitializer_hpp -#define CompositionLayersInitializer_hpp - -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.hpp" -#include "Lottie/Private/Model/Assets/AssetLibrary.hpp" -#include "Lottie/Private/MainThread/LayerContainers/Utility/LayerImageProvider.hpp" -#include "Lottie/Public/TextProvider/AnimationTextProvider.hpp" -#include "Lottie/Public/FontProvider/AnimationFontProvider.hpp" - -namespace lottie { - -std::vector> initializeCompositionLayers( - std::vector> const &layers, - std::shared_ptr const &assetLibrary, - std::shared_ptr const &layerImageProvider, - std::shared_ptr const &textProvider, - std::shared_ptr const &fontProvider, - float frameRate -); - -} - -#endif /* CompositionLayersInitializer_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerFontProvider.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerFontProvider.cpp deleted file mode 100644 index d6123ee219..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerFontProvider.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "LayerFontProvider.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerFontProvider.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerFontProvider.hpp deleted file mode 100644 index ff9eaae19c..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerFontProvider.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef LayerFontProvider_hpp -#define LayerFontProvider_hpp - -#include "Lottie/Public/FontProvider/AnimationFontProvider.hpp" -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.hpp" - -namespace lottie { - -/// Connects a LottieFontProvider to a group of text layers -class LayerFontProvider { -public: - LayerFontProvider(std::shared_ptr const &fontProvider) { - _fontProvider = fontProvider; - reloadTexts(); - } - - std::shared_ptr const &fontProvider() const { - return _fontProvider; - } - void setFontProvider(std::shared_ptr const &fontProvider) { - _fontProvider = fontProvider; - reloadTexts(); - } - - void addTextLayers(std::vector> const &layers) { - for (const auto &layer : layers) { - _textLayers.push_back(layer); - } - } - - void reloadTexts() { - for (const auto &layer : _textLayers) { - layer->setFontProvider(_fontProvider); - } - } - -private: - std::vector> _textLayers; - - std::shared_ptr _fontProvider; -}; - -} - -#endif /* LayerFontProvider_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerImageProvider.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerImageProvider.cpp deleted file mode 100644 index 536c043749..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerImageProvider.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "LayerImageProvider.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerImageProvider.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerImageProvider.hpp deleted file mode 100644 index d9affbd1cf..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerImageProvider.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef LayerImageProvider_hpp -#define LayerImageProvider_hpp - -#include "Lottie/Public/ImageProvider/AnimationImageProvider.hpp" -#include "Lottie/Private/Model/Assets/ImageAsset.hpp" -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/ImageCompositionLayer.hpp" - -namespace lottie { - -/// Connects a LottieImageProvider to a group of image layers -class LayerImageProvider { -public: - LayerImageProvider(std::shared_ptr const &imageProvider, std::map> const &assets) : - _imageProvider(imageProvider), - _imageAssets(assets) { - reloadImages(); - } - - std::shared_ptr imageProvider() const { - return _imageProvider; - } - void setImageProvider(std::shared_ptr const &imageProvider) { - _imageProvider = imageProvider; - reloadImages(); - } - - std::vector> const &imageLayers() const { - return _imageLayers; - } - - void addImageLayers(std::vector> const &layers) { - for (const auto &layer : layers) { - auto it = _imageAssets.find(layer->imageReferenceID()); - if (it != _imageAssets.end()) { - _imageLayers.push_back(layer); - } - } - } - - void reloadImages() { - for (const auto &imageLayer : imageLayers()) { - auto it = _imageAssets.find(imageLayer->imageReferenceID()); - if (it != _imageAssets.end()) { - imageLayer->setImage(_imageProvider->imageForAsset(*it->second)); - } - } - } - -private: - std::shared_ptr _imageProvider; - std::vector> _imageLayers; - - std::map> _imageAssets; -}; - -} - -#endif /* LayerImageProvider_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerTextProvider.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerTextProvider.cpp deleted file mode 100644 index 22da907bd3..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerTextProvider.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "LayerTextProvider.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerTextProvider.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerTextProvider.hpp deleted file mode 100644 index 82c96ec8f3..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerTextProvider.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef LayerTextProvider_hpp -#define LayerTextProvider_hpp - -#include "Lottie/Public/TextProvider/AnimationTextProvider.hpp" -#include "Lottie/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.hpp" - -namespace lottie { - -/// Connects a LottieTextProvider to a group of text layers -class LayerTextProvider { -public: - LayerTextProvider(std::shared_ptr const &textProvider) { - _textProvider = textProvider; - reloadTexts(); - } - - std::shared_ptr const &textProvider() const { - return _textProvider; - } - void setTextProvider(std::shared_ptr const &textProvider) { - _textProvider = textProvider; - reloadTexts(); - } - - void addTextLayers(std::vector> const &layers) { - for (const auto &layer : layers) { - _textLayers.push_back(layer); - } - } - - void reloadTexts() { - for (const auto &layer : _textLayers) { - layer->setTextProvider(_textProvider); - } - } - -private: - std::vector> _textLayers; - - std::shared_ptr _textProvider; -}; - -} - -#endif /* LayerTextProvider_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerTransformNode.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerTransformNode.cpp deleted file mode 100644 index 8f751a571f..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerTransformNode.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "LayerTransformNode.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerTransformNode.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerTransformNode.hpp deleted file mode 100644 index 459558a2bd..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/LayerContainers/Utility/LayerTransformNode.hpp +++ /dev/null @@ -1,205 +0,0 @@ -#ifndef LayerTransformNode_hpp -#define LayerTransformNode_hpp - -#include "Lottie/Private/Model/Objects/Transform.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/NodeProperty.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/Protocols/AnimatorNode.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/Protocols/NodeOutput.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/PassThroughOutputNode.hpp" - -namespace lottie { - -class LayerTransformProperties: public KeypathSearchableNodePropertyMap { -public: - LayerTransformProperties(std::shared_ptr transform) { - _anchor = std::make_shared>(std::make_shared>(transform->anchorPoint().keyframes)); - _scale = std::make_shared>(std::make_shared>(transform->scale().keyframes)); - _rotation = std::make_shared>(std::make_shared>(transform->rotation().keyframes)); - _opacity = std::make_shared>(std::make_shared>(transform->opacity().keyframes)); - - std::map> propertyMap; - _keypathProperties.insert(std::make_pair("Anchor Point", _anchor)); - _keypathProperties.insert(std::make_pair("Scale", _scale)); - _keypathProperties.insert(std::make_pair("Rotation", _rotation)); - _keypathProperties.insert(std::make_pair("Opacity", _opacity)); - - if (transform->positionX().has_value() && transform->positionY().has_value()) { - auto xPosition = std::make_shared>(std::make_shared>(transform->positionX()->keyframes)); - auto yPosition = std::make_shared>(std::make_shared>(transform->positionY()->keyframes)); - _keypathProperties.insert(std::make_pair("X Position", xPosition)); - _keypathProperties.insert(std::make_pair("Y Position", yPosition)); - - _positionX = xPosition; - _positionY = yPosition; - _position = nullptr; - } else if (transform->position().has_value()) { - auto position = std::make_shared>(std::make_shared>(transform->position()->keyframes)); - _keypathProperties.insert(std::make_pair("Position", position)); - - _position = position; - _positionX = nullptr; - _positionY = nullptr; - } else { - _position = nullptr; - _positionX = nullptr; - _positionY = nullptr; - } - - for (const auto &it : _keypathProperties) { - _properties.push_back(it.second); - } - } - - virtual ~LayerTransformProperties() = default; - - virtual std::vector> &properties() override { - return _properties; - } - - virtual std::vector> const &childKeypaths() const override { - return _childKeypaths; - } - - virtual std::string keypathName() const override { - return "Transform"; - } - - virtual std::map> keypathProperties() const override { - return _keypathProperties; - } - - virtual std::shared_ptr keypathLayer() const override { - return nullptr; - } - - std::shared_ptr> const &anchor() { - return _anchor; - } - - std::shared_ptr> const &scale() { - return _scale; - } - - std::shared_ptr> const &rotation() { - return _rotation; - } - - std::shared_ptr> const &position() { - return _position; - } - - std::shared_ptr> const &positionX() { - return _positionX; - } - - std::shared_ptr> const &positionY() { - return _positionY; - } - - std::shared_ptr> const &opacity() { - return _opacity; - } - -private: - std::map> _keypathProperties; - std::vector> _childKeypaths; - - std::vector> _properties; - - std::shared_ptr> _anchor; - std::shared_ptr> _scale; - std::shared_ptr> _rotation; - std::shared_ptr> _position; - std::shared_ptr> _positionX; - std::shared_ptr> _positionY; - std::shared_ptr> _opacity; -}; - -class LayerTransformNode: public AnimatorNode { -public: - LayerTransformNode(std::shared_ptr transform) : - AnimatorNode(nullptr), - _transformProperties(std::make_shared(transform)) { - _outputNode = std::make_shared(nullptr); - } - - virtual ~LayerTransformNode() = default; - - virtual std::shared_ptr outputNode() override { - return _outputNode; - } - - virtual std::shared_ptr propertyMap() const override { - return _transformProperties; - } - - virtual bool shouldRebuildOutputs(float frame) override { - return hasLocalUpdates() || hasUpstreamUpdates(); - } - - virtual void rebuildOutputs(float frame) override { - _opacity = ((float)_transformProperties->opacity()->value().value) * 0.01f; - - Vector2D position(0.0, 0.0); - if (_transformProperties->position()) { - auto position3d = _transformProperties->position()->value(); - position.x = position3d.x; - position.y = position3d.y; - } else if (_transformProperties->positionX() && _transformProperties->positionY()) { - position = Vector2D( - _transformProperties->positionX()->value().value, - _transformProperties->positionY()->value().value - ); - } - - Vector3D anchor = _transformProperties->anchor()->value(); - Vector3D scale = _transformProperties->scale()->value(); - _localTransform = Transform2D::makeTransform( - Vector2D(anchor.x, anchor.y), - position, - Vector2D(scale.x, scale.y), - _transformProperties->rotation()->value().value, - std::nullopt, - std::nullopt - ); - - if (parentNode() && parentNode()->asLayerTransformNode()) { - _globalTransform = _localTransform * parentNode()->asLayerTransformNode()->_globalTransform; - } else { - _globalTransform = _localTransform; - } - } - - std::shared_ptr const &transformProperties() { - return _transformProperties; - } - - float opacity() { - return _opacity; - } - - Transform2D const &globalTransform() { - return _globalTransform; - } - -private: - std::shared_ptr _outputNode; - - std::shared_ptr _transformProperties; - - float _opacity = 1.0; - Transform2D _localTransform = Transform2D::identity(); - Transform2D _globalTransform = Transform2D::identity(); - -public: - virtual LayerTransformNode *asLayerTransformNode() override { - return this; - } -}; - -} - -#endif /* LayerTransformNode_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/NodeProperty.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/NodeProperty.cpp deleted file mode 100644 index eb9e3a5837..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/NodeProperty.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "NodeProperty.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/NodeProperty.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/NodeProperty.hpp deleted file mode 100644 index f77cdc470b..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/NodeProperty.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef NodeProperty_hpp -#define NodeProperty_hpp - -#include "Lottie/Public/Primitives/AnyValue.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyNodeProperty.hpp" -#include "Lottie/Public/DynamicProperties/AnyValueProvider.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueContainer.hpp" - -namespace lottie { - -/// A node property that holds a reference to a T ValueProvider and a T ValueContainer. -template -class NodeProperty: public AnyNodeProperty { -public: - NodeProperty(std::shared_ptr> provider) : - _typedContainer(provider->value(0.0)), - _valueProvider(provider) { - _typedContainer.setNeedsUpdate(); - } - -public: - virtual AnyValue::Type valueType() const override { - return AnyValueType::type(); - } - - virtual T value() { - return _typedContainer.outputValue(); - } - - virtual bool needsUpdate(float frame) const override { - return _typedContainer.needsUpdate() || _valueProvider->hasUpdate(frame); - } - - virtual void setProvider(std::shared_ptr provider) override { - /*if (provider->valueType() != valueType()) { - return; - } - _valueProvider = provider; - _typedContainer.setNeedsUpdate();*/ - } - - virtual void update(float frame) override { - _typedContainer.setValue(_valueProvider->value(frame), frame); - } - -private: - ValueContainer _typedContainer; - std::shared_ptr> _valueProvider; - //std::shared_ptr _originalValueProvider; -}; - -} - -#endif /* NodeProperty_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyNodeProperty.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyNodeProperty.cpp deleted file mode 100644 index 8609641d49..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyNodeProperty.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "AnyNodeProperty.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyNodeProperty.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyNodeProperty.hpp deleted file mode 100644 index ec682ceb93..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyNodeProperty.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef AnyNodeProperty_hpp -#define AnyNodeProperty_hpp - -#include "Lottie/Public/Primitives/AnyValue.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyValueContainer.hpp" -#include "Lottie/Public/DynamicProperties/AnyValueProvider.hpp" - -#include - -namespace lottie { - -/// A property of a node. The node property holds a provider and a container -class AnyNodeProperty { -public: - virtual ~AnyNodeProperty() = default; - -public: - /// Returns true if the property needs to recompute its stored value - virtual bool needsUpdate(float frame) const = 0; - - /// Updates the property for the frame - virtual void update(float frame) = 0; - - /// The Type of the value provider - virtual AnyValue::Type valueType() const = 0; - - /// Sets the value provider for the property. - virtual void setProvider(std::shared_ptr provider) = 0; -}; - -} - -#endif /* AnyNodeProperty_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyValueContainer.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyValueContainer.cpp deleted file mode 100644 index b186f2e2f4..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyValueContainer.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "AnyValueContainer.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyValueContainer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyValueContainer.hpp deleted file mode 100644 index 1776bd13bc..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyValueContainer.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef AnyValueContainer_hpp -#define AnyValueContainer_hpp - -#include "Lottie/Public/Primitives/AnyValue.hpp" - -namespace lottie { - -class AnyValueContainer { -public: - /// The stored value of the container - virtual AnyValue value() const = 0; - - /// Notifies the provider that it should update its container - virtual void setNeedsUpdate() = 0; - - /// When true the container needs to have its value updated by its provider - virtual bool needsUpdate() const = 0; - - /// The frame time of the last provided update - virtual float lastUpdateFrame() const = 0; -}; - -} - -#endif /* AnyValueContainer_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/HasRenderUpdates.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/HasRenderUpdates.hpp deleted file mode 100644 index bc6a13261e..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/HasRenderUpdates.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef HasRenderUpdates_hpp -#define HasRenderUpdates_hpp - -namespace lottie { - -class HasRenderUpdates { -public: - virtual bool hasRenderUpdates(float forFrame) = 0; -}; - -} - -#endif /* HasRenderUpdates_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/HasUpdate.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/HasUpdate.hpp deleted file mode 100644 index f0c35b0530..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/HasUpdate.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef HasUpdate_hpp -#define HasUpdate_hpp - -namespace lottie { - -class HasUpdate { -public: - /// The last frame in which this node was updated. - virtual bool hasUpdate() = 0; -}; - -} - -#endif /* HasUpdate_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.cpp deleted file mode 100644 index 62c08facba..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "KeypathSearchable.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.hpp deleted file mode 100644 index 4586c7ddc2..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef KeypathSearchable_hpp -#define KeypathSearchable_hpp - -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyNodeProperty.hpp" -#include "Lottie/Public/Primitives/CALayer.hpp" - -#include -#include -#include -#include - -namespace lottie { - -class KeypathSearchable; - -class HasChildKeypaths { -public: - /// Children Keypaths - virtual std::vector> const &childKeypaths() const = 0; -}; - -/// Protocol that provides keypath search functionality. Returns all node properties associated with a keypath. -class KeypathSearchable: virtual public HasChildKeypaths { -public: - /// The name of the Keypath - virtual std::string keypathName() const = 0; - - /// A list of properties belonging to the keypath. - virtual std::map> keypathProperties() const = 0; - - virtual std::shared_ptr keypathLayer() const = 0; -}; - -} - -#endif /* KeypathSearchable_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.cpp deleted file mode 100644 index 100edba8df..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "NodePropertyMap.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.hpp deleted file mode 100644 index 0879d00c82..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef NodePropertyMap_hpp -#define NodePropertyMap_hpp - -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyNodeProperty.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.hpp" -#include "Lottie/Public/Primitives/CALayer.hpp" - -#include - -namespace lottie { - -class NodePropertyMap: virtual public HasChildKeypaths { -public: - virtual std::vector> &properties() = 0; - - bool needsLocalUpdate(float frame) { - for (auto &property : properties()) { - if (property->needsUpdate(frame)) { - return true; - } - } - return false; - } - - void updateNodeProperties(float frame) { - for (auto &property : properties()) { - property->update(frame); - } - } -}; - -class KeypathSearchableNodePropertyMap: virtual public NodePropertyMap, virtual public KeypathSearchable { -public: - virtual std::shared_ptr keypathLayer() const override { - return nullptr; - } -}; - -} - -#endif /* NodePropertyMap_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueContainer.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueContainer.cpp deleted file mode 100644 index 2ead9de1ed..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueContainer.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "ValueContainer.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueContainer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueContainer.hpp deleted file mode 100644 index 563de16de5..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueContainer.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef ValueContainer_hpp -#define ValueContainer_hpp - -#include "Lottie/Public/Primitives/AnyValue.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyValueContainer.hpp" - -namespace lottie { - -/// A container for a node value that is Typed to T. -template -class ValueContainer: public AnyValueContainer { -public: - ValueContainer(T value) : - _outputValue(value) { - } - -public: - float _lastUpdateFrame = std::numeric_limits::infinity(); - bool _needsUpdate = true; - - virtual AnyValue value() const override { - return AnyValue(_outputValue); - } - - virtual bool needsUpdate() const override { - return _needsUpdate; - } - - virtual float lastUpdateFrame() const override { - return _lastUpdateFrame; - } - - T _outputValue; - - T outputValue() { - return _outputValue; - } - void setOutputValue(T value) { - _outputValue = value; - _needsUpdate = false; - } - - void setValue(AnyValue value, float forFrame) { - if (value.type() == AnyValueType::type()) { - _needsUpdate = false; - _lastUpdateFrame = forFrame; - _outputValue = value.get(); - } - } - - virtual void setNeedsUpdate() override { - _needsUpdate = true; - } -}; - -} - -#endif /* ValueContainer_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/DashPatternInterpolator.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/DashPatternInterpolator.cpp deleted file mode 100644 index b3f91f556b..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/DashPatternInterpolator.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "DashPatternInterpolator.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/DashPatternInterpolator.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/DashPatternInterpolator.hpp deleted file mode 100644 index 5e744386dd..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/DashPatternInterpolator.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef DashPatternInterpolator_hpp -#define DashPatternInterpolator_hpp - -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.hpp" -#include "Lottie/Public/Primitives/DashPattern.hpp" - -namespace lottie { - -/// A value provider that produces an array of values from an array of Keyframe Interpolators -class DashPatternInterpolator: public ValueProvider, public std::enable_shared_from_this { -public: - /// Initialize with an array of array of keyframes. - DashPatternInterpolator(std::vector>> const &keyframeGroups) { - for (const auto &keyframeGroup : keyframeGroups) { - _keyframeInterpolators.push_back(std::make_shared>(keyframeGroup)); - } - } - - virtual ~DashPatternInterpolator() = default; - - virtual AnyValue::Type valueType() const override { - return AnyValueType::type(); - } - - virtual DashPattern value(AnimationFrameTime frame) override { - std::vector values; - for (const auto &interpolator : _keyframeInterpolators) { - values.push_back(interpolator->value(frame).value); - } - return DashPattern(std::move(values)); - } - - virtual bool hasUpdate(float frame) const override { - for (const auto &interpolator : _keyframeInterpolators) { - if (interpolator->hasUpdate(frame)) { - return true; - } - } - return false; - } - -private: - std::vector>> _keyframeInterpolators; -}; - -} - -#endif /* DashPatternInterpolator_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.cpp deleted file mode 100644 index 8ec2364762..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "KeyframeInterpolator.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.hpp deleted file mode 100644 index de35d4887a..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.hpp +++ /dev/null @@ -1,452 +0,0 @@ -#ifndef KeyframeInterpolator_hpp -#define KeyframeInterpolator_hpp - -#include "Lottie/Public/DynamicProperties/AnyValueProvider.hpp" - -namespace lottie { - -/// A value provider that produces a value at Time from a group of keyframes -template -class KeyframeInterpolator: public ValueProvider, public std::enable_shared_from_this> { -public: - KeyframeInterpolator(std::vector> const &keyframes_) : - keyframes(keyframes_) { - assert(!keyframes.empty()); - } - - virtual ~KeyframeInterpolator() { - } - -public: - std::vector> keyframes; - - virtual AnyValue::Type valueType() const override { - return AnyValueType::type(); - } - - virtual T value(AnimationFrameTime frame) override { - // First set the keyframe span for the frame. - updateSpanIndices(frame); - lastUpdatedFrame = frame; - // If only one keyframe return its value - - if (leadingKeyframe.has_value() && - trailingKeyframe.has_value()) - { - /// We have leading and trailing keyframe. - auto progress = leadingKeyframe->interpolatedProgress(trailingKeyframe.value(), frame); - return leadingKeyframe->interpolate(trailingKeyframe.value(), progress); - } else if (leadingKeyframe.has_value()) { - return leadingKeyframe->value; - } else if (trailingKeyframe.has_value()) { - return trailingKeyframe->value; - } else { - /// Satisfy the compiler. - return keyframes[0].value; - } - } - - /// Returns true to trigger a frame update for this interpolator. - /// - /// An interpolator will be asked if it needs to update every frame. - /// If the interpolator needs updating it will be asked to compute its value for - /// the given frame. - /// - /// Cases a keyframe should not be updated: - /// - If time is in span and leading keyframe is hold - /// - If time is after the last keyframe. - /// - If time is before the first keyframe - /// - /// Cases for updating a keyframe: - /// - If time is in the span, and is not a hold - /// - If time is outside of the span, and there are more keyframes - /// - If a value delegate is set - /// - If leading and trailing are both nil. - virtual bool hasUpdate(float frame) const override { - if (!lastUpdatedFrame.has_value()) { - return true; - } - - if (leadingKeyframe.has_value() && - !trailingKeyframe.has_value() && - leadingKeyframe->time < frame) - { - /// Frame is after bounds of keyframes - return false; - } - if (trailingKeyframe.has_value() && - !leadingKeyframe.has_value() && - frame < trailingKeyframe->time) - { - /// Frame is before bounds of keyframes - return false; - } - if (leadingKeyframe.has_value() && - trailingKeyframe.has_value() && - leadingKeyframe->isHold && - leadingKeyframe->time < frame && - frame < trailingKeyframe->time) - { - return false; - } - return true; - } - - // MARK: Fileprivate - - std::optional lastUpdatedFrame; - - std::optional leadingIndex; - std::optional trailingIndex; - std::optional> leadingKeyframe; - std::optional> trailingKeyframe; - - /// Finds the appropriate Leading and Trailing keyframe index for the given time. - void updateSpanIndices(float frame) { - if (keyframes.empty()) { - leadingIndex = std::nullopt; - trailingIndex = std::nullopt; - leadingKeyframe = std::nullopt; - trailingKeyframe = std::nullopt; - return; - } - - // This function searches through the array to find the span of two keyframes - // that contain the current time. - // - // We could use Array.first(where:) but that would search through the entire array - // each frame. - // Instead we track the last used index and search either forwards or - // backwards from there. This reduces the iterations and complexity from - // - // O(n), where n is the length of the sequence to - // O(n), where n is the number of items after or before the last used index. - // - - if (keyframes.size() == 1) { - /// Only one keyframe. Set it as first and move on. - leadingIndex = 0; - trailingIndex = std::nullopt; - leadingKeyframe = keyframes[0]; - trailingKeyframe = std::nullopt; - return; - } - - /// Sets the initial keyframes. This is often only needed for the first check. - if - (!leadingIndex.has_value() && - !trailingIndex.has_value()) - { - if (frame < keyframes[0].time) { - /// Time is before the first keyframe. Set it as the trailing. - trailingIndex = 0; - } else { - /// Time is after the first keyframe. Set the keyframe and the trailing. - leadingIndex = 0; - trailingIndex = 1; - } - } - - if - (trailingIndex.has_value() && - keyframes[trailingIndex.value()].time <= frame) - { - /// Time is after the current span. Iterate forward. - auto newLeading = trailingIndex.value(); - bool keyframeFound = false; - while (!keyframeFound) { - leadingIndex = newLeading; - if (newLeading + 1 >= 0 && newLeading + 1 < keyframes.size()) { - trailingIndex = newLeading + 1; - } else { - trailingIndex = std::nullopt; - } - - if (!trailingIndex.has_value()) { - /// We have reached the end of our keyframes. Time is after the last keyframe. - keyframeFound = true; - continue; - } - - if (frame < keyframes[trailingIndex.value()].time) { - /// Keyframe in current span. - keyframeFound = true; - continue; - } - /// Advance the array. - newLeading = trailingIndex.value(); - } - - } else if - (leadingIndex.has_value() && - frame < keyframes[leadingIndex.value()].time) - { - - /// Time is before the current span. Iterate backwards - auto newTrailing = leadingIndex.value(); - - bool keyframeFound = false; - while (!keyframeFound) { - if (newTrailing - 1 >= 0 && newTrailing - 1 < keyframes.size()) { - leadingIndex = newTrailing - 1; - } else { - leadingIndex = std::nullopt; - } - trailingIndex = newTrailing; - - if (!leadingIndex.has_value()) { - /// We have reached the end of our keyframes. Time is after the last keyframe. - keyframeFound = true; - continue; - } - if (keyframes[leadingIndex.value()].time <= frame) { - /// Keyframe in current span. - keyframeFound = true; - continue; - } - /// Step back - newTrailing = leadingIndex.value(); - } - } - if (const auto keyFrame = leadingIndex) { - leadingKeyframe = keyframes[keyFrame.value()]; - } else { - leadingKeyframe = std::nullopt; - } - - if (const auto keyFrame = trailingIndex) { - trailingKeyframe = keyframes[keyFrame.value()]; - } else { - trailingKeyframe = std::nullopt; - } - } -}; - -class BezierPathKeyframeInterpolator { -public: - BezierPathKeyframeInterpolator(std::vector> const &keyframes_) : - keyframes(keyframes_) { - assert(!keyframes.empty()); - } - -public: - std::vector> keyframes; - - void update(AnimationFrameTime frame, BezierPath &outPath) { - // First set the keyframe span for the frame. - updateSpanIndices(frame); - lastUpdatedFrame = frame; - // If only one keyframe return its value - - if (leadingKeyframe.has_value() && - trailingKeyframe.has_value()) - { - /// We have leading and trailing keyframe. - auto progress = leadingKeyframe->interpolatedProgress(trailingKeyframe.value(), frame); - interpolateInplace(leadingKeyframe.value(), trailingKeyframe.value(), progress, outPath); - } else if (leadingKeyframe.has_value()) { - setInplace(leadingKeyframe.value(), outPath); - } else if (trailingKeyframe.has_value()) { - setInplace(trailingKeyframe.value(), outPath); - } else { - /// Satisfy the compiler. - setInplace(keyframes[0], outPath); - } - } - - /// Returns true to trigger a frame update for this interpolator. - /// - /// An interpolator will be asked if it needs to update every frame. - /// If the interpolator needs updating it will be asked to compute its value for - /// the given frame. - /// - /// Cases a keyframe should not be updated: - /// - If time is in span and leading keyframe is hold - /// - If time is after the last keyframe. - /// - If time is before the first keyframe - /// - /// Cases for updating a keyframe: - /// - If time is in the span, and is not a hold - /// - If time is outside of the span, and there are more keyframes - /// - If a value delegate is set - /// - If leading and trailing are both nil. - bool hasUpdate(float frame) const { - if (!lastUpdatedFrame.has_value()) { - return true; - } - - if (leadingKeyframe.has_value() && - !trailingKeyframe.has_value() && - leadingKeyframe->time < frame) - { - /// Frame is after bounds of keyframes - return false; - } - if (trailingKeyframe.has_value() && - !leadingKeyframe.has_value() && - frame < trailingKeyframe->time) - { - /// Frame is before bounds of keyframes - return false; - } - if (leadingKeyframe.has_value() && - trailingKeyframe.has_value() && - leadingKeyframe->isHold && - leadingKeyframe->time < frame && - frame < trailingKeyframe->time) - { - return false; - } - return true; - } - - // MARK: Fileprivate - - std::optional lastUpdatedFrame; - - std::optional leadingIndex; - std::optional trailingIndex; - std::optional> leadingKeyframe; - std::optional> trailingKeyframe; - - /// Finds the appropriate Leading and Trailing keyframe index for the given time. - void updateSpanIndices(float frame) { - if (keyframes.empty()) { - leadingIndex = std::nullopt; - trailingIndex = std::nullopt; - leadingKeyframe = std::nullopt; - trailingKeyframe = std::nullopt; - return; - } - - // This function searches through the array to find the span of two keyframes - // that contain the current time. - // - // We could use Array.first(where:) but that would search through the entire array - // each frame. - // Instead we track the last used index and search either forwards or - // backwards from there. This reduces the iterations and complexity from - // - // O(n), where n is the length of the sequence to - // O(n), where n is the number of items after or before the last used index. - // - - if (keyframes.size() == 1) { - /// Only one keyframe. Set it as first and move on. - leadingIndex = 0; - trailingIndex = std::nullopt; - leadingKeyframe = keyframes[0]; - trailingKeyframe = std::nullopt; - return; - } - - /// Sets the initial keyframes. This is often only needed for the first check. - if - (!leadingIndex.has_value() && - !trailingIndex.has_value()) - { - if (frame < keyframes[0].time) { - /// Time is before the first keyframe. Set it as the trailing. - trailingIndex = 0; - } else { - /// Time is after the first keyframe. Set the keyframe and the trailing. - leadingIndex = 0; - trailingIndex = 1; - } - } - - if - (trailingIndex.has_value() && - keyframes[trailingIndex.value()].time <= frame) - { - /// Time is after the current span. Iterate forward. - auto newLeading = trailingIndex.value(); - bool keyframeFound = false; - while (!keyframeFound) { - leadingIndex = newLeading; - if (newLeading + 1 >= 0 && newLeading + 1 < keyframes.size()) { - trailingIndex = newLeading + 1; - } else { - trailingIndex = std::nullopt; - } - - if (!trailingIndex.has_value()) { - /// We have reached the end of our keyframes. Time is after the last keyframe. - keyframeFound = true; - continue; - } - - if (frame < keyframes[trailingIndex.value()].time) { - /// Keyframe in current span. - keyframeFound = true; - continue; - } - /// Advance the array. - newLeading = trailingIndex.value(); - } - - } else if - (leadingIndex.has_value() && - frame < keyframes[leadingIndex.value()].time) - { - - /// Time is before the current span. Iterate backwards - auto newTrailing = leadingIndex.value(); - - bool keyframeFound = false; - while (!keyframeFound) { - if (newTrailing - 1 >= 0 && newTrailing - 1 < keyframes.size()) { - leadingIndex = newTrailing - 1; - } else { - leadingIndex = std::nullopt; - } - trailingIndex = newTrailing; - - if (!leadingIndex.has_value()) { - /// We have reached the end of our keyframes. Time is after the last keyframe. - keyframeFound = true; - continue; - } - if (keyframes[leadingIndex.value()].time <= frame) { - /// Keyframe in current span. - keyframeFound = true; - continue; - } - /// Step back - newTrailing = leadingIndex.value(); - } - } - if (const auto keyFrame = leadingIndex) { - leadingKeyframe = keyframes[keyFrame.value()]; - } else { - leadingKeyframe = std::nullopt; - } - - if (const auto keyFrame = trailingIndex) { - trailingKeyframe = keyframes[keyFrame.value()]; - } else { - trailingKeyframe = std::nullopt; - } - } - -private: - void setInplace(Keyframe const &from, BezierPath &outPath) { - ValueInterpolator::setInplace(from.value, outPath); - } - - void interpolateInplace(Keyframe const &from, Keyframe const &to, float progress, BezierPath &outPath) { - std::optional spatialOutTangent2d; - if (from.spatialOutTangent) { - spatialOutTangent2d = Vector2D(from.spatialOutTangent->x, from.spatialOutTangent->y); - } - std::optional spatialInTangent2d; - if (to.spatialInTangent) { - spatialInTangent2d = Vector2D(to.spatialInTangent->x, to.spatialInTangent->y); - } - ValueInterpolator::interpolateInplace(from.value, to.value, progress, spatialOutTangent2d, spatialInTangent2d, outPath); - } -}; - -} - -#endif /* KeyframeInterpolator_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/SingleValueProvider.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/SingleValueProvider.cpp deleted file mode 100644 index face321499..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/SingleValueProvider.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "SingleValueProvider.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/SingleValueProvider.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/SingleValueProvider.hpp deleted file mode 100644 index b6c3fe6a1f..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/SingleValueProvider.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef SingleValueProvider_hpp -#define SingleValueProvider_hpp - -#include "Lottie/Public/DynamicProperties/AnyValueProvider.hpp" - -namespace lottie { - -/// Returns a value for every frame. -template -class SingleValueProvider: public ValueProvider { -public: - SingleValueProvider(T const &value) : - _value(value) { - } - - virtual ~SingleValueProvider() = default; - - void setValue(T const &value) { - _value = value; - _hasUpdate = true; - } - - virtual T value(AnimationFrameTime frame) override { - return _value; - } - - virtual AnyValue::Type valueType() const override { - return AnyValueType::type(); - } - - virtual bool hasUpdate(float frame) const override { - return _hasUpdate; - } - -private: - T _value; - bool _hasUpdate = true; -}; - -} - -#endif /* SingleValueProvider_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/PassThroughOutputNode.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/PassThroughOutputNode.hpp deleted file mode 100644 index f7b73a550d..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/PassThroughOutputNode.hpp +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef PassThroughOutputNode_hpp -#define PassThroughOutputNode_hpp - -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/HasRenderUpdates.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/HasUpdate.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/Protocols/NodeOutput.hpp" - -namespace lottie { - -class PassThroughOutputNode: virtual public NodeOutput, virtual public HasRenderUpdates, virtual public HasUpdate { -public: - PassThroughOutputNode(std::shared_ptr parent) : - _parent(parent) { - } - - virtual ~PassThroughOutputNode() = default; - - virtual std::shared_ptr parent() override { - return _parent; - } - - virtual bool isEnabled() const override { - return _isEnabled; - } - virtual void setIsEnabled(bool isEnabled) override { - _isEnabled = isEnabled; - } - - virtual bool hasUpdate() override { - return _hasUpdate; - } - void setHasUpdate(bool hasUpdate) { - _hasUpdate = hasUpdate; - } - - virtual std::shared_ptr outputPath() override { - if (_parent) { - return _parent->outputPath(); - } - return nullptr; - } - - virtual bool hasOutputUpdates(float forFrame) override { - /// Changes to this node do not affect downstream nodes. - bool parentUpdate = false; - if (_parent) { - parentUpdate = _parent->hasOutputUpdates(forFrame); - } - /// Changes to upstream nodes do, however, affect this nodes state. - _hasUpdate = _hasUpdate || parentUpdate; - return parentUpdate; - } - - virtual bool hasRenderUpdates(float forFrame) override { - /// Return true if there are upstream updates or if this node has updates - bool upstreamUpdates = false; - if (_parent) { - upstreamUpdates = _parent->hasOutputUpdates(forFrame); - } - _hasUpdate = _hasUpdate || upstreamUpdates; - return _hasUpdate; - } - -private: - std::shared_ptr _parent; - bool _hasUpdate = false; - bool _isEnabled = true; -}; - -} - -#endif /* PassThroughOutputNode_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.hpp deleted file mode 100644 index 731a81149c..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef StrokeNode_hpp -#define StrokeNode_hpp - -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.hpp" -#include "Lottie/Private/Model/ShapeItems/Stroke.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/NodeProperty.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/SingleValueProvider.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/Protocols/AnimatorNode.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/Protocols/RenderNode.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/DashPatternInterpolator.hpp" - -namespace lottie { - -class StrokeShapeDashConfiguration { -public: - StrokeShapeDashConfiguration(std::vector const &elements) { - /// Converts the `[DashElement]` data model into `lineDashPattern` and `lineDashPhase` - /// representations usable in a `CAShapeLayer` - for (const auto &dash : elements) { - if (dash.type == DashElementType::Offset) { - dashPhase = dash.value.keyframes; - } else { - dashPatterns.push_back(dash.value.keyframes); - } - } - } - -public: - std::vector>> dashPatterns; - std::vector> dashPhase; -}; - -} - -#endif /* StrokeNode_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Nodes/Text/TextAnimatorNode.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Nodes/Text/TextAnimatorNode.hpp deleted file mode 100644 index 6e8b534b48..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Nodes/Text/TextAnimatorNode.hpp +++ /dev/null @@ -1,367 +0,0 @@ -#ifndef TextAnimatorNode_hpp -#define TextAnimatorNode_hpp - -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.hpp" -#include "Lottie/Private/Model/Text/TextAnimator.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/NodeProperty.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/Protocols/NodeOutput.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/Protocols/AnimatorNode.hpp" - -namespace lottie { - -class TextAnimatorNodeProperties: public KeypathSearchableNodePropertyMap { -public: - TextAnimatorNodeProperties(std::shared_ptr const &textAnimator) { - _keypathName = textAnimator->name.value_or(""); - - if (textAnimator->anchor) { - _anchor = std::make_shared>(std::make_shared>(textAnimator->anchor->keyframes)); - _keypathProperties.insert(std::make_pair("Anchor", _anchor)); - } - - if (textAnimator->position) { - _position = std::make_shared>(std::make_shared>(textAnimator->position->keyframes)); - _keypathProperties.insert(std::make_pair("Position", _position)); - } - - if (textAnimator->scale) { - _scale = std::make_shared>(std::make_shared>(textAnimator->scale->keyframes)); - _keypathProperties.insert(std::make_pair("Scale", _scale)); - } - - if (textAnimator->skew) { - _skew = std::make_shared>(std::make_shared>(textAnimator->skew->keyframes)); - _keypathProperties.insert(std::make_pair("Skew", _skew)); - } - - if (textAnimator->skewAxis) { - _skewAxis = std::make_shared>(std::make_shared>(textAnimator->skewAxis->keyframes)); - _keypathProperties.insert(std::make_pair("Skew Axis", _skewAxis)); - } - - if (textAnimator->rotation) { - _rotation = std::make_shared>(std::make_shared>(textAnimator->rotation->keyframes)); - _keypathProperties.insert(std::make_pair("Rotation", _rotation)); - } - - if (textAnimator->rotation) { - _opacity = std::make_shared>(std::make_shared>(textAnimator->opacity->keyframes)); - _keypathProperties.insert(std::make_pair("Opacity", _opacity)); - } - - if (textAnimator->strokeColor) { - _strokeColor = std::make_shared>(std::make_shared>(textAnimator->strokeColor->keyframes)); - _keypathProperties.insert(std::make_pair("Stroke Color", _strokeColor)); - } - - if (textAnimator->fillColor) { - _fillColor = std::make_shared>(std::make_shared>(textAnimator->fillColor->keyframes)); - _keypathProperties.insert(std::make_pair("Fill Color", _fillColor)); - } - - if (textAnimator->strokeWidth) { - _strokeWidth = std::make_shared>(std::make_shared>(textAnimator->strokeWidth->keyframes)); - _keypathProperties.insert(std::make_pair("Stroke Width", _strokeWidth)); - } - - if (textAnimator->tracking) { - _tracking = std::make_shared>(std::make_shared>(textAnimator->tracking->keyframes)); - _keypathProperties.insert(std::make_pair("Tracking", _tracking)); - } - - for (const auto &it : _keypathProperties) { - _properties.push_back(it.second); - } - } - - virtual ~TextAnimatorNodeProperties() = default; - - virtual std::string keypathName() const override { - return _keypathName; - } - - virtual std::map> keypathProperties() const override { - return _keypathProperties; - } - - virtual std::vector> &properties() override { - return _properties; - } - - virtual std::vector> const &childKeypaths() const override { - return _childKeypaths; - } - - Transform2D caTransform() { - Vector2D anchor = Vector2D::Zero(); - if (_anchor) { - auto anchor3d = _anchor->value(); - anchor = Vector2D(anchor3d.x, anchor3d.y); - } - - Vector2D position = Vector2D::Zero(); - if (_position) { - auto position3d = _position->value(); - position = Vector2D(position3d.x, position3d.y); - } - - Vector2D scale = Vector2D(100.0, 100.0); - if (_scale) { - auto scale3d = _scale->value(); - scale = Vector2D(scale3d.x, scale3d.y); - } - - float rotation = 0.0; - if (_rotation) { - rotation = _rotation->value().value; - } - - std::optional skew; - if (_skew) { - skew = _skew->value().value; - } - std::optional skewAxis; - if (_skewAxis) { - skewAxis = _skewAxis->value().value; - } - - return Transform2D::makeTransform( - anchor, - position, - scale, - rotation, - skew, - skewAxis - ); - } - - virtual std::shared_ptr keypathLayer() const override { - return nullptr; - } - - float opacity() { - if (_opacity) { - return _opacity->value().value; - } else { - return 100.0; - } - } - - std::optional strokeColor() { - if (_strokeColor) { - return _strokeColor->value(); - } else { - return std::nullopt; - } - } - - std::optional fillColor() { - if (_fillColor) { - return _fillColor->value(); - } else { - return std::nullopt; - } - } - - float tracking() { - if (_tracking) { - return _tracking->value().value; - } else { - return 1.0; - } - } - - float strokeWidth() { - if (_strokeWidth) { - return _strokeWidth->value().value; - } else { - return 0.0; - } - } - -private: - std::string _keypathName; - - std::shared_ptr> _anchor; - std::shared_ptr> _position; - std::shared_ptr> _scale; - std::shared_ptr> _skew; - std::shared_ptr> _skewAxis; - std::shared_ptr> _rotation; - std::shared_ptr> _opacity; - std::shared_ptr> _strokeColor; - std::shared_ptr> _fillColor; - std::shared_ptr> _strokeWidth; - std::shared_ptr> _tracking; - - std::map> _keypathProperties; - std::vector> _childKeypaths; - std::vector> _properties; -}; - -class TextOutputNode: virtual public NodeOutput { -public: - TextOutputNode(std::shared_ptr parent) : - _parentTextNode(parent) { - } - - virtual ~TextOutputNode() = default; - - virtual std::shared_ptr parent() override { - return _parentTextNode; - } - - Transform2D xform() { - if (_xform.has_value()) { - return _xform.value(); - } else if (_parentTextNode) { - return _parentTextNode->xform(); - } else { - return Transform2D::identity(); - } - } - void setXform(Transform2D const &xform) { - _xform = xform; - } - - float opacity() { - if (_opacity.has_value()) { - return _opacity.value(); - } else if (_parentTextNode) { - return _parentTextNode->opacity(); - } else { - return 1.0; - } - } - void setOpacity(float opacity) { - _opacity = opacity; - } - - std::optional strokeColor() { - if (_strokeColor.has_value()) { - return _strokeColor.value(); - } else if (_parentTextNode) { - return _parentTextNode->strokeColor(); - } else { - return std::nullopt; - } - } - void setStrokeColor(std::optional strokeColor) { - _strokeColor = strokeColor; - } - - std::optional fillColor() { - if (_fillColor.has_value()) { - return _fillColor.value(); - } else if (_parentTextNode) { - return _parentTextNode->fillColor(); - } else { - return std::nullopt; - } - } - void setFillColor(std::optional fillColor) { - _fillColor = fillColor; - } - - float tracking() { - if (_tracking.has_value()) { - return _tracking.value(); - } else if (_parentTextNode) { - return _parentTextNode->tracking(); - } else { - return 0.0; - } - } - void setTracking(float tracking) { - _tracking = tracking; - } - - float strokeWidth() { - if (_strokeWidth.has_value()) { - return _strokeWidth.value(); - } else if (_parentTextNode) { - return _parentTextNode->strokeWidth(); - } else { - return 0.0; - } - } - void setStrokeWidth(float strokeWidth) { - _strokeWidth = strokeWidth; - } - - virtual bool hasOutputUpdates(float frame) override { - // TODO Fix This - return true; - } - - virtual std::shared_ptr outputPath() override { - return _outputPath; - } - - virtual bool isEnabled() const override { - return _isEnabled; - } - virtual void setIsEnabled(bool isEnabled) override { - _isEnabled = isEnabled; - } - -private: - std::shared_ptr _parentTextNode; - bool _isEnabled = true; - - std::shared_ptr _outputPath; - - std::optional _xform; - std::optional _opacity; - std::optional _strokeColor; - std::optional _fillColor; - std::optional _tracking; - std::optional _strokeWidth; -}; - -class TextAnimatorNode: public AnimatorNode { -public: - TextAnimatorNode(std::shared_ptr const &parentNode, std::shared_ptr const &textAnimator) : - AnimatorNode(parentNode) { - std::shared_ptr parentOutputNode; - if (parentNode) { - parentOutputNode = parentNode->_textOutputNode; - } - _textOutputNode = std::make_shared(parentOutputNode); - - _textAnimatorProperties = std::make_shared(textAnimator); - } - - virtual ~TextAnimatorNode() = default; - - virtual std::shared_ptr outputNode() override { - return _textOutputNode; - } - - virtual std::shared_ptr propertyMap() const override { - return _textAnimatorProperties; - } - - virtual bool localUpdatesPermeateDownstream() override { - return true; - } - - virtual void rebuildOutputs(float frame) override { - _textOutputNode->setXform(_textAnimatorProperties->caTransform()); - _textOutputNode->setOpacity(((float)_textAnimatorProperties->opacity()) * 0.01f); - _textOutputNode->setStrokeColor(_textAnimatorProperties->strokeColor()); - _textOutputNode->setFillColor(_textAnimatorProperties->fillColor()); - _textOutputNode->setTracking(_textAnimatorProperties->tracking()); - _textOutputNode->setStrokeWidth(_textAnimatorProperties->strokeWidth()); - } - -private: - std::shared_ptr _textOutputNode; - - std::shared_ptr _textAnimatorProperties; -}; - -} - -#endif /* TextAnimatorNode_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Protocols/AnimatorNode.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Protocols/AnimatorNode.hpp deleted file mode 100644 index 249c055665..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Protocols/AnimatorNode.hpp +++ /dev/null @@ -1,238 +0,0 @@ -#ifndef AnimatorNode_hpp -#define AnimatorNode_hpp - -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/Protocols/NodeOutput.hpp" - -#include -#include - -namespace lottie { - -class LayerTransformNode; -class PathNode; -class RenderNode; - -/// The Animator Node is the base node in the render system tree. -/// -/// It defines a single node that has an output path and option input node. -/// At animation time the root animation node is asked to update its contents for -/// the current frame. -/// The node reaches up its chain of nodes until the first node that does not need -/// updating is found. Then each node updates its contents down the render pipeline. -/// Each node adds its local path to its input path and passes it forward. -/// -/// An animator node holds a group of interpolators. These interpolators determine -/// if the node needs an update for the current frame. -/// -class AnimatorNode: public KeypathSearchable { -public: - AnimatorNode(std::shared_ptr const &parentNode) : - _parentNode(parentNode) { - } - - AnimatorNode(const AnimatorNode&) = delete; - AnimatorNode& operator=(AnimatorNode&) = delete; - - /// The available properties of the Node. - /// - /// These properties are automatically updated each frame. - /// These properties are also settable and gettable through the dynamic - /// property system. - /// - virtual std::shared_ptr propertyMap() const = 0; - - /// The upstream input node - std::shared_ptr parentNode() { - return _parentNode; - } - void setParentNode(std::shared_ptr const &parentNode) { - _parentNode = parentNode; - } - - /// The output of the node. - virtual std::shared_ptr outputNode() = 0; - - /// Update the outputs of the node. Called if local contents were update or if outputsNeedUpdate returns true. - virtual void rebuildOutputs(float frame) = 0; - - /// Setters for marking current node state. - bool isEnabled() { - return _isEnabled; - } - virtual void setIsEnabled(bool isEnabled) { - _isEnabled = isEnabled; - } - - bool hasLocalUpdates() { - return _hasLocalUpdates; - } - virtual void setHasLocalUpdates(bool hasLocalUpdates) { - _hasLocalUpdates = hasLocalUpdates; - } - - bool hasUpstreamUpdates() { - return _hasUpstreamUpdates; - } - virtual void setHasUpstreamUpdates(bool hasUpstreamUpdates) { - _hasUpstreamUpdates = hasUpstreamUpdates; - } - - std::optional lastUpdateFrame() { - return _lastUpdateFrame; - } - virtual void setLastUpdateFrame(std::optional lastUpdateFrame) { - _lastUpdateFrame = lastUpdateFrame; - } - - /// Marks if updates to this node affect nodes downstream. - virtual bool localUpdatesPermeateDownstream() { - /// Optional override - return true; - } - virtual bool forceUpstreamOutputUpdates() { - /// Optional - return false; - } - - /// Called at the end of this nodes update cycle. Always called. Optional. - virtual bool performAdditionalLocalUpdates(float frame, bool forceLocalUpdate) { - /// Optional - return forceLocalUpdate; - } - virtual void performAdditionalOutputUpdates(float frame, bool forceOutputUpdate) { - /// Optional - } - - /// The default simply returns `hasLocalUpdates` - virtual bool shouldRebuildOutputs(float frame) { - return hasLocalUpdates(); - } - - virtual bool updateOutputs(float frame, bool forceOutputUpdate) { - if (!isEnabled()) { - setLastUpdateFrame(frame); - if (const auto parentNodeValue = parentNode()) { - return parentNodeValue->updateOutputs(frame, forceOutputUpdate); - } else { - return false; - } - } - - if (!forceOutputUpdate && lastUpdateFrame().has_value() && lastUpdateFrame().value() == frame) { - /// This node has already updated for this frame. Go ahead and return the results. - return hasUpstreamUpdates() || hasLocalUpdates(); - } - - /// Ask if this node should force output updates upstream. - bool forceUpstreamUpdates = forceOutputUpdate || forceUpstreamOutputUpdates(); - - /// Perform upstream output updates. Optionally mark upstream updates if any. - if (const auto parentNodeValue = parentNode()) { - setHasUpstreamUpdates(parentNodeValue->updateOutputs(frame, forceUpstreamUpdates) || hasUpstreamUpdates()); - } else { - setHasUpstreamUpdates(hasUpstreamUpdates()); - } - - /// Perform additional local output updates - performAdditionalOutputUpdates(frame, forceUpstreamUpdates); - - /// If there are local updates, or if updates have been force, rebuild outputs - if (forceUpstreamUpdates || shouldRebuildOutputs(frame)) { - setLastUpdateFrame(frame); - rebuildOutputs(frame); - } - return hasUpstreamUpdates() || hasLocalUpdates(); - } - - /// Rebuilds the content of this node, and upstream nodes if necessary. - virtual bool updateContents(float frame, bool forceLocalUpdate) { - if (!isEnabled()) { - // Disabled node, pass through. - if (const auto parentNodeValue = parentNode()) { - return parentNodeValue->updateContents(frame, forceLocalUpdate); - } else { - return false; - } - } - - if (forceLocalUpdate == false && lastUpdateFrame().has_value() && lastUpdateFrame().value() == frame) { - /// This node has already updated for this frame. Go ahead and return the results. - return localUpdatesPermeateDownstream() ? hasUpstreamUpdates() || hasLocalUpdates() : hasUpstreamUpdates(); - } - - /// Are there local updates? If so mark the node. - setHasLocalUpdates(forceLocalUpdate ? forceLocalUpdate : propertyMap()->needsLocalUpdate(frame)); - - /// Were there upstream updates? If so mark the node - if (const auto parentNodeValue = parentNode()) { - setHasUpstreamUpdates(parentNodeValue->updateContents(frame, forceLocalUpdate)); - } else { - setHasUpstreamUpdates(false); - } - - /// Perform property updates if necessary. - if (hasLocalUpdates()) { - /// Rebuild local properties - propertyMap()->updateNodeProperties(frame); - } - - /// Ask the node to perform any other updates it might have. - setHasUpstreamUpdates(performAdditionalLocalUpdates(frame, forceLocalUpdate) || hasUpstreamUpdates()); - - /// If the node can update nodes downstream, notify them, otherwise pass on any upstream updates downstream. - return localUpdatesPermeateDownstream() ? hasUpstreamUpdates() || hasLocalUpdates() : hasUpstreamUpdates(); - } - - bool updateTree(float frame, bool forceUpdates) { - if (updateContents(frame, forceUpdates)) { - return updateOutputs(frame, forceUpdates); - } else { - return false; - } - } - - /// The name of the Keypath - virtual std::string keypathName() const override { - return propertyMap()->keypathName(); - } - - /// A list of properties belonging to the keypath. - virtual std::map> keypathProperties() const override { - return propertyMap()->keypathProperties(); - } - - /// Children Keypaths - virtual std::vector> const &childKeypaths() const override { - return propertyMap()->childKeypaths(); - } - - virtual std::shared_ptr keypathLayer() const override { - return nullptr; - } - -public: - virtual LayerTransformNode *asLayerTransformNode() { - return nullptr; - } - - virtual PathNode *asPathNode() { - return nullptr; - } - - virtual RenderNode *asRenderNode() { - return nullptr; - } - -private: - std::shared_ptr _parentNode; - bool _isEnabled = true; - bool _hasLocalUpdates = false; - bool _hasUpstreamUpdates = false; - std::optional _lastUpdateFrame; -}; - -} - -#endif /* AnimatorNode_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Protocols/NodeOutput.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Protocols/NodeOutput.hpp deleted file mode 100644 index 69d5dd81d5..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Protocols/NodeOutput.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef NodeOutput_hpp -#define NodeOutput_hpp - -#include - -#include - -namespace lottie { - -/// Defines the basic outputs of an animator node. -/// -class NodeOutput { -public: - /// The parent node. - virtual std::shared_ptr parent() = 0; - - /// Returns true if there are any updates upstream. OutputPath must be built before returning. - virtual bool hasOutputUpdates(float forFrame) = 0; - - virtual std::shared_ptr outputPath() = 0; - - virtual bool isEnabled() const = 0; - virtual void setIsEnabled(bool isEnabled) = 0; -}; - -} - -#endif /* NodeOutput_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Protocols/RenderNode.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Protocols/RenderNode.hpp deleted file mode 100644 index 5db444d408..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/Protocols/RenderNode.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef RenderNode_hpp -#define RenderNode_hpp - -#include "Lottie/Public/Primitives/CALayer.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/Protocols/AnimatorNode.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/Protocols/NodeOutput.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/HasRenderUpdates.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/HasUpdate.hpp" - -namespace lottie { - -class StrokeRenderer; -class FillRenderer; -class GradientStrokeRenderer; -class GradientFillRenderer; - -/// A protocol that defines anything with render instructions -class Renderable: virtual public HasRenderUpdates, virtual public HasUpdate { -public: - enum RenderableType { - Fill, - Stroke, - GradientFill, - GradientStroke - }; - -public: - /// Determines if the renderer requires a custom context for drawing. - /// If yes the shape layer will perform a custom drawing pass. - /// If no the shape layer will be a standard CAShapeLayer - virtual bool shouldRenderInContext() = 0; - - /// Passes in the CAShapeLayer to update - virtual void updateShapeLayer(std::shared_ptr const &layer) = 0; - - /// Asks the renderer what the renderable bounds is for the given box. - virtual CGRect renderBoundsFor(CGRect const &boundingBox) { - /// Optional - return boundingBox; - } - - /// Opportunity for renderers to inject sublayers - virtual void setupSublayers(std::shared_ptr const &layer) = 0; - - virtual RenderableType renderableType() const = 0; - - virtual StrokeRenderer *asStrokeRenderer() { - return nullptr; - } - - virtual FillRenderer *asFillRenderer() { - return nullptr; - } - - virtual GradientStrokeRenderer *asGradientStrokeRenderer() { - return nullptr; - } - - virtual GradientFillRenderer *asGradientFillRenderer() { - return nullptr; - } -}; - -/// A protocol that defines a node that holds render instructions -class RenderNode { -public: - virtual std::shared_ptr renderer() = 0; - virtual std::shared_ptr nodeOutput() = 0; -}; - -} - -#endif /* RenderNode_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/RenderLayers/GetGradientParameters.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/RenderLayers/GetGradientParameters.cpp deleted file mode 100644 index a1ec1b2bed..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/RenderLayers/GetGradientParameters.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include "GetGradientParameters.hpp" - -namespace lottie { - -void getGradientParameters(int numberOfColors, GradientColorSet const &colors, std::vector &outColors, std::vector &outLocations) { - std::vector alphaColors; - std::vector alphaValues; - std::vector alphaLocations; - - std::vector gradientColors; - std::vector colorLocations; - - for (int i = 0; i < numberOfColors; i++) { - int ix = i * 4; - if (colors.colors.size() > ix) { - Color color( - colors.colors[ix + 1], - colors.colors[ix + 2], - colors.colors[ix + 3], - 1 - ); - gradientColors.push_back(color); - colorLocations.push_back(colors.colors[ix]); - } - } - - bool drawMask = false; - for (int i = numberOfColors * 4; i < (int)colors.colors.size(); i += 2) { - float alpha = colors.colors[i + 1]; - if (alpha < 1.0) { - drawMask = true; - } - alphaLocations.push_back(colors.colors[i]); - alphaColors.push_back(Color(alpha, alpha, alpha, 1.0)); - alphaValues.push_back(alpha); - } - - if (drawMask) { - std::vector locations; - for (size_t i = 0; i < std::min(gradientColors.size(), colorLocations.size()); i++) { - if (std::find(locations.begin(), locations.end(), colorLocations[i]) == locations.end()) { - locations.push_back(colorLocations[i]); - } - } - for (size_t i = 0; i < std::min(alphaValues.size(), alphaLocations.size()); i++) { - if (std::find(locations.begin(), locations.end(), alphaLocations[i]) == locations.end()) { - locations.push_back(alphaLocations[i]); - } - } - - std::sort(locations.begin(), locations.end()); - if (locations[0] != 0.0) { - locations.insert(locations.begin(), 0.0); - } - if (locations[locations.size() - 1] != 1.0) { - locations.push_back(1.0); - } - - std::vector colors; - - for (const auto location : locations) { - Color color = gradientColors[0]; - for (size_t i = 0; i < std::min(gradientColors.size(), colorLocations.size()) - 1; i++) { - if (location >= colorLocations[i] && location <= colorLocations[i + 1]) { - float localLocation = 0.0; - if (colorLocations[i] != colorLocations[i + 1]) { - localLocation = remapFloat(location, colorLocations[i], colorLocations[i + 1], 0.0, 1.0); - } - color = ValueInterpolator::interpolate(gradientColors[i], gradientColors[i + 1], localLocation, std::nullopt, std::nullopt); - break; - } - } - - float alpha = 1.0; - for (size_t i = 0; i < std::min(alphaValues.size(), alphaLocations.size()) - 1; i++) { - if (location >= alphaLocations[i] && location <= alphaLocations[i + 1]) { - float localLocation = 0.0; - if (alphaLocations[i] != alphaLocations[i + 1]) { - localLocation = remapFloat(location, alphaLocations[i], alphaLocations[i + 1], 0.0, 1.0); - } - alpha = ValueInterpolator::interpolate(alphaValues[i], alphaValues[i + 1], localLocation, std::nullopt, std::nullopt); - break; - } - } - - color.a = alpha; - - colors.push_back(color); - } - - gradientColors = colors; - colorLocations = locations; - } - - outColors = gradientColors; - outLocations = colorLocations; -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/RenderLayers/GetGradientParameters.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/RenderLayers/GetGradientParameters.hpp deleted file mode 100644 index 8319b8505b..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/MainThread/NodeRenderSystem/RenderLayers/GetGradientParameters.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef ShapeRenderLayer_hpp -#define ShapeRenderLayer_hpp - -#include "Lottie/Private/MainThread/NodeRenderSystem/Protocols/RenderNode.hpp" -#include "Lottie/Private/MainThread/NodeRenderSystem/Protocols/NodeOutput.hpp" - -namespace lottie { - -void getGradientParameters(int numberOfColors, GradientColorSet const &colors, std::vector &outColors, std::vector &outLocations); - -} - -#endif /* ShapeRenderLayer_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Animation.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Animation.cpp deleted file mode 100644 index 577a56be35..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Animation.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Animation.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Animation.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Animation.hpp deleted file mode 100644 index ffeb67964b..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Animation.hpp +++ /dev/null @@ -1,314 +0,0 @@ -#ifndef Animation_hpp -#define Animation_hpp - -#include "Lottie/Public/Primitives/AnimationTime.hpp" -#include "Lottie/Private/Utility/Primitives/CoordinateSpace.hpp" -#include "Lottie/Private/Model/Layers/LayerModel.hpp" -#include "Lottie/Private/Model/Text/Glyph.hpp" -#include "Lottie/Private/Model/Text/Font.hpp" -#include "Lottie/Private/Model/Objects/Marker.hpp" -#include "Lottie/Private/Model/Assets/AssetLibrary.hpp" -#include "Lottie/Private/Model/Objects/FitzModifier.hpp" - -#include -#include "Lottie/Private/Parsing/JsonParsing.hpp" -#include "Lottie/Private/Model/Layers/LayerModelSerialization.hpp" - -#include -#include -#include -#include - -namespace lottie { - -/// The `Animation` model is the top level model object in Lottie. -/// -/// An `Animation` holds all of the animation data backing a Lottie Animation. -/// Codable, see JSON schema [here](https://github.com/airbnb/lottie-web/tree/master/docs/json). -class Animation { -public: - Animation( - std::optional name_, - std::optional tgs_, - AnimationFrameTime startFrame_, - AnimationFrameTime endFrame_, - float framerate_, - std::string const &version_, - std::optional type_, - int width_, - int height_, - std::vector> const &layers_, - std::optional>> glyphs_, - std::optional> fonts_, - std::shared_ptr assetLibrary_, - std::optional> markers_, - std::optional> fitzModifiers_, - std::optional meta_, - std::optional comps_ - ) : - startFrame(startFrame_), - endFrame(endFrame_), - framerate(framerate_), - name(name_), - version(version_), - tgs(tgs_), - type(type_), - width(width_), - height(height_), - layers(layers_), - glyphs(glyphs_), - fonts(fonts_), - assetLibrary(assetLibrary_), - markers(markers_), - fitzModifiers(fitzModifiers_), - meta(meta_), - comps(comps_) { - if (markers) { - std::map parsedMarkerMap; - for (const auto &marker : markers.value()) { - parsedMarkerMap.insert(std::make_pair(marker.name, marker)); - } - markerMap = std::move(parsedMarkerMap); - } - } - - Animation(const Animation&) = delete; - Animation& operator=(Animation&) = delete; - - static std::shared_ptr fromJson(lottiejson11::Json::object const &json) noexcept(false) { - auto name = getOptionalString(json, "nm"); - auto version = getString(json, "v"); - - auto tgs = getOptionalInt(json, "tgs"); - - std::optional type; - if (const auto typeRawValue = getOptionalInt(json, "ddd")) { - if (typeRawValue.value() == 0) { - type = CoordinateSpace::Type2d; - } else { - type = CoordinateSpace::Type3d; - } - } - - AnimationFrameTime startFrame = (float)getDouble(json, "ip"); - AnimationFrameTime endFrame = (float)getDouble(json, "op"); - - float framerate = (float)getDouble(json, "fr"); - - int width = getInt(json, "w"); - int height = getInt(json, "h"); - - auto layerDictionaries = getObjectArray(json, "layers"); - std::vector> layers; - for (size_t i = 0; i < layerDictionaries.size(); i++) { - try { - auto layer = parseLayerModel(layerDictionaries[i]); - layers.push_back(layer); - } catch(...) { - throw LottieParsingException(); - } - } - - std::optional>> glyphs; - if (const auto glyphDictionaries = getOptionalObjectArray(json, "chars")) { - glyphs = std::vector>(); - for (const auto &glyphDictionary : glyphDictionaries.value()) { - glyphs->push_back(std::make_shared(glyphDictionary)); - } - } else { - glyphs = std::nullopt; - } - - std::optional> fonts; - if (const auto fontsDictionary = getOptionalObject(json, "fonts")) { - fonts = std::make_shared(fontsDictionary.value()); - } - - std::shared_ptr assetLibrary; - if (const auto assetLibraryData = getOptionalAny(json, "assets")) { - assetLibrary = std::make_shared(assetLibraryData.value()); - } - - std::optional> markers; - if (const auto markerDictionaries = getOptionalObjectArray(json, "markers")) { - markers = std::vector(); - for (const auto &markerDictionary : markerDictionaries.value()) { - markers->push_back(Marker(markerDictionary)); - } - } - std::optional> fitzModifiers; - if (const auto fitzModifierDictionaries = getOptionalObjectArray(json, "fitz")) { - fitzModifiers = std::vector(); - for (const auto &fitzModifierDictionary : fitzModifierDictionaries.value()) { - fitzModifiers->push_back(FitzModifier(fitzModifierDictionary)); - } - } - - auto meta = getOptionalAny(json, "meta"); - auto comps = getOptionalAny(json, "comps"); - - return std::make_shared( - name, - tgs, - startFrame, - endFrame, - framerate, - version, - type, - width, - height, - std::move(layers), - std::move(glyphs), - std::move(fonts), - assetLibrary, - std::move(markers), - fitzModifiers, - meta, - comps - ); - } - - lottiejson11::Json::object toJson() const { - lottiejson11::Json::object result; - - if (name.has_value()) { - result.insert(std::make_pair("nm", name.value())); - } - - result.insert(std::make_pair("v", lottiejson11::Json(version))); - - if (tgs.has_value()) { - result.insert(std::make_pair("tgs", tgs.value())); - } - - if (type.has_value()) { - switch (type.value()) { - case CoordinateSpace::Type2d: - result.insert(std::make_pair("ddd", lottiejson11::Json(0))); - break; - case CoordinateSpace::Type3d: - result.insert(std::make_pair("ddd", lottiejson11::Json(1))); - break; - } - } - - result.insert(std::make_pair("ip", lottiejson11::Json(startFrame))); - result.insert(std::make_pair("op", lottiejson11::Json(endFrame))); - result.insert(std::make_pair("fr", lottiejson11::Json(framerate))); - result.insert(std::make_pair("w", lottiejson11::Json(width))); - result.insert(std::make_pair("h", lottiejson11::Json(height))); - - lottiejson11::Json::array layersArray; - for (const auto &layer : layers) { - lottiejson11::Json::object layerJson; - layer->toJson(layerJson); - layersArray.push_back(layerJson); - } - result.insert(std::make_pair("layers", lottiejson11::Json(layersArray))); - - if (glyphs.has_value()) { - lottiejson11::Json::array glyphArray; - for (const auto &glyph : glyphs.value()) { - glyphArray.push_back(glyph->toJson()); - } - result.insert(std::make_pair("chars", lottiejson11::Json(glyphArray))); - } - - if (fonts.has_value()) { - result.insert(std::make_pair("fonts", fonts.value()->toJson())); - } - - if (assetLibrary) { - result.insert(std::make_pair("assets", assetLibrary->toJson())); - } - - if (markers.has_value()) { - lottiejson11::Json::array markerArray; - for (const auto &marker : markers.value()) { - markerArray.push_back(marker.toJson()); - } - result.insert(std::make_pair("markers", lottiejson11::Json(markerArray))); - } - - if (fitzModifiers.has_value()) { - lottiejson11::Json::array fitzModifierArray; - for (const auto &fitzModifier : fitzModifiers.value()) { - fitzModifierArray.push_back(fitzModifier.toJson()); - } - result.insert(std::make_pair("fitz", lottiejson11::Json(fitzModifierArray))); - } - - if (meta.has_value()) { - result.insert(std::make_pair("meta", meta.value())); - } - if (comps.has_value()) { - result.insert(std::make_pair("comps", comps.value())); - } - - return result; - } - -public: - /// The start time of the composition in frameTime. - AnimationFrameTime startFrame; - - /// The end time of the composition in frameTime. - AnimationFrameTime endFrame; - - /// The frame rate of the composition. - float framerate; - - /// Return all marker names, in order, or an empty list if none are specified - std::vector markerNames() { - if (!markers.has_value()) { - return {}; - } - std::vector result; - for (const auto &marker : markers.value()) { - result.push_back(marker.name); - } - return result; - } - - /// Animation name - std::optional name; - - /// The version of the JSON Schema. - std::string version; - - std::optional tgs; - - /// The coordinate space of the composition. - std::optional type; - - /// The height of the composition in points. - int width; - - /// The width of the composition in points. - int height; - - /// The list of animation layers - std::vector> layers; - - /// The list of glyphs used for text rendering - std::optional>> glyphs; - - /// The list of fonts used for text rendering - std::optional> fonts; - - /// Asset Library - std::shared_ptr assetLibrary; - - /// Markers - std::optional> markers; - std::optional> markerMap; - - std::optional> fitzModifiers; - - std::optional meta; - std::optional comps; -}; - -} - -#endif /* Animation_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/Asset.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/Asset.cpp deleted file mode 100644 index 12f67cdd8a..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/Asset.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Asset.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/Asset.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/Asset.hpp deleted file mode 100644 index dabec9756c..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/Asset.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef Asset_hpp -#define Asset_hpp - -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include -#include - -namespace lottie { - -class Asset { -public: - Asset(std::string id_) : - id(id_) { - } - - explicit Asset(lottiejson11::Json::object const &json) noexcept(false) { - auto idData = getAny(json, "id"); - if (idData.is_string()) { - id = idData.string_value(); - } else if (idData.is_number()) { - std::ostringstream idString; - idString << idData.int_value(); - id = idString.str(); - } - - objectName = getOptionalString(json, "nm"); - } - - Asset(const Asset&) = delete; - Asset& operator=(Asset&) = delete; - - virtual void toJson(lottiejson11::Json::object &json) const { - json.insert(std::make_pair("id", id)); - - if (objectName.has_value()) { - json.insert(std::make_pair("nm", objectName.value())); - } - } - -public: - /// The ID of the asset - std::string id; - - std::optional objectName; -}; - -} - -#endif /* Asset_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/AssetLibrary.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/AssetLibrary.cpp deleted file mode 100644 index 7feff3231e..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/AssetLibrary.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "AssetLibrary.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/AssetLibrary.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/AssetLibrary.hpp deleted file mode 100644 index 5e7b893d02..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/AssetLibrary.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef AssetLibrary_hpp -#define AssetLibrary_hpp - -#include "Lottie/Private/Model/Assets/Asset.hpp" -#include "Lottie/Private/Model/Assets/ImageAsset.hpp" -#include "Lottie/Private/Model/Assets/PrecompAsset.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include - -namespace lottie { - -class AssetLibrary { -public: - AssetLibrary( - std::map> const &assets_, - std::map> const &imageAssets_, - std::map> const &precompAssets_ - ) : - assets(assets_), - imageAssets(imageAssets_), - precompAssets(precompAssets_) { - } - - explicit AssetLibrary(lottiejson11::Json const &json) noexcept(false) { - if (!json.is_array()) { - throw LottieParsingException(); - } - - for (const auto &item : json.array_items()) { - if (!item.is_object()) { - throw LottieParsingException(); - } - if (item.object_items().find("layers") != item.object_items().end()) { - auto asset = std::make_shared(item.object_items()); - assets.insert(std::make_pair(asset->id, asset)); - assetList.push_back(asset); - precompAssets.insert(std::make_pair(asset->id, asset)); - } else { - auto asset = std::make_shared(item.object_items()); - assets.insert(std::make_pair(asset->id, asset)); - assetList.push_back(asset); - imageAssets.insert(std::make_pair(asset->id, asset)); - } - } - } - - lottiejson11::Json::array toJson() const { - lottiejson11::Json::array result; - - for (const auto &asset : assetList) { - lottiejson11::Json::object assetJson; - asset->toJson(assetJson); - result.push_back(assetJson); - } - - return result; - } - -public: - /// The Assets - std::vector> assetList; - std::map> assets; - - std::map> imageAssets; - std::map> precompAssets; -}; - -} - -#endif /* AssetLibrary_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/ImageAsset.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/ImageAsset.cpp deleted file mode 100644 index b5a2e57d52..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/ImageAsset.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "ImageAsset.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/ImageAsset.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/ImageAsset.hpp deleted file mode 100644 index 5eea900309..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/ImageAsset.hpp +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef ImageAsset_hpp -#define ImageAsset_hpp - -#include "Lottie/Private/Model/Assets/Asset.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -namespace lottie { - -class Image { -public: - Image() { - } -}; - -class ImageAsset: public Asset { -public: - ImageAsset( - std::string id_, - std::string name_, - std::string directory_, - float width_, - float height_ - ) : Asset(id_), - name(name_), - directory(directory_), - width(width_), - height(height_) { - } - - virtual ~ImageAsset() = default; - - explicit ImageAsset(lottiejson11::Json::object const &json) noexcept(false) : - Asset(json) { - name = getString(json, "p"); - directory = getString(json, "u"); - width = (float)getDouble(json, "w"); - height = (float)getDouble(json, "h"); - - _e = getOptionalInt(json, "e"); - _t = getOptionalString(json, "t"); - } - - virtual void toJson(lottiejson11::Json::object &json) const override { - Asset::toJson(json); - - json.insert(std::make_pair("p", name)); - json.insert(std::make_pair("u", directory)); - json.insert(std::make_pair("w", width)); - json.insert(std::make_pair("h", height)); - - if (_e.has_value()) { - json.insert(std::make_pair("e", _e.value())); - } - if (_t.has_value()) { - json.insert(std::make_pair("t", _t.value())); - } - } - -public: - /// Image name - std::string name; - - /// Image Directory - std::string directory; - - /// Image Size - float width; - float height; - - std::optional _e; - std::optional _t; -}; - -/*extension Data { - - // MARK: Lifecycle - - /// Initializes `Data` from an `ImageAsset`. - /// - /// Returns nil when the input is not recognized as valid Data URL. - /// - parameter imageAsset: The image asset that contains Data URL. - internal init?(imageAsset: ImageAsset) { - self.init(dataString: imageAsset.name) - } - - /// Initializes `Data` from a [Data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) String. - /// - /// Returns nil when the input is not recognized as valid Data URL. - /// - parameter dataString: The data string to parse. - /// - parameter options: Options for the string parsing. Default value is `[]`. - internal init?(dataString: String, options: DataURLReadOptions = []) { - guard - dataString.hasPrefix("data:"), - let url = URL(string: dataString) - else { - return nil - } - // The code below is needed because Data(contentsOf:) floods logs - // with messages since url doesn't have a host. This only fixes flooding logs - // when data inside Data URL is base64 encoded. - if - let base64Range = dataString.range(of: ";base64,"), - !options.contains(DataURLReadOptions.legacy) - { - let encodedString = String(dataString[base64Range.upperBound...]) - self.init(base64Encoded: encodedString) - } else { - try? self.init(contentsOf: url) - } - } - - // MARK: Internal - - internal struct DataURLReadOptions: OptionSet { - let rawValue: Int - - /// Will read Data URL using Data(contentsOf:) - static let legacy = DataURLReadOptions(rawValue: 1 << 0) - } - -};*/ - -} - -#endif /* ImageAsset_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/PrecompAsset.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/PrecompAsset.cpp deleted file mode 100644 index 976044565a..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/PrecompAsset.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "PrecompAsset.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/PrecompAsset.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/PrecompAsset.hpp deleted file mode 100644 index af169474a7..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Assets/PrecompAsset.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef PrecompAsset_hpp -#define PrecompAsset_hpp - -#include "Lottie/Private/Model/Assets/Asset.hpp" -#include "Lottie/Private/Model/Layers/LayerModel.hpp" -#include "Lottie/Private/Model/Layers/LayerModelSerialization.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include - -namespace lottie { - -class PrecompAsset: public Asset { -public: - PrecompAsset( - std::string const &id_, - std::vector> const &layers_ - ) : Asset(id_), - layers(layers_) { - } - - virtual ~PrecompAsset() = default; - - explicit PrecompAsset(lottiejson11::Json::object const &json) noexcept(false) : - Asset(json) { - if (const auto frameRateValue = getOptionalDouble(json, "fr")) { - frameRate = (float)frameRateValue.value(); - } - - auto layerDictionaries = getObjectArray(json, "layers"); - for (size_t i = 0; i < layerDictionaries.size(); i++) { - try { - auto layer = parseLayerModel(layerDictionaries[i]); - layers.push_back(layer); - } catch(...) { - throw LottieParsingException(); - } - } - } - - virtual void toJson(lottiejson11::Json::object &json) const override { - Asset::toJson(json); - - lottiejson11::Json::array layerArray; - for (const auto &layer : layers) { - lottiejson11::Json::object layerJson; - layer->toJson(layerJson); - layerArray.push_back(layerJson); - } - json.insert(std::make_pair("layers", layerArray)); - - if (frameRate.has_value()) { - json.insert(std::make_pair("fr", frameRate.value())); - } - } - -public: - /// Layers of the precomp - std::vector> layers; - - std::optional frameRate; -}; - -} - -#endif /* PrecompAsset_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Keyframes/KeyframeGroup.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Keyframes/KeyframeGroup.cpp deleted file mode 100644 index 2f0c1a788a..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Keyframes/KeyframeGroup.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "KeyframeGroup.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Keyframes/KeyframeGroup.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Keyframes/KeyframeGroup.hpp deleted file mode 100644 index 50549a1121..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Keyframes/KeyframeGroup.hpp +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef KeyframeGroup_hpp -#define KeyframeGroup_hpp - -#include "Lottie/Public/Keyframes/Keyframe.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include - -namespace lottie { - -/// Used for coding/decoding a group of Keyframes by type. -/// -/// Keyframe data is wrapped in a dictionary { "k" : KeyframeData }. -/// The keyframe data can either be an array of keyframes or, if no animation is present, the raw value. -/// This helper object is needed to properly decode the json. - -template -class KeyframeGroup { -public: - KeyframeGroup(std::vector> &&keyframes_) : - keyframes(std::move(keyframes_)), - isSingle(false) { - } - - KeyframeGroup(T const &value_) : - keyframes({ Keyframe(value_, std::nullopt, std::nullopt) }), - isSingle(false) { - } - - KeyframeGroup(lottiejson11::Json::object const &json) noexcept(false) { - isAnimated = getOptionalInt(json, "a"); - expression = getOptionalAny(json, "x"); - expressionIndex = getOptionalInt(json, "ix"); - _extraL = getOptionalInt(json, "l"); - - auto containerData = getAny(json, "k"); - - try { - LottieParsingException::Guard expectedException; - T keyframeData = T(containerData); - keyframes.push_back(Keyframe(keyframeData, std::nullopt, std::nullopt)); - isSingle = true; - } catch(...) { - // Decode and array of keyframes. - // - // Body Movin and Lottie deal with keyframes in different ways. - // - // A keyframe object in Body movin defines a span of time with a START - // and an END, from the current keyframe time to the next keyframe time. - // - // A keyframe object in Lottie defines a singular point in time/space. - // This point has an in-tangent and an out-tangent. - // - // To properly decode this we must iterate through keyframes while holding - // reference to the previous keyframe. - - if (!containerData.is_array()) { - throw LottieParsingException(); - } - - std::optional> previousKeyframeData; - for (const auto &containerItem : containerData.array_items()) { - // Ensure that Time and Value are present. - auto keyframeData = KeyframeData(containerItem); - rawKeyframeData.push_back(keyframeData); - - std::optional value; - if (keyframeData.startValue.has_value()) { - value = keyframeData.startValue; - } else if (previousKeyframeData.has_value()) { - value = previousKeyframeData->endValue; - } - if (!value.has_value()) { - throw LottieParsingException(); - } - if (!keyframeData.time.has_value()) { - throw LottieParsingException(); - } - - std::optional inTangent; - std::optional spatialInTangent; - if (previousKeyframeData.has_value()) { - inTangent = previousKeyframeData->inTangent; - spatialInTangent = previousKeyframeData->spatialInTangent; - } - - keyframes.emplace_back( - value.value(), - keyframeData.time.value(), - keyframeData.isHold(), - inTangent, - keyframeData.outTangent, - spatialInTangent, - keyframeData.spatialOutTangent - ); - - previousKeyframeData = keyframeData; - } - - isSingle = false; - } - } - - lottiejson11::Json::object toJson() const { - lottiejson11::Json::object result; - - assert(!keyframes.empty()); - - if (keyframes.size() == 1 && isSingle) { - result.insert(std::make_pair("k", keyframes[0].value.toJson())); - } else { - lottiejson11::Json::array containerData; - - for (const auto &keyframe : rawKeyframeData) { - containerData.push_back(keyframe.toJson()); - } - - result.insert(std::make_pair("k", containerData)); - } - - if (isAnimated.has_value()) { - result.insert(std::make_pair("a", isAnimated.value())); - } - if (expression.has_value()) { - result.insert(std::make_pair("x", expression.value())); - } - if (expressionIndex.has_value()) { - result.insert(std::make_pair("ix", expressionIndex.value())); - } - if (_extraL.has_value()) { - result.insert(std::make_pair("l", _extraL.value())); - } - - return result; - } - -public: - std::vector> keyframes; - std::optional isAnimated; - - std::optional expression; - std::optional expressionIndex; - std::vector> rawKeyframeData; - bool isSingle = false; - std::optional _extraL; -}; - -} - -#endif /* KeyframeGroup_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/ImageLayerModel.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/ImageLayerModel.cpp deleted file mode 100644 index 4251973760..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/ImageLayerModel.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "ImageLayerModel.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/ImageLayerModel.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/ImageLayerModel.hpp deleted file mode 100644 index 23349f7390..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/ImageLayerModel.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef ImageLayerModel_hpp -#define ImageLayerModel_hpp - -#include "Lottie/Private/Model/Layers/LayerModel.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -namespace lottie { - -/// A layer that holds an image. -class ImageLayerModel: public LayerModel { -public: - explicit ImageLayerModel(lottiejson11::Json::object const &json) noexcept(false) : - LayerModel(json) { - referenceID = getString(json, "refId"); - - _sc = getOptionalString(json, "sc"); - } - - virtual ~ImageLayerModel() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - LayerModel::toJson(json); - - json.insert(std::make_pair("refId", referenceID)); - - if (_sc.has_value()) { - json.insert(std::make_pair("sc", _sc.value())); - } - } - -public: - /// The reference ID of the image. - std::string referenceID; - - std::optional _sc; -}; - -} - -#endif /* ImageLayerModel_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/LayerModel.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/LayerModel.cpp deleted file mode 100644 index f14f1df9b8..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/LayerModel.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "LayerModel.hpp" - -namespace lottie { - -LayerType parseLayerType(lottiejson11::Json::object const &json, std::string const &key) { - if (const auto layerTypeValue = getOptionalInt(json, "ty")) { - switch (layerTypeValue.value()) { - case 0: - return LayerType::Precomp; - case 1: - return LayerType::Solid; - case 2: - return LayerType::Image; - case 3: - return LayerType::Null; - case 4: - return LayerType::Shape; - case 5: - return LayerType::Text; - default: - return LayerType::Null; - } - } else { - return LayerType::Null; - } -} - -int serializeLayerType(LayerType value) { - switch (value) { - case LayerType::Precomp: - return 0; - case LayerType::Solid: - return 1; - case LayerType::Image: - return 2; - case LayerType::Null: - return 3; - case LayerType::Shape: - return 4; - case LayerType::Text: - return 5; - } -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/LayerModel.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/LayerModel.hpp deleted file mode 100644 index 16f84d0f10..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/LayerModel.hpp +++ /dev/null @@ -1,318 +0,0 @@ -#ifndef LayerModel_hpp -#define LayerModel_hpp - -#include "Lottie/Private/Model/Objects/Transform.hpp" -#include "Lottie/Private/Model/Objects/Mask.hpp" -#include "Lottie/Private/Utility/Primitives/CoordinateSpace.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include -#include -#include - -namespace lottie { - -enum class LayerType { - Precomp, - Solid, - Image, - Null, - Shape, - Text -}; - -LayerType parseLayerType(lottiejson11::Json::object const &json, std::string const &key); -int serializeLayerType(LayerType value); - -enum class MatteType: int { - None = 0, - Add = 1, - Invert = 2, - Unknown = 3 -}; - -enum class BlendMode: int { - Normal = 0, - Multiply = 1, - Screen = 2, - Overlay = 3, - Darken = 4, - Lighten = 5, - ColorDodge = 6, - ColorBurn = 7, - HardLight = 8, - SoftLight = 9, - Difference = 10, - Exclusion = 11, - Hue = 12, - Saturation = 13, - Color = 14, - Luminosity = 15 -}; - -/// A base top container for shapes, images, and other view objects. -class LayerModel { -public: - explicit LayerModel(lottiejson11::Json::object const &json) noexcept(false) { - name = getOptionalString(json, "nm"); - index = getOptionalInt(json, "ind"); - - type = parseLayerType(json, "ty"); - - autoOrient = getOptionalInt(json, "ao"); - - if (const auto typeRawValue = getOptionalInt(json, "ddd")) { - if (typeRawValue.value() == 0) { - coordinateSpace = CoordinateSpace::Type2d; - } else { - coordinateSpace = CoordinateSpace::Type3d; - } - } else { - coordinateSpace = std::nullopt; - } - - inFrame = (float)getDouble(json, "ip"); - outFrame = (float)getDouble(json, "op"); - startTime = (float)getDouble(json, "st"); - - transform = std::make_shared(getObject(json, "ks")); - parent = getOptionalInt(json, "parent"); - - if (const auto blendModeRawValue = getOptionalInt(json, "bm")) { - switch (blendModeRawValue.value()) { - case 0: - blendMode = BlendMode::Normal; - break; - case 1: - blendMode = BlendMode::Multiply; - break; - case 2: - blendMode = BlendMode::Screen; - break; - case 3: - blendMode = BlendMode::Overlay; - break; - case 4: - blendMode = BlendMode::Darken; - break; - case 5: - blendMode = BlendMode::Lighten; - break; - case 6: - blendMode = BlendMode::ColorDodge; - break; - case 7: - blendMode = BlendMode::ColorBurn; - break; - case 8: - blendMode = BlendMode::HardLight; - break; - case 9: - blendMode = BlendMode::SoftLight; - break; - case 10: - blendMode = BlendMode::Difference; - break; - case 11: - blendMode = BlendMode::Exclusion; - break; - case 12: - blendMode = BlendMode::Hue; - break; - case 13: - blendMode = BlendMode::Saturation; - break; - case 14: - blendMode = BlendMode::Color; - break; - case 15: - blendMode = BlendMode::Luminosity; - break; - default: - throw LottieParsingException(); - } - } - - if (const auto maskDictionaries = getOptionalObjectArray(json, "masksProperties")) { - masks = std::vector>(); - for (const auto &maskDictionary : maskDictionaries.value()) { - masks->push_back(std::make_shared(maskDictionary)); - } - } - - if (const auto timeStretchData = getOptionalDouble(json, "sr")) { - _timeStretch = (float)timeStretchData.value(); - } - - if (const auto matteRawValue = getOptionalInt(json, "tt")) { - switch (matteRawValue.value()) { - case 0: - matte = MatteType::None; - break; - case 1: - matte = MatteType::Add; - break; - case 2: - matte = MatteType::Invert; - break; - case 3: - matte = MatteType::Unknown; - break; - default: - throw LottieParsingException(); - } - } - - if (const auto hiddenData = getOptionalBool(json, "hd")) { - hidden = hiddenData.value(); - } - - hasMask = getOptionalBool(json, "hasMask"); - td = getOptionalInt(json, "td"); - effectsData = getOptionalAny(json, "ef"); - layerClass = getOptionalString(json, "cl"); - _extraHidden = getOptionalAny(json, "hidden"); - } - - LayerModel(const LayerModel&) = delete; - LayerModel& operator=(LayerModel&) = delete; - - virtual ~LayerModel() = default; - - virtual void toJson(lottiejson11::Json::object &json) const { - if (name.has_value()) { - json.insert(std::make_pair("nm", name.value())); - } - if (index.has_value()) { - json.insert(std::make_pair("ind", index.value())); - } - - if (autoOrient.has_value()) { - json.insert(std::make_pair("ao", autoOrient.value())); - } - - json.insert(std::make_pair("ty", serializeLayerType(type))); - - if (coordinateSpace.has_value()) { - switch (coordinateSpace.value()) { - case CoordinateSpace::Type2d: - json.insert(std::make_pair("ddd", 0)); - break; - case CoordinateSpace::Type3d: - json.insert(std::make_pair("ddd", 1)); - break; - } - } - - json.insert(std::make_pair("ip", inFrame)); - json.insert(std::make_pair("op", outFrame)); - json.insert(std::make_pair("st", startTime)); - - json.insert(std::make_pair("ks", transform->toJson())); - - if (parent.has_value()) { - json.insert(std::make_pair("parent", parent.value())); - } - - if (blendMode.has_value()) { - json.insert(std::make_pair("bm", (int)blendMode.value())); - } - - if (masks.has_value()) { - lottiejson11::Json::array maskArray; - for (const auto &mask : masks.value()) { - maskArray.push_back(mask->toJson()); - } - json.insert(std::make_pair("masksProperties", maskArray)); - } - - if (_timeStretch.has_value()) { - json.insert(std::make_pair("sr", _timeStretch.value())); - } - - if (matte.has_value()) { - json.insert(std::make_pair("tt", (int)matte.value())); - } - - if (hidden.has_value()) { - json.insert(std::make_pair("hd", hidden.value())); - } - - if (hasMask.has_value()) { - json.insert(std::make_pair("hasMask", hasMask.value())); - } - if (td.has_value()) { - json.insert(std::make_pair("td", td.value())); - } - if (effectsData.has_value()) { - json.insert(std::make_pair("ef", effectsData.value())); - } - if (layerClass.has_value()) { - json.insert(std::make_pair("cl", layerClass.value())); - } - if (_extraHidden.has_value()) { - json.insert(std::make_pair("hidden", _extraHidden.value())); - } - } - - float timeStretch() { - if (_timeStretch.has_value()) { - return _timeStretch.value(); - } else { - return 1.0; - } - } - -public: - /// The readable name of the layer - std::optional name; - - /// The index of the layer - std::optional index; - - /// The type of the layer. - LayerType type; - - std::optional autoOrient; - - /// The coordinate space - std::optional coordinateSpace; - - /// The in time of the layer in frames. - float inFrame; - /// The out time of the layer in frames. - float outFrame; - - /// The start time of the layer in frames. - float startTime; - - /// The transform of the layer - std::shared_ptr transform; - - /// The index of the parent layer, if applicable. - std::optional parent; - - /// The blending mode for the layer - std::optional blendMode; - - /// An array of masks for the layer. - std::optional>> masks; - - /// A number that stretches time by a multiplier - std::optional _timeStretch; - - /// The type of matte if any. - std::optional matte; - - std::optional hidden; - - std::optional hasMask; - std::optional td; - std::optional effectsData; - std::optional layerClass; - std::optional _extraHidden; -}; - -} - -#endif /* LayerModel_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/LayerModelSerialization.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/LayerModelSerialization.cpp deleted file mode 100644 index 47bb5b1467..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/LayerModelSerialization.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "LayerModelSerialization.hpp" - -#include "Lottie/Private/Model/Layers/PreCompLayerModel.hpp" -#include "Lottie/Private/Model/Layers/SolidLayerModel.hpp" -#include "Lottie/Private/Model/Layers/ImageLayerModel.hpp" -#include "Lottie/Private/Model/Layers/ShapeLayerModel.hpp" -#include "Lottie/Private/Model/Layers/TextLayerModel.hpp" - -namespace lottie { - -std::shared_ptr parseLayerModel(lottiejson11::Json::object const &json) noexcept(false) { - LayerType layerType = parseLayerType(json, "ty"); - - switch (layerType) { - case LayerType::Precomp: - return std::make_shared(json); - case LayerType::Solid: - return std::make_shared(json); - case LayerType::Image: - return std::make_shared(json); - case LayerType::Null: - return std::make_shared(json); - case LayerType::Shape: - try { - return std::make_shared(json); - } catch(...) { - throw LottieParsingException(); - } - case LayerType::Text: - return std::make_shared(json); - } -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/LayerModelSerialization.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/LayerModelSerialization.hpp deleted file mode 100644 index cc2f9ee012..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/LayerModelSerialization.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef LayerModelSerialization_hpp -#define LayerModelSerialization_hpp - -#include -#include "Lottie/Private/Parsing/JsonParsing.hpp" -#include "Lottie/Private/Model/Layers/LayerModel.hpp" - -namespace lottie { - -std::shared_ptr parseLayerModel(lottiejson11::Json::object const &json) noexcept(false); - -} - -#endif /* LayerModelSerialization_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/PreCompLayerModel.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/PreCompLayerModel.cpp deleted file mode 100644 index 2a4c7b1363..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/PreCompLayerModel.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "PreCompLayerModel.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/PreCompLayerModel.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/PreCompLayerModel.hpp deleted file mode 100644 index 16a2195a0b..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/PreCompLayerModel.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef PreCompLayerModel_hpp -#define PreCompLayerModel_hpp - -#include "Lottie/Private/Model/Layers/LayerModel.hpp" -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include - -namespace lottie { - -/// A layer that holds another animation composition. -class PreCompLayerModel: public LayerModel { -public: - PreCompLayerModel(lottiejson11::Json::object const &json) : - LayerModel(json) { - referenceID = getString(json, "refId"); - if (const auto timeRemappingData = getOptionalObject(json, "tm")) { - timeRemapping = KeyframeGroup(timeRemappingData.value()); - } - width = (float)getDouble(json, "w"); - height = (float)getDouble(json, "h"); - } - - virtual ~PreCompLayerModel() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - LayerModel::toJson(json); - - json.insert(std::make_pair("refId", referenceID)); - - if (timeRemapping.has_value()) { - json.insert(std::make_pair("tm", timeRemapping->toJson())); - } - - json.insert(std::make_pair("w", width)); - json.insert(std::make_pair("h", height)); - } - -public: - /// The reference ID of the precomp. - std::string referenceID; - - /// A value that remaps time over time. - std::optional> timeRemapping; - - /// Precomp Width - float width; - - /// Precomp Height - float height; -}; - -} - -#endif /* PreCompLayerModel_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/ShapeLayerModel.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/ShapeLayerModel.cpp deleted file mode 100644 index 608dca567b..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/ShapeLayerModel.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "ShapeLayerModel.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/ShapeLayerModel.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/ShapeLayerModel.hpp deleted file mode 100644 index 61f4329bba..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/ShapeLayerModel.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef ShapeLayerModel_hpp -#define ShapeLayerModel_hpp - -#include "Lottie/Private/Model/Layers/LayerModel.hpp" -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include - -namespace lottie { - -/// A layer that holds vector shape objects. -class ShapeLayerModel: public LayerModel { -public: - ShapeLayerModel(lottiejson11::Json::object const &json) noexcept(false) : - LayerModel(json) { - auto shapeItemsData = getObjectArray(json, "shapes"); - for (const auto &shapeItemData : shapeItemsData) { - items.push_back(parseShapeItem(shapeItemData)); - } - } - - virtual ~ShapeLayerModel() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - LayerModel::toJson(json); - - lottiejson11::Json::array shapeItemArray; - for (const auto &item : items) { - lottiejson11::Json::object itemJson; - item->toJson(itemJson); - shapeItemArray.push_back(itemJson); - } - - json.insert(std::make_pair("shapes", shapeItemArray)); - } - -public: - /// A list of shape items. - std::vector> items; -}; - -} - -#endif /* ShapeLayerModel_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/SolidLayerModel.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/SolidLayerModel.cpp deleted file mode 100644 index 153c283953..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/SolidLayerModel.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "SolidLayerModel.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/SolidLayerModel.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/SolidLayerModel.hpp deleted file mode 100644 index cea0671b49..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/SolidLayerModel.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef SolidLayerModel_hpp -#define SolidLayerModel_hpp - -#include "Lottie/Private/Model/Layers/LayerModel.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -namespace lottie { - -/// A layer that holds a solid color. -class SolidLayerModel: public LayerModel { -public: - explicit SolidLayerModel(lottiejson11::Json::object const &json) noexcept(false) : - LayerModel(json) { - colorHex = getString(json, "sc"); - width = (float)getDouble(json, "sw"); - height = (float)getDouble(json, "sh"); - } - - virtual ~SolidLayerModel() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - LayerModel::toJson(json); - - json.insert(std::make_pair("sc", colorHex)); - json.insert(std::make_pair("sw", width)); - json.insert(std::make_pair("sh", height)); - } - -public: - /// The color of the solid in Hex // Change to value provider. - std::string colorHex; - - /// The Width of the color layer - float width; - - /// The height of the color layer - float height; -}; - -} - -#endif /* SolidLayerModel_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/TextLayerModel.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/TextLayerModel.cpp deleted file mode 100644 index 9e2ad034b1..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/TextLayerModel.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "TextLayerModel.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/TextLayerModel.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/TextLayerModel.hpp deleted file mode 100644 index 37fb374ddf..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Layers/TextLayerModel.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef TextLayerModel_hpp -#define TextLayerModel_hpp - -#include "Lottie/Private/Model/Layers/LayerModel.hpp" -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include "Lottie/Private/Model/Text/TextDocument.hpp" -#include "Lottie/Private/Model/Text/TextAnimator.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -namespace lottie { - -/// A layer that holds text. -class TextLayerModel: public LayerModel { -public: - TextLayerModel(lottiejson11::Json::object const &json) : - LayerModel(json), - text(KeyframeGroup(TextDocument( - "", - 0.0, - "", - TextJustification::Left, - 0, - 0.0, - std::nullopt, - std::nullopt, - std::nullopt, - std::nullopt, - std::nullopt, - std::nullopt, - std::nullopt - ))) { - auto textContainer = getObject(json, "t"); - - auto textData = getObject(textContainer, "d"); - text = KeyframeGroup(textData); - - if (auto animatorsData = getOptionalObjectArray(textContainer, "a")) { - for (const auto &animatorData : animatorsData.value()) { - animators.push_back(std::make_shared(animatorData)); - } - } - - _extraM = getOptionalAny(textContainer, "m"); - _extraP = getOptionalAny(textContainer, "p"); - } - - virtual ~TextLayerModel() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - LayerModel::toJson(json); - - lottiejson11::Json::object textContainer; - textContainer.insert(std::make_pair("d", text.toJson())); - if (_extraM.has_value()) { - textContainer.insert(std::make_pair("m", _extraM.value())); - } - if (_extraP.has_value()) { - textContainer.insert(std::make_pair("p", _extraP.value())); - } - lottiejson11::Json::array animatorArray; - for (const auto &animator : animators) { - animatorArray.push_back(animator->toJson()); - } - textContainer.insert(std::make_pair("a", animatorArray)); - - json.insert(std::make_pair("t", textContainer)); - } - -public: - /// The text for the layer - KeyframeGroup text; - - /// Text animators - std::vector> animators; - - std::optional _extraM; - std::optional _extraP; - std::optional _extraA; -}; - -} - -#endif /* TextLayerModel_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/DashElement.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/DashElement.cpp deleted file mode 100644 index a28df19770..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/DashElement.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "DashElement.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/DashElement.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/DashElement.hpp deleted file mode 100644 index 87379ea722..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/DashElement.hpp +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef DashElement_hpp -#define DashElement_hpp - -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" -#include "Lottie/Public/Primitives/DashPattern.hpp" - -namespace lottie { - -enum class DashElementType { - Offset, - Dash, - Gap -}; - -class DashElement { -public: - DashElement( - DashElementType type_, - KeyframeGroup const &value_ - ) : - type(type_), - value(value_) { - } - - explicit DashElement(lottiejson11::Json::object const &json) noexcept(false) : - type(DashElementType::Offset), - value(KeyframeGroup(Vector1D(0.0))) { - auto typeRawValue = getString(json, "n"); - if (typeRawValue == "o") { - type = DashElementType::Offset; - } else if (typeRawValue == "d") { - type = DashElementType::Dash; - } else if (typeRawValue == "g") { - type = DashElementType::Gap; - } else { - throw LottieParsingException(); - } - - value = KeyframeGroup(getObject(json, "v")); - - name = getOptionalString(json, "nm"); - } - - lottiejson11::Json::object toJson() const { - lottiejson11::Json::object result; - - switch (type) { - case DashElementType::Offset: - result.insert(std::make_pair("n", "o")); - break; - case DashElementType::Dash: - result.insert(std::make_pair("n", "d")); - break; - case DashElementType::Gap: - result.insert(std::make_pair("n", "g")); - break; - } - - result.insert(std::make_pair("v", value.toJson())); - - if (name.has_value()) { - result.insert(std::make_pair("nm", name.value())); - } - - return result; - } - -public: - DashElementType type; - KeyframeGroup value; - - std::optional name; -}; - -} - -#endif /* DashElement_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/FitzModifier.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/FitzModifier.cpp deleted file mode 100644 index 7b18e01e4a..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/FitzModifier.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "FitzModifier.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/FitzModifier.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/FitzModifier.hpp deleted file mode 100644 index 632a2374f9..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/FitzModifier.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef FitzModifier_hpp -#define FitzModifier_hpp - -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -namespace lottie { - -class FitzModifier { -public: - explicit FitzModifier(lottiejson11::Json::object const &json) noexcept(false) { - original = getInt(json, "o"); - type12 = getOptionalInt(json, "f12"); - type3 = getOptionalInt(json, "f3"); - type4 = getOptionalInt(json, "f4"); - type5 = getOptionalInt(json, "f5"); - type6 = getOptionalInt(json, "f6"); - } - - lottiejson11::Json::object toJson() const { - lottiejson11::Json::object result; - - result.insert(std::make_pair("o", (float)original)); - if (type12.has_value()) { - result.insert(std::make_pair("f12", (float)type12.value())); - } - if (type3.has_value()) { - result.insert(std::make_pair("f3", (float)type3.value())); - } - if (type4.has_value()) { - result.insert(std::make_pair("f4", (float)type4.value())); - } - if (type5.has_value()) { - result.insert(std::make_pair("f5", (float)type5.value())); - } - if (type6.has_value()) { - result.insert(std::make_pair("f6", (float)type6.value())); - } - - return result; - } - -public: - float original; - std::optional type12; - std::optional type3; - std::optional type4; - std::optional type5; - std::optional type6; -}; - -} - -#endif /* FitzModifier_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Marker.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Marker.cpp deleted file mode 100644 index ea2664d416..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Marker.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Marker.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Marker.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Marker.hpp deleted file mode 100644 index bd1e5584dd..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Marker.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef Marker_hpp -#define Marker_hpp - -#include "Lottie/Public/Primitives/AnimationTime.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include - -namespace lottie { - -class Marker { -public: - Marker( - std::string const &name_, - AnimationFrameTime frameTime_ - ) : - name(name_), - frameTime(frameTime_) { - } - - explicit Marker(lottiejson11::Json::object const &json) noexcept(false) { - name = getString(json, "cm"); - frameTime = (float)getDouble(json, "tm"); - dr = getOptionalInt(json, "dr"); - } - - lottiejson11::Json::object toJson() const { - lottiejson11::Json::object result; - - result.insert(std::make_pair("cm", name)); - result.insert(std::make_pair("tm", frameTime)); - - if (dr.has_value()) { - result.insert(std::make_pair("dr", dr.value())); - } - - return result; - } - -public: - /// The Marker Name - std::string name; - - /// The Frame time of the marker - AnimationFrameTime frameTime; - - std::optional dr; -}; - -} - -#endif /* Marker_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Mask.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Mask.cpp deleted file mode 100644 index 8cb64d6709..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Mask.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Mask.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Mask.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Mask.hpp deleted file mode 100644 index 0a4d790684..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Mask.hpp +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef Mask_hpp -#define Mask_hpp - -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -namespace lottie { - -enum class MaskMode { - Add, - Subtract, - Intersect, - Lighten, - Darken, - Difference, - None -}; - -class Mask { -public: - explicit Mask(lottiejson11::Json::object const &json) noexcept(false) : - opacity(KeyframeGroup(Vector1D(100.0))), - shape(KeyframeGroup(BezierPath())), - inverted(false), - expansion(KeyframeGroup(Vector1D(0.0))) { - if (const auto modeRawValue = getOptionalString(json, "mode")) { - if (modeRawValue.value() == "a") { - _mode = MaskMode::Add; - } else if (modeRawValue.value() == "s") { - _mode = MaskMode::Subtract; - } else if (modeRawValue.value() == "i") { - _mode = MaskMode::Intersect; - } else if (modeRawValue.value() == "l") { - _mode = MaskMode::Lighten; - } else if (modeRawValue.value() == "d") { - _mode = MaskMode::Darken; - } else if (modeRawValue.value() == "f") { - _mode = MaskMode::Difference; - } else if (modeRawValue.value() == "n") { - _mode = MaskMode::None; - } else { - throw LottieParsingException(); - } - } - - if (const auto opacityData = getOptionalObject(json, "o")) { - opacity = KeyframeGroup(opacityData.value()); - } - - shape = KeyframeGroup(getObject(json, "pt")); - - if (const auto invertedData = getOptionalBool(json, "inv")) { - inverted = invertedData.value(); - } - - if (const auto expansionData = getOptionalObject(json, "x")) { - expansion = KeyframeGroup(expansionData.value()); - } - - name = getOptionalString(json, "nm"); - } - - lottiejson11::Json::object toJson() const { - lottiejson11::Json::object result; - - if (_mode.has_value()) { - switch (_mode.value()) { - case MaskMode::Add: - result.insert(std::make_pair("mode", "a")); - break; - case MaskMode::Subtract: - result.insert(std::make_pair("mode", "s")); - break; - case MaskMode::Intersect: - result.insert(std::make_pair("mode", "i")); - break; - case MaskMode::Lighten: - result.insert(std::make_pair("mode", "l")); - break; - case MaskMode::Darken: - result.insert(std::make_pair("mode", "d")); - break; - case MaskMode::Difference: - result.insert(std::make_pair("mode", "f")); - break; - case MaskMode::None: - result.insert(std::make_pair("mode", "n")); - break; - } - } - - if (opacity.has_value()) { - result.insert(std::make_pair("o", opacity->toJson())); - } - - result.insert(std::make_pair("pt", shape.toJson())); - - if (inverted.has_value()) { - result.insert(std::make_pair("inv", inverted.value())); - } - - if (expansion.has_value()) { - result.insert(std::make_pair("x", expansion->toJson())); - } - - if (name.has_value()) { - result.insert(std::make_pair("nm", name.value())); - } - - return result; - } - -public: - MaskMode mode() const { - if (_mode.has_value()) { - return _mode.value(); - } else { - return MaskMode::Add; - } - } - -public: - std::optional _mode; - - std::optional> opacity; - - KeyframeGroup shape; - - std::optional inverted; - - std::optional> expansion; - - std::optional name; -}; - -} - -#endif /* Mask_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Transform.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Transform.cpp deleted file mode 100644 index e55154304f..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Transform.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Transform.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Transform.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Transform.hpp deleted file mode 100644 index 19cfc92da8..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Objects/Transform.hpp +++ /dev/null @@ -1,267 +0,0 @@ -#ifndef Transform_hpp -#define Transform_hpp - -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include - -namespace lottie { - -class Transform { -public: - enum class PositionInternalRepresentation { - None, - TopLevelXY, - TopLevelCombined, - NestedXY - }; - - enum class RotationZInternalRepresentation { - RZ, - R - }; - -public: - Transform( - std::optional> anchorPoint_, - std::optional> position_, - std::optional> positionX_, - std::optional> positionY_, - std::optional> scale_, - std::optional> rotation_, - std::optional> &opacity_, - std::optional> rotationZ_ - ) : - _anchorPoint(anchorPoint_), - _position(position_), - _positionX(positionX_), - _positionY(positionY_), - _scale(scale_), - _rotation(rotation_), - _opacity(opacity_), - _rotationZ(rotationZ_) { - } - - explicit Transform(lottiejson11::Json::object const &json) noexcept(false) { - // AnchorPoint - if (const auto anchorPointDictionary = getOptionalObject(json, "a")) { - _anchorPoint = KeyframeGroup(anchorPointDictionary.value()); - } - - try { - auto xDictionary = getOptionalObject(json, "px"); - auto yDictionary = getOptionalObject(json, "py"); - if (xDictionary.has_value() && yDictionary.has_value()) { - _positionX = KeyframeGroup(xDictionary.value()); - _positionY = KeyframeGroup(yDictionary.value()); - _position = std::nullopt; - _positionInternalRepresentation = PositionInternalRepresentation::TopLevelXY; - } else if (const auto positionData = getOptionalObject(json, "p")) { - try { - LottieParsingException::Guard expectedGuard; - - _position = KeyframeGroup(positionData.value()); - _positionX = std::nullopt; - _positionX = std::nullopt; - _positionInternalRepresentation = PositionInternalRepresentation::TopLevelCombined; - } catch(...) { - auto xData = getObject(positionData.value(), "x"); - auto yData = getObject(positionData.value(), "y"); - _positionX = KeyframeGroup(xData); - _positionY = KeyframeGroup(yData); - _position = std::nullopt; - _positionInternalRepresentation = PositionInternalRepresentation::NestedXY; - _extra_positionS = getOptionalBool(positionData.value(), "s"); - } - } else { - _position = std::nullopt; - _positionX = std::nullopt; - _positionY = std::nullopt; - _positionInternalRepresentation = PositionInternalRepresentation::None; - } - } catch(...) { - throw LottieParsingException(); - } - - try { - // Scale - if (const auto scaleData = getOptionalObject(json, "s")) { - _scale = KeyframeGroup(scaleData.value()); - } - - // Rotation - if (const auto rotationZData = getOptionalObject(json, "rz")) { - _rotationZ = KeyframeGroup(rotationZData.value()); - _rotationZInternalRepresentation = RotationZInternalRepresentation::RZ; - } else if (const auto rotationData = getOptionalObject(json, "r")) { - _rotation = KeyframeGroup(rotationData.value()); - _rotationZInternalRepresentation = RotationZInternalRepresentation::R; - } - - // Opacity - if (const auto opacityData = getOptionalObject(json, "o")) { - _opacity = KeyframeGroup(opacityData.value()); - } - } catch(...) { - throw LottieParsingException(); - } - - _extraTy = getOptionalString(json, "ty"); - _extraSa = getOptionalAny(json, "sa"); - _extraSk = getOptionalAny(json, "sk"); - } - - lottiejson11::Json::object toJson() const { - lottiejson11::Json::object result; - - if (_anchorPoint.has_value()) { - result.insert(std::make_pair("a", _anchorPoint->toJson())); - } - - switch (_positionInternalRepresentation) { - case PositionInternalRepresentation::None: - assert(!_positionX.has_value()); - assert(!_positionY.has_value()); - assert(!_position.has_value()); - break; - case PositionInternalRepresentation::TopLevelXY: - assert(_positionX.has_value()); - assert(_positionY.has_value()); - assert(!_position.has_value()); - result.insert(std::make_pair("x", _positionX->toJson())); - result.insert(std::make_pair("y", _positionY->toJson())); - break; - case PositionInternalRepresentation::TopLevelCombined: - assert(_position.has_value()); - assert(!_positionX.has_value()); - assert(!_positionY.has_value()); - result.insert(std::make_pair("p", _position->toJson())); - break; - case PositionInternalRepresentation::NestedXY: - lottiejson11::Json::object nestedPosition; - assert(_positionX.has_value()); - assert(_positionY.has_value()); - assert(!_position.has_value()); - nestedPosition.insert(std::make_pair("x", _positionX->toJson())); - nestedPosition.insert(std::make_pair("y", _positionY->toJson())); - if (_extra_positionS.has_value()) { - nestedPosition.insert(std::make_pair("s", _extra_positionS.value())); - } - result.insert(std::make_pair("p", nestedPosition)); - break; - } - - if (_scale.has_value()) { - result.insert(std::make_pair("s", _scale->toJson())); - } - - if (_rotation.has_value()) { - switch (_rotationZInternalRepresentation) { - case RotationZInternalRepresentation::RZ: - result.insert(std::make_pair("rz", _rotation->toJson())); - break; - case RotationZInternalRepresentation::R: - result.insert(std::make_pair("r", _rotation->toJson())); - break; - } - } - - if (_opacity.has_value()) { - result.insert(std::make_pair("o", _opacity->toJson())); - } - - if (_extraTy.has_value()) { - result.insert(std::make_pair("ty", _extraTy.value())); - } - if (_extraSa.has_value()) { - result.insert(std::make_pair("sa", _extraSa.value())); - } - if (_extraSk.has_value()) { - result.insert(std::make_pair("sk", _extraSk.value())); - } - - return result; - } - - KeyframeGroup anchorPoint() { - if (_anchorPoint.has_value()) { - return _anchorPoint.value(); - } else { - return KeyframeGroup(Vector3D(0.0, 0.0, 0.0)); - } - } - - KeyframeGroup scale() const { - if (_scale) { - return _scale.value(); - } else { - return KeyframeGroup(Vector3D(100.0, 100.0, 100.0)); - } - } - - KeyframeGroup rotation() const { - if (_rotation) { - return _rotation.value(); - } else { - return KeyframeGroup(Vector1D(0.0)); - } - } - - KeyframeGroup opacity() const { - if (_opacity) { - return _opacity.value(); - } else { - return KeyframeGroup(Vector1D(100.0)); - } - } - - std::optional> const &position() const { - return _position; - } - - std::optional> const &positionX() const { - return _positionX; - } - - std::optional> const &positionY() const { - return _positionY; - } - -private: - /// The anchor point of the transform. - std::optional> _anchorPoint; - - /// The position of the transform. This is nil if the position data was split. - std::optional> _position; - - /// The positionX of the transform. This is nil if the position property is set. - std::optional> _positionX; - - /// The positionY of the transform. This is nil if the position property is set. - std::optional> _positionY; - - PositionInternalRepresentation _positionInternalRepresentation = PositionInternalRepresentation::None; - - /// The scale of the transform - std::optional> _scale; - - /// The rotation of the transform. Note: This is single dimensional rotation. - std::optional> _rotation; - - /// The opacity of the transform. - std::optional> _opacity; - - /// Should always be nil. - std::optional> _rotationZ; - RotationZInternalRepresentation _rotationZInternalRepresentation; - - std::optional _extra_positionS; - std::optional _extraTy; - std::optional _extraSa; - std::optional _extraSk; -}; - -} - -#endif /* Transform_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Ellipse.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Ellipse.cpp deleted file mode 100644 index 9378276f24..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Ellipse.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Ellipse.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Ellipse.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Ellipse.hpp deleted file mode 100644 index e1aff804dd..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Ellipse.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef Ellipse_hpp -#define Ellipse_hpp - -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -namespace lottie { - -enum class PathDirection: int { - Clockwise = 1, - UserSetClockwise = 2, - CounterClockwise = 3 -}; - -/// An item that define an ellipse shape -class Ellipse: public ShapeItem { -public: - explicit Ellipse(lottiejson11::Json::object const &json) noexcept(false) : - ShapeItem(json), - position(KeyframeGroup(Vector3D(0.0, 0.0, 0.0))), - size(KeyframeGroup(Vector3D(0.0, 0.0, 0.0))) { - if (const auto directionRawValue = getOptionalInt(json, "d")) { - switch (directionRawValue.value()) { - case 1: - direction = PathDirection::Clockwise; - break; - case 2: - direction = PathDirection::UserSetClockwise; - break; - case 3: - direction = PathDirection::CounterClockwise; - break; - default: - throw LottieParsingException(); - } - } - - position = KeyframeGroup(getObject(json, "p")); - size = KeyframeGroup(getObject(json, "s")); - } - - virtual ~Ellipse() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - ShapeItem::toJson(json); - - if (direction.has_value()) { - json.insert(std::make_pair("d", (int)direction.value())); - } - json.insert(std::make_pair("p", position.toJson())); - json.insert(std::make_pair("s", size.toJson())); - } - -public: - std::optional direction; - KeyframeGroup position; - KeyframeGroup size; -}; - -} - -#endif /* Ellipse_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Fill.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Fill.cpp deleted file mode 100644 index 992a25a5be..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Fill.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "Fill.hpp" - -namespace lottie { - -} - diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Fill.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Fill.hpp deleted file mode 100644 index f8139628a6..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Fill.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef Fill_hpp -#define Fill_hpp - -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#import -#include -#include "Lottie/Private/Parsing/JsonParsing.hpp" -#include - -namespace lottie { - -class Fill: public ShapeItem { -public: - explicit Fill(lottiejson11::Json::object const &json) noexcept(false) : - ShapeItem(json), - opacity(KeyframeGroup(Vector1D(0.0))), - color(KeyframeGroup(Color(0.0, 0.0, 0.0, 0.0))) { - opacity = KeyframeGroup(getObject(json, "o")); - color = KeyframeGroup(getObject(json, "c")); - - if (const auto fillRuleRawValue = getOptionalInt(json, "r")) { - switch (fillRuleRawValue.value()) { - case 0: - fillRule = FillRule::None; - break; - case 1: - fillRule = FillRule::NonZeroWinding; - break; - case 2: - fillRule = FillRule::EvenOdd; - break; - default: - throw LottieParsingException(); - } - } - - fillEnabled = getOptionalBool(json, "fillEnabled"); - } - - virtual ~Fill() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - ShapeItem::toJson(json); - - json.insert(std::make_pair("o", opacity.toJson())); - json.insert(std::make_pair("c", color.toJson())); - - if (fillRule.has_value()) { - json.insert(std::make_pair("r", (int)fillRule.value())); - } - - if (fillEnabled.has_value()) { - json.insert(std::make_pair("fillEnabled", fillEnabled.value())); - } - } - -public: - KeyframeGroup opacity; - - /// The color keyframes for the fill - KeyframeGroup color; - - std::optional fillRule; - - std::optional fillEnabled; -}; - -} - -#endif /* Fill_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/GradientFill.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/GradientFill.cpp deleted file mode 100644 index f2ed96d1b9..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/GradientFill.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "GradientFill.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/GradientFill.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/GradientFill.hpp deleted file mode 100644 index c0fecb7baf..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/GradientFill.hpp +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef GradientFill_hpp -#define GradientFill_hpp - -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" -#include "Lottie/Public/Primitives/GradientColorSet.hpp" -#include - -namespace lottie { - -/// An item that define a gradient fill -class GradientFill: public ShapeItem { -public: - explicit GradientFill(lottiejson11::Json::object const &json) noexcept(false) : - ShapeItem(json), - opacity(KeyframeGroup(Vector1D(100.0))), - startPoint(KeyframeGroup(Vector3D(0.0, 0.0, 0.0))), - endPoint(KeyframeGroup(Vector3D(0.0, 0.0, 0.0))), - gradientType(GradientType::None), - numberOfColors(0), - colors(KeyframeGroup(GradientColorSet())) { - opacity = KeyframeGroup(getObject(json, "o")); - startPoint = KeyframeGroup(getObject(json, "s")); - endPoint = KeyframeGroup(getObject(json, "e")); - - auto gradientTypeRawValue = getInt(json, "t"); - switch (gradientTypeRawValue) { - case 0: - gradientType = GradientType::None; - break; - case 1: - gradientType = GradientType::Linear; - break; - case 2: - gradientType = GradientType::Radial; - break; - default: - throw LottieParsingException(); - } - - if (const auto highlightLengthData = getOptionalObject(json, "h")) { - highlightLength = KeyframeGroup(highlightLengthData.value()); - } - if (const auto highlightAngleData = getOptionalObject(json, "a")) { - highlightAngle = KeyframeGroup(highlightAngleData.value()); - } - - auto colorsContainer = getObject(json, "g"); - numberOfColors = getInt(colorsContainer, "p"); - colors = KeyframeGroup(getObject(colorsContainer, "k")); - - rValue = getOptionalInt(json, "r"); - } - - virtual ~GradientFill() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - ShapeItem::toJson(json); - - json.insert(std::make_pair("o", opacity.toJson())); - json.insert(std::make_pair("s", startPoint.toJson())); - json.insert(std::make_pair("e", endPoint.toJson())); - json.insert(std::make_pair("t", (int)gradientType)); - - if (highlightLength.has_value()) { - json.insert(std::make_pair("h", highlightLength->toJson())); - } - if (highlightAngle.has_value()) { - json.insert(std::make_pair("a", highlightAngle->toJson())); - } - - lottiejson11::Json::object colorsContainer; - colorsContainer.insert(std::make_pair("p", numberOfColors)); - colorsContainer.insert(std::make_pair("k", colors.toJson())); - json.insert(std::make_pair("g", colorsContainer)); - - if (rValue.has_value()) { - json.insert(std::make_pair("r", rValue.value())); - } - } - -public: - /// The opacity of the fill - KeyframeGroup opacity; - - /// The start of the gradient - KeyframeGroup startPoint; - - /// The end of the gradient - KeyframeGroup endPoint; - - /// The type of gradient - GradientType gradientType; - - /// Gradient Highlight Length. Only if type is Radial - std::optional> highlightLength; - - /// Highlight Angle. Only if type is Radial - std::optional> highlightAngle; - - /// The number of color points in the gradient - int numberOfColors; - - /// The Colors of the gradient. - KeyframeGroup colors; - - std::optional rValue; -}; - -} - -#endif /* GradientFill_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/GradientStroke.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/GradientStroke.cpp deleted file mode 100644 index 465b20fde8..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/GradientStroke.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "GradientStroke.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/GradientStroke.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/GradientStroke.hpp deleted file mode 100644 index 95bed62b51..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/GradientStroke.hpp +++ /dev/null @@ -1,193 +0,0 @@ -#ifndef GradientStroke_hpp -#define GradientStroke_hpp - -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#include "Lottie/Private/Model/ShapeItems/GradientFill.hpp" -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include "Lottie/Private/Model/Objects/DashElement.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" -#include - -namespace lottie { - -/// An item that define a gradient stroke -class GradientStroke: public ShapeItem { -public: - explicit GradientStroke(lottiejson11::Json::object const &json) noexcept(false) : - ShapeItem(json), - opacity(KeyframeGroup(Vector1D(100.0))), - startPoint(KeyframeGroup(Vector3D(0.0, 0.0, 0.0))), - endPoint(KeyframeGroup(Vector3D(0.0, 0.0, 0.0))), - gradientType(GradientType::None), - numberOfColors(0), - colors(KeyframeGroup(GradientColorSet())), - width(KeyframeGroup(Vector1D(0.0))), - lineCap(LineCap::Round), - lineJoin(LineJoin::Round) { - opacity = KeyframeGroup(getObject(json, "o")); - startPoint = KeyframeGroup(getObject(json, "s")); - endPoint = KeyframeGroup(getObject(json, "e")); - - auto gradientTypeRawValue = getInt(json, "t"); - switch (gradientTypeRawValue) { - case 0: - gradientType = GradientType::None; - break; - case 1: - gradientType = GradientType::Linear; - break; - case 2: - gradientType = GradientType::Radial; - break; - default: - throw LottieParsingException(); - } - - if (const auto highlightLengthData = getOptionalObject(json, "h")) { - highlightLength = KeyframeGroup(highlightLengthData.value()); - } - if (const auto highlightAngleData = getOptionalObject(json, "a")) { - highlightAngle = KeyframeGroup(highlightAngleData.value()); - } - - width = KeyframeGroup(getObject(json, "w")); - - if (const auto lineCapRawValue = getOptionalInt(json, "lc")) { - switch (lineCapRawValue.value()) { - case 0: - lineCap = LineCap::None; - break; - case 1: - lineCap = LineCap::Butt; - break; - case 2: - lineCap = LineCap::Round; - break; - case 3: - lineCap = LineCap::Square; - break; - default: - throw LottieParsingException(); - } - } - - if (const auto lineJoinRawValue = getOptionalInt(json, "lj")) { - switch (lineJoinRawValue.value()) { - case 0: - lineJoin = LineJoin::None; - break; - case 1: - lineJoin = LineJoin::Miter; - break; - case 2: - lineJoin = LineJoin::Round; - break; - case 3: - lineJoin = LineJoin::Bevel; - break; - default: - throw LottieParsingException(); - } - } - - if (const auto miterLimitData = getOptionalDouble(json, "ml")) { - miterLimit = (float)miterLimitData.value(); - } - - auto colorsContainer = getObject(json, "g"); - numberOfColors = getInt(colorsContainer, "p"); - auto colorsData = getObject(colorsContainer, "k"); - colors = KeyframeGroup(colorsData); - - if (const auto dashElementsData = getOptionalObjectArray(json, "d")) { - dashPattern = std::vector(); - for (const auto &dashElementData : dashElementsData.value()) { - dashPattern->push_back(DashElement(dashElementData)); - } - } - } - - virtual ~GradientStroke() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - ShapeItem::toJson(json); - - json.insert(std::make_pair("o", opacity.toJson())); - json.insert(std::make_pair("s", startPoint.toJson())); - json.insert(std::make_pair("e", endPoint.toJson())); - json.insert(std::make_pair("t", (int)gradientType)); - - if (highlightLength.has_value()) { - json.insert(std::make_pair("h", highlightLength->toJson())); - } - if (highlightAngle.has_value()) { - json.insert(std::make_pair("a", highlightAngle->toJson())); - } - - json.insert(std::make_pair("w", width.toJson())); - - json.insert(std::make_pair("lc", (int)lineCap)); - json.insert(std::make_pair("lj", (int)lineJoin)); - - if (miterLimit.has_value()) { - json.insert(std::make_pair("ml", miterLimit.value())); - } - - lottiejson11::Json::object colorsContainer; - colorsContainer.insert(std::make_pair("p", numberOfColors)); - colorsContainer.insert(std::make_pair("k", colors.toJson())); - json.insert(std::make_pair("g", colorsContainer)); - - if (dashPattern.has_value()) { - lottiejson11::Json::array dashElements; - for (const auto &dashElement : dashPattern.value()) { - dashElements.push_back(dashElement.toJson()); - } - json.insert(std::make_pair("d", dashElements)); - } - } - -public: - /// The opacity of the fill - KeyframeGroup opacity; - - /// The start of the gradient - KeyframeGroup startPoint; - - /// The end of the gradient - KeyframeGroup endPoint; - - /// The type of gradient - GradientType gradientType; - - /// Gradient Highlight Length. Only if type is Radial - std::optional> highlightLength; - - /// Highlight Angle. Only if type is Radial - std::optional> highlightAngle; - - /// The number of color points in the gradient - int numberOfColors; - - /// The Colors of the gradient. - KeyframeGroup colors; - - /// The width of the stroke - KeyframeGroup width; - - /// Line Cap - LineCap lineCap; - - /// Line Join - LineJoin lineJoin; - - /// Miter Limit - std::optional miterLimit; - - /// The dash pattern of the stroke - std::optional> dashPattern; -}; - -} - -#endif /* GradientStroke_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Group.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Group.cpp deleted file mode 100644 index 89ea7daea7..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Group.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Group.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Group.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Group.hpp deleted file mode 100644 index 7bc2eb4d10..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Group.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef Group_hpp -#define Group_hpp - -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include -#include - -namespace lottie { - -/// An item that define an ellipse shape -class Group: public ShapeItem { -public: - explicit Group(lottiejson11::Json::object const &json) noexcept(false) : - ShapeItem(json) { - auto itemsData = getObjectArray(json, "it"); - for (const auto &itemData : itemsData) { - items.push_back(parseShapeItem(itemData)); - } - - numberOfProperties = getOptionalInt(json, "np"); - } - - virtual ~Group() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - ShapeItem::toJson(json); - - lottiejson11::Json::array itemArray; - for (const auto &item : items) { - lottiejson11::Json::object itemJson; - item->toJson(itemJson); - itemArray.push_back(itemJson); - } - - json.insert(std::make_pair("it", itemArray)); - - if (numberOfProperties.has_value()) { - json.insert(std::make_pair("np", numberOfProperties.value())); - } - } - -public: - /// A list of shape items. - std::vector> items; - - std::optional numberOfProperties; -}; - -} - -#endif /* Group_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Merge.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Merge.cpp deleted file mode 100644 index b22b05d1f6..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Merge.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Merge.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Merge.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Merge.hpp deleted file mode 100644 index 4f6fcc4881..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Merge.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef Merge_hpp -#define Merge_hpp - -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -namespace lottie { - -enum class MergeMode: int { - None = 0, - Merge = 1, - Add = 2, - Subtract = 3, - Intersect = 4, - Exclude = 5 -}; - -/// An item that define an ellipse shape -class Merge: public ShapeItem { -public: - explicit Merge(lottiejson11::Json::object const &json) noexcept(false) : - ShapeItem(json), - mode(MergeMode::None) { - auto modeRawValue = getInt(json, "mm"); - switch (modeRawValue) { - case 0: - mode = MergeMode::None; - break; - case 1: - mode = MergeMode::Merge; - break; - case 2: - mode = MergeMode::Add; - break; - case 3: - mode = MergeMode::Subtract; - break; - case 4: - mode = MergeMode::Intersect; - break; - case 5: - mode = MergeMode::Exclude; - break; - default: - throw LottieParsingException(); - } - } - - virtual ~Merge() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - ShapeItem::toJson(json); - - json.insert(std::make_pair("mm", (int)mode)); - } - -public: - /// The mode of the merge path - MergeMode mode; -}; - -} - -#endif /* Merge_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Rectangle.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Rectangle.cpp deleted file mode 100644 index c686130aa9..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Rectangle.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Rectangle.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Rectangle.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Rectangle.hpp deleted file mode 100644 index 67926f2e29..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Rectangle.hpp +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef Rectangle_hpp -#define Rectangle_hpp - -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#include "Lottie/Private/Model/ShapeItems/Ellipse.hpp" -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -namespace lottie { - -/// An item that define an ellipse shape -class Rectangle: public ShapeItem { -public: - explicit Rectangle(lottiejson11::Json::object const &json) noexcept(false) : - ShapeItem(json), - position(KeyframeGroup(Vector3D(0.0, 0.0, 0.0))), - size(KeyframeGroup(Vector3D(0.0, 0.0, 0.0))), - cornerRadius(KeyframeGroup(Vector1D(0.0))) { - if (const auto directionRawValue = getOptionalInt(json, "d")) { - switch (directionRawValue.value()) { - case 1: - direction = PathDirection::Clockwise; - break; - case 2: - direction = PathDirection::UserSetClockwise; - break; - case 3: - direction = PathDirection::CounterClockwise; - break; - default: - throw LottieParsingException(); - } - } - - position = KeyframeGroup(getObject(json, "p")); - size = KeyframeGroup(getObject(json, "s")); - cornerRadius = KeyframeGroup(getObject(json, "r")); - } - - virtual ~Rectangle() = default; - - explicit Rectangle( - std::optional name_, - std::optional matchName_, - std::optional expressionIndex_, - std::optional cix_, - std::optional _hidden_, - std::optional index_, - std::optional blendMode_, - std::optional layerClass_, - std::optional direction_, - KeyframeGroup position_, - KeyframeGroup size_, - KeyframeGroup cornerRadius_ - ) : - ShapeItem( - name_, - matchName_, - expressionIndex_, - cix_, - ShapeType::Rectangle, - _hidden_, - index_, - blendMode_, - layerClass_ - ), - direction(direction_), - position(position_), - size(size_), - cornerRadius(cornerRadius_) { - } - - virtual void toJson(lottiejson11::Json::object &json) const override { - ShapeItem::toJson(json); - - if (direction.has_value()) { - json.insert(std::make_pair("d", (int)direction.value())); - } - - json.insert(std::make_pair("p", position.toJson())); - json.insert(std::make_pair("s", size.toJson())); - json.insert(std::make_pair("r", cornerRadius.toJson())); - } - -public: - /// The direction of the rect. - std::optional direction; - - /// The position - KeyframeGroup position; - - /// The size - KeyframeGroup size; - - /// The Corner radius of the rectangle - KeyframeGroup cornerRadius; -}; - -} - -#endif /* Rectangle_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Repeater.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Repeater.cpp deleted file mode 100644 index 70477e31af..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Repeater.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Repeater.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Repeater.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Repeater.hpp deleted file mode 100644 index 8bb25a1c37..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Repeater.hpp +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef Repeater_hpp -#define Repeater_hpp - -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -namespace lottie { - -/// An item that define a repeater -class Repeater: public ShapeItem { -public: - explicit Repeater(lottiejson11::Json::object const &json) noexcept(false) : - ShapeItem(json) { - if (const auto copiesData = getOptionalObject(json, "c")) { - copies = KeyframeGroup(copiesData.value()); - } - if (const auto offsetData = getOptionalObject(json, "o")) { - offset = KeyframeGroup(offsetData.value()); - } - - auto transformContainer = getObject(json, "tr"); - if (const auto startOpacityData = getOptionalObject(transformContainer, "so")) { - startOpacity = KeyframeGroup(startOpacityData.value()); - } - if (const auto endOpacityData = getOptionalObject(transformContainer, "eo")) { - endOpacity = KeyframeGroup(endOpacityData.value()); - } - if (const auto rotationData = getOptionalObject(transformContainer, "r")) { - rotation = KeyframeGroup(rotationData.value()); - } - if (const auto positionData = getOptionalObject(transformContainer, "p")) { - position = KeyframeGroup(positionData.value()); - } - if (const auto scaleData = getOptionalObject(transformContainer, "s")) { - scale = KeyframeGroup(scaleData.value()); - } - } - - virtual ~Repeater() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - ShapeItem::toJson(json); - - if (copies.has_value()) { - json.insert(std::make_pair("c", copies->toJson())); - } - if (offset.has_value()) { - json.insert(std::make_pair("o", offset->toJson())); - } - - lottiejson11::Json::object transformContainer; - if (startOpacity.has_value()) { - json.insert(std::make_pair("so", startOpacity->toJson())); - } - if (endOpacity.has_value()) { - json.insert(std::make_pair("eo", endOpacity->toJson())); - } - if (rotation.has_value()) { - json.insert(std::make_pair("r", rotation->toJson())); - } - if (position.has_value()) { - json.insert(std::make_pair("p", position->toJson())); - } - if (scale.has_value()) { - json.insert(std::make_pair("s", scale->toJson())); - } - - json.insert(std::make_pair("tr", transformContainer)); - } - -public: - /// The number of copies to repeat - std::optional> copies; - - /// The offset of each copy - std::optional> offset; - - /// Start Opacity - std::optional> startOpacity; - - /// End opacity - std::optional> endOpacity; - - /// The rotation - std::optional> rotation; - - /// Anchor Point - std::optional> anchorPoint; - - /// Position - std::optional> position; - - /// Scale - std::optional> scale; -}; - -} - -#endif /* Repeater_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/RoundedRectangle.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/RoundedRectangle.cpp deleted file mode 100644 index 64cba09363..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/RoundedRectangle.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "RoundedRectangle.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/RoundedRectangle.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/RoundedRectangle.hpp deleted file mode 100644 index 548d23a32d..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/RoundedRectangle.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef RoundedRectangle_hpp -#define RoundedRectangle_hpp - -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#include "Lottie/Private/Model/ShapeItems/Ellipse.hpp" -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -namespace lottie { - -/// An item that define an ellipse shape -class RoundedRectangle: public ShapeItem { -public: - explicit RoundedRectangle(lottiejson11::Json::object const &json) noexcept(false) : - ShapeItem(json), - cornerRadius(KeyframeGroup(Vector1D(0.0))) { - if (const auto directionRawValue = getOptionalInt(json, "d")) { - switch (directionRawValue.value()) { - case 1: - direction = PathDirection::Clockwise; - break; - case 2: - direction = PathDirection::UserSetClockwise; - break; - case 3: - direction = PathDirection::CounterClockwise; - break; - default: - throw LottieParsingException(); - } - } - - if (const auto positionData = getOptionalObject(json, "p")) { - position = KeyframeGroup(positionData.value()); - } - if (const auto sizeData = getOptionalObject(json, "s")) { - size = KeyframeGroup(sizeData.value()); - } - - cornerRadius = KeyframeGroup(getObject(json, "r")); - } - - virtual ~RoundedRectangle() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - ShapeItem::toJson(json); - - if (direction.has_value()) { - json.insert(std::make_pair("d", (int)direction.value())); - } - if (position.has_value()) { - json.insert(std::make_pair("p", position->toJson())); - } - if (size.has_value()) { - json.insert(std::make_pair("s", size->toJson())); - } - - json.insert(std::make_pair("r", cornerRadius.toJson())); - } - -public: - /// The direction of the rect. - std::optional direction; - - /// The position - std::optional> position; - - /// The size - std::optional> size; - - /// The Corner radius of the rectangle - KeyframeGroup cornerRadius; -}; - -} - -#endif /* RoundedRectangle_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Shape.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Shape.cpp deleted file mode 100644 index bf5a96876c..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Shape.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Shape.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Shape.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Shape.hpp deleted file mode 100644 index 66a5a36f85..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Shape.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef Shape_hpp -#define Shape_hpp - -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#include "Lottie/Private/Model/ShapeItems/Ellipse.hpp" -#include -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include - -namespace lottie { - -/// An item that defines an custom shape -class Shape: public ShapeItem { -public: - explicit Shape(lottiejson11::Json::object const &json) noexcept(false) : - ShapeItem(json), - path(KeyframeGroup(getObject(json, "ks"))) { - if (const auto directionRawValue = getOptionalInt(json, "d")) { - switch (directionRawValue.value()) { - case 1: - direction = PathDirection::Clockwise; - break; - case 2: - direction = PathDirection::UserSetClockwise; - break; - case 3: - direction = PathDirection::CounterClockwise; - break; - default: - throw LottieParsingException(); - } - } - } - - virtual ~Shape() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - ShapeItem::toJson(json); - - json.insert(std::make_pair("ks", path.toJson())); - - if (direction.has_value()) { - json.insert(std::make_pair("d", (int)direction.value())); - } - } - -public: - KeyframeGroup path; - std::optional direction; -}; - -} - -#endif /* Shape_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/ShapeItem.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/ShapeItem.cpp deleted file mode 100644 index a47b348c29..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/ShapeItem.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "ShapeItem.hpp" - -#include "Ellipse.hpp" -#include "Fill.hpp" -#include "GradientFill.hpp" -#include "Group.hpp" -#include "GradientStroke.hpp" -#include "Merge.hpp" -#include "Rectangle.hpp" -#include "RoundedRectangle.hpp" -#include "Repeater.hpp" -#include "Shape.hpp" -#include "Star.hpp" -#include "Stroke.hpp" -#include "Trim.hpp" -#include "ShapeTransform.hpp" - -namespace lottie { - -std::shared_ptr parseShapeItem(lottiejson11::Json::object const &json) noexcept(false) { - auto typeRawValue = getString(json, "ty"); - if (typeRawValue == "el") { - return std::make_shared(json); - } else if (typeRawValue == "fl") { - return std::make_shared(json); - } else if (typeRawValue == "gf") { - return std::make_shared(json); - } else if (typeRawValue == "gr") { - return std::make_shared(json); - } else if (typeRawValue == "gs") { - return std::make_shared(json); - } else if (typeRawValue == "mm") { - return std::make_shared(json); - } else if (typeRawValue == "rc") { - return std::make_shared(json); - } else if (typeRawValue == "rp") { - return std::make_shared(json); - } else if (typeRawValue == "sh") { - return std::make_shared(json); - } else if (typeRawValue == "sr") { - return std::make_shared(json); - } else if (typeRawValue == "st") { - return std::make_shared(json); - } else if (typeRawValue == "tm") { - return std::make_shared(json); - } else if (typeRawValue == "tr") { - return std::make_shared(json); - } else if (typeRawValue == "rd") { - return std::make_shared(json); - } else { - throw LottieParsingException(); - } -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/ShapeItem.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/ShapeItem.hpp deleted file mode 100644 index 892eba1db2..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/ShapeItem.hpp +++ /dev/null @@ -1,209 +0,0 @@ -#ifndef ShapeItem_hpp -#define ShapeItem_hpp - -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include - -namespace lottie { - -enum class ShapeType { - Ellipse, - Fill, - GradientFill, - Group, - GradientStroke, - Merge, - Rectangle, - Repeater, - Shape, - Star, - Stroke, - Trim, - Transform, - RoundedRectangle -}; - -/// An item belonging to a Shape Layer -class ShapeItem { -public: - ShapeItem(lottiejson11::Json const &jsonAny) noexcept(false) : - type(ShapeType::Ellipse) { - if (!jsonAny.is_object()) { - throw LottieParsingException(); - } - - lottiejson11::Json::object const &json = jsonAny.object_items(); - - name = getOptionalString(json, "nm"); - matchName = getOptionalString(json, "mn"); - expressionIndex = getOptionalInt(json, "ix"); - cix = getOptionalInt(json, "cix"); - - index = getOptionalInt(json, "ind"); - blendMode = getOptionalInt(json, "bm"); - - auto typeRawValue = getString(json, "ty"); - if (typeRawValue == "el") { - type = ShapeType::Ellipse; - } else if (typeRawValue == "fl") { - type = ShapeType::Fill; - } else if (typeRawValue == "gf") { - type = ShapeType::GradientFill; - } else if (typeRawValue == "gr") { - type = ShapeType::Group; - } else if (typeRawValue == "gs") { - type = ShapeType::GradientStroke; - } else if (typeRawValue == "mm") { - type = ShapeType::Merge; - } else if (typeRawValue == "rc") { - type = ShapeType::Rectangle; - } else if (typeRawValue == "rp") { - type = ShapeType::Repeater; - } else if (typeRawValue == "sh") { - type = ShapeType::Shape; - } else if (typeRawValue == "sr") { - type = ShapeType::Star; - } else if (typeRawValue == "st") { - type = ShapeType::Stroke; - } else if (typeRawValue == "tm") { - type = ShapeType::Trim; - } else if (typeRawValue == "tr") { - type = ShapeType::Transform; - } else if (typeRawValue == "rd") { - type = ShapeType::RoundedRectangle; - } else { - throw LottieParsingException(); - } - - _hidden = getOptionalBool(json, "hd"); - - layerClass = getOptionalString(json, "cl"); - } - - ShapeItem( - std::optional name_, - std::optional matchName_, - std::optional expressionIndex_, - std::optional cix_, - ShapeType type_, - std::optional _hidden_, - std::optional index_, - std::optional blendMode_, - std::optional layerClass_ - ) : - name(name_), - matchName(matchName_), - expressionIndex(expressionIndex_), - cix(cix_), - type(type_), - _hidden(_hidden_), - index(index_), - blendMode(blendMode_), - layerClass(layerClass_) { - } - - ShapeItem(const ShapeItem&) = delete; - ShapeItem& operator=(ShapeItem&) = delete; - - virtual void toJson(lottiejson11::Json::object &json) const { - if (name.has_value()) { - json.insert(std::make_pair("nm", name.value())); - } - if (matchName.has_value()) { - json.insert(std::make_pair("mn", matchName.value())); - } - if (expressionIndex.has_value()) { - json.insert(std::make_pair("ix", expressionIndex.value())); - } - if (cix.has_value()) { - json.insert(std::make_pair("cix", cix.value())); - } - - if (index.has_value()) { - json.insert(std::make_pair("ind", index.value())); - } - if (blendMode.has_value()) { - json.insert(std::make_pair("bm", blendMode.value())); - } - - switch (type) { - case ShapeType::Ellipse: - json.insert(std::make_pair("ty", "el")); - break; - case ShapeType::Fill: - json.insert(std::make_pair("ty", "fl")); - break; - case ShapeType::GradientFill: - json.insert(std::make_pair("ty", "gf")); - break; - case ShapeType::Group: - json.insert(std::make_pair("ty", "gr")); - break; - case ShapeType::GradientStroke: - json.insert(std::make_pair("ty", "gs")); - break; - case ShapeType::Merge: - json.insert(std::make_pair("ty", "mm")); - break; - case ShapeType::Rectangle: - json.insert(std::make_pair("ty", "rc")); - break; - case ShapeType::RoundedRectangle: - json.insert(std::make_pair("ty", "rd")); - break; - case ShapeType::Repeater: - json.insert(std::make_pair("ty", "rp")); - break; - case ShapeType::Shape: - json.insert(std::make_pair("ty", "sh")); - break; - case ShapeType::Star: - json.insert(std::make_pair("ty", "sr")); - break; - case ShapeType::Stroke: - json.insert(std::make_pair("ty", "st")); - break; - case ShapeType::Trim: - json.insert(std::make_pair("ty", "tm")); - break; - case ShapeType::Transform: - json.insert(std::make_pair("ty", "tr")); - break; - } - - if (_hidden.has_value()) { - json.insert(std::make_pair("hd", _hidden.value())); - } - - if (layerClass.has_value()) { - json.insert(std::make_pair("cl", layerClass.value())); - } - } - - bool hidden() const { - if (_hidden.has_value()) { - return _hidden.value(); - } else { - return false; - } - } - -public: - std::optional name; - std::optional matchName; - std::optional expressionIndex; - std::optional cix; - ShapeType type; - std::optional _hidden; - std::optional index; - std::optional blendMode; - - std::optional layerClass; -}; - -std::shared_ptr parseShapeItem(lottiejson11::Json::object const &json) noexcept(false); - -} - -#endif /* ShapeItem_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/ShapeTransform.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/ShapeTransform.cpp deleted file mode 100644 index 1df07218bc..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/ShapeTransform.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "ShapeTransform.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/ShapeTransform.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/ShapeTransform.hpp deleted file mode 100644 index fcfd28a2b8..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/ShapeTransform.hpp +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef ShapeTransform_hpp -#define ShapeTransform_hpp - -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -namespace lottie { - -/// An item that define a shape transform -class ShapeTransform: public ShapeItem { -public: - explicit ShapeTransform(lottiejson11::Json::object const &json) noexcept(false) : - ShapeItem(json) { - if (const auto anchorData = getOptionalObject(json, "a")) { - anchor = KeyframeGroup(anchorData.value()); - } - if (const auto positionData = getOptionalObject(json, "p")) { - position = KeyframeGroup(positionData.value()); - } - if (const auto scaleData = getOptionalObject(json, "s")) { - scale = KeyframeGroup(scaleData.value()); - } - if (const auto rotationData = getOptionalObject(json, "r")) { - rotation = KeyframeGroup(rotationData.value()); - } - if (const auto opacityData = getOptionalObject(json, "o")) { - opacity = KeyframeGroup(opacityData.value()); - } - if (const auto skewData = getOptionalObject(json, "sk")) { - skew = KeyframeGroup(skewData.value()); - } - if (const auto skewAxisData = getOptionalObject(json, "sa")) { - skewAxis = KeyframeGroup(skewAxisData.value()); - } - } - - virtual ~ShapeTransform() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - ShapeItem::toJson(json); - - if (anchor.has_value()) { - json.insert(std::make_pair("a", anchor->toJson())); - } - if (position.has_value()) { - json.insert(std::make_pair("p", position->toJson())); - } - if (scale.has_value()) { - json.insert(std::make_pair("s", scale->toJson())); - } - if (rotation.has_value()) { - json.insert(std::make_pair("r", rotation->toJson())); - } - if (opacity.has_value()) { - json.insert(std::make_pair("o", opacity->toJson())); - } - if (skew.has_value()) { - json.insert(std::make_pair("sk", skew->toJson())); - } - if (skewAxis.has_value()) { - json.insert(std::make_pair("sa", skewAxis->toJson())); - } - } - -public: - /// Anchor Point - std::optional> anchor; - - /// Position - std::optional> position; - - /// Scale - std::optional> scale; - - /// Rotation - std::optional> rotation; - - /// opacity - std::optional> opacity; - - /// Skew - std::optional> skew; - - /// Skew Axis - std::optional> skewAxis; -}; - -} - -#endif /* ShapeTransform_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Star.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Star.cpp deleted file mode 100644 index c5f38f5946..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Star.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Star.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Star.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Star.hpp deleted file mode 100644 index c9f711526a..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Star.hpp +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef Star_hpp -#define Star_hpp - -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#include "Lottie/Private/Model/ShapeItems/Ellipse.hpp" -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include - -namespace lottie { - -enum class StarType: int { - None = 0, - Star = 1, - Polygon = 2 -}; - -/// An item that define a star shape -class Star: public ShapeItem { -public: - explicit Star(lottiejson11::Json::object const &json) noexcept(false) : - ShapeItem(json), - position(KeyframeGroup(Vector3D(0.0, 0.0, 0.0))), - outerRadius(KeyframeGroup(Vector1D(0.0))), - outerRoundness(KeyframeGroup(Vector1D(0.0))), - rotation(KeyframeGroup(Vector1D(0.0))), - points(KeyframeGroup(Vector1D(0.0))), - starType(StarType::None) { - if (const auto directionRawValue = getOptionalInt(json, "d")) { - switch (directionRawValue.value()) { - case 1: - direction = PathDirection::Clockwise; - break; - case 2: - direction = PathDirection::UserSetClockwise; - break; - case 3: - direction = PathDirection::CounterClockwise; - break; - default: - throw LottieParsingException(); - } - } - - position = KeyframeGroup(getObject(json, "p")); - outerRadius = KeyframeGroup(getObject(json, "or")); - outerRoundness = KeyframeGroup(getObject(json, "os")); - - if (const auto innerRadiusData = getOptionalObject(json, "ir")) { - innerRadius = KeyframeGroup(innerRadiusData.value()); - } - if (const auto innerRoundnessData = getOptionalObject(json, "is")) { - innerRoundness = KeyframeGroup(innerRoundnessData.value()); - } - - rotation = KeyframeGroup(getObject(json, "r")); - points = KeyframeGroup(getObject(json, "pt")); - - auto starTypeRawValue = getInt(json, "sy"); - switch (starTypeRawValue) { - case 0: - starType = StarType::None; - break; - case 1: - starType = StarType::Star; - break; - case 2: - starType = StarType::Polygon; - break; - default: - throw LottieParsingException(); - } - } - - virtual ~Star() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - ShapeItem::toJson(json); - - if (direction.has_value()) { - json.insert(std::make_pair("d", (int)direction.value())); - } - - json.insert(std::make_pair("p", position.toJson())); - json.insert(std::make_pair("or", outerRadius.toJson())); - json.insert(std::make_pair("os", outerRoundness.toJson())); - - if (innerRadius.has_value()) { - json.insert(std::make_pair("ir", innerRadius->toJson())); - } - if (innerRoundness.has_value()) { - json.insert(std::make_pair("is", innerRoundness->toJson())); - } - - json.insert(std::make_pair("r", rotation.toJson())); - json.insert(std::make_pair("pt", points.toJson())); - - json.insert(std::make_pair("sy", (int)starType)); - } - -public: - /// The direction of the star. - std::optional direction; - - /// The position of the star - KeyframeGroup position; - - /// The outer radius of the star - KeyframeGroup outerRadius; - - /// The outer roundness of the star - KeyframeGroup outerRoundness; - - /// The outer radius of the star - std::optional> innerRadius; - - /// The outer roundness of the star - std::optional> innerRoundness; - - /// The rotation of the star - KeyframeGroup rotation; - - /// The number of points on the star - KeyframeGroup points; - - /// The type of star - StarType starType; -}; - -} - -#endif /* Star_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Stroke.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Stroke.cpp deleted file mode 100644 index 0c858f2442..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Stroke.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Stroke.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Stroke.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Stroke.hpp deleted file mode 100644 index e306fcd6a6..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Stroke.hpp +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef Stroke_hpp -#define Stroke_hpp - -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#include "Lottie/Private/Model/ShapeItems/GradientStroke.hpp" -#import -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include "Lottie/Private/Model/Objects/DashElement.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include - -namespace lottie { - -/// An item that define an ellipse shape -class Stroke: public ShapeItem { -public: - explicit Stroke(lottiejson11::Json::object const &json) noexcept(false) : - ShapeItem(json), - opacity(KeyframeGroup(Vector1D(100.0))), - color(KeyframeGroup(Color(0.0, 0.0, 0.0, 0.0))), - width(KeyframeGroup(Vector1D(0.0))), - lineCap(LineCap::Round), - lineJoin(LineJoin::Round) { - opacity = KeyframeGroup(getObject(json, "o")); - color = KeyframeGroup(getObject(json, "c")); - width = KeyframeGroup(getObject(json, "w")); - - if (const auto lineCapRawValue = getOptionalInt(json, "lc")) { - switch (lineCapRawValue.value()) { - case 0: - lineCap = LineCap::None; - break; - case 1: - lineCap = LineCap::Butt; - break; - case 2: - lineCap = LineCap::Round; - break; - case 3: - lineCap = LineCap::Square; - break; - default: - throw LottieParsingException(); - } - } - - if (const auto lineJoinRawValue = getOptionalInt(json, "lj")) { - switch (lineJoinRawValue.value()) { - case 0: - lineJoin = LineJoin::None; - break; - case 1: - lineJoin = LineJoin::Miter; - break; - case 2: - lineJoin = LineJoin::Round; - break; - case 3: - lineJoin = LineJoin::Bevel; - break; - default: - throw LottieParsingException(); - } - } - - if (const auto miterLimitData = getOptionalDouble(json, "ml")) { - miterLimit = (float)miterLimitData.value(); - } - - if (const auto dashElementsData = getOptionalObjectArray(json, "d")) { - dashPattern = std::vector(); - for (const auto &dashElementData : dashElementsData.value()) { - dashPattern->push_back(DashElement(dashElementData)); - } - } - - fillEnabled = getOptionalBool(json, "fillEnabled"); - ml2 = getOptionalAny(json, "ml2"); - } - - virtual ~Stroke() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - ShapeItem::toJson(json); - - json.insert(std::make_pair("o", opacity.toJson())); - json.insert(std::make_pair("c", color.toJson())); - json.insert(std::make_pair("w", width.toJson())); - - json.insert(std::make_pair("lc", (int)lineCap)); - json.insert(std::make_pair("lj", (int)lineJoin)); - - if (miterLimit.has_value()) { - json.insert(std::make_pair("ml", miterLimit.value())); - } - - if (dashPattern.has_value()) { - lottiejson11::Json::array dashElements; - for (const auto &dashElement : dashPattern.value()) { - dashElements.push_back(dashElement.toJson()); - } - json.insert(std::make_pair("d", dashElements)); - } - - if (fillEnabled.has_value()) { - json.insert(std::make_pair("fillEnabled", fillEnabled.value())); - } - if (ml2.has_value()) { - json.insert(std::make_pair("ml2", ml2.value())); - } - } - -public: - /// The opacity of the stroke - KeyframeGroup opacity; - - /// The Color of the stroke - KeyframeGroup color; - - /// The width of the stroke - KeyframeGroup width; - - /// Line Cap - LineCap lineCap; - - /// Line Join - LineJoin lineJoin; - - /// Miter Limit - std::optional miterLimit; - - /// The dash pattern of the stroke - std::optional> dashPattern; - - std::optional fillEnabled; - std::optional ml2; -}; - -} - -#endif /* Stroke_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Trim.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Trim.cpp deleted file mode 100644 index 85f95d8b0c..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Trim.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Trim.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Trim.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Trim.hpp deleted file mode 100644 index e4628d604a..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/ShapeItems/Trim.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef Trim_hpp -#define Trim_hpp - -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -namespace lottie { - -/// An item that defines trim -class Trim: public ShapeItem { -public: - explicit Trim(lottiejson11::Json::object const &json) noexcept(false) : - ShapeItem(json), - start(KeyframeGroup(Vector1D(0.0))), - end(KeyframeGroup(Vector1D(0.0))), - offset(KeyframeGroup(Vector1D(0.0))), - trimType(TrimType::Simultaneously) { - start = KeyframeGroup(getObject(json, "s")); - end = KeyframeGroup(getObject(json, "e")); - offset = KeyframeGroup(getObject(json, "o")); - - auto trimTypeRawValue = getInt(json, "m"); - switch (trimTypeRawValue) { - case 1: - trimType = TrimType::Simultaneously; - break; - case 2: - trimType = TrimType::Individually; - break; - default: - throw LottieParsingException(); - } - } - - virtual ~Trim() = default; - - virtual void toJson(lottiejson11::Json::object &json) const override { - ShapeItem::toJson(json); - - json.insert(std::make_pair("s", start.toJson())); - json.insert(std::make_pair("e", end.toJson())); - json.insert(std::make_pair("o", offset.toJson())); - json.insert(std::make_pair("m", (int)trimType)); - } - -public: - KeyframeGroup start; - KeyframeGroup end; - KeyframeGroup offset; - TrimType trimType; -}; - -} - -#endif /* Trim_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/Font.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/Font.cpp deleted file mode 100644 index 7dfd91b3cc..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/Font.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Font.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/Font.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/Font.hpp deleted file mode 100644 index b321983e71..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/Font.hpp +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef Font_hpp -#define Font_hpp - -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include -#include - -namespace lottie { - -class Font { -public: - Font( - std::string const &name_, - std::string const &familyName_, - std::string const &style_, - float ascent_ - ) : - name(name_), - familyName(familyName_), - style(style_), - ascent(ascent_) { - } - - explicit Font(lottiejson11::Json::object const &json) noexcept(false) { - name = getString(json, "fName"); - familyName = getString(json, "fFamily"); - path = getOptionalString(json, "fPath"); - weight = getOptionalString(json, "fWeight"); - fontClass = getOptionalString(json, "fClass"); - style = getString(json, "fStyle"); - ascent = (float)getDouble(json, "ascent"); - origin = getOptionalInt(json, "origin"); - } - - lottiejson11::Json::object toJson() const { - lottiejson11::Json::object result; - - result.insert(std::make_pair("fName", name)); - result.insert(std::make_pair("fFamily", familyName)); - if (path.has_value()) { - result.insert(std::make_pair("fPath", path.value())); - } - if (weight.has_value()) { - result.insert(std::make_pair("fWeight", weight.value())); - } - if (fontClass.has_value()) { - result.insert(std::make_pair("fClass", fontClass.value())); - } - result.insert(std::make_pair("fStyle", style)); - result.insert(std::make_pair("ascent", ascent)); - if (origin.has_value()) { - result.insert(std::make_pair("origin", origin.value())); - } - - return result; - } - -public: - std::string name; - std::string familyName; - std::optional path; - std::optional weight; - std::optional fontClass; - std::string style; - float ascent; - std::optional origin; -}; - -/// A list of fonts -class FontList { -public: - FontList(std::vector const &fonts_) : - fonts(fonts_) { - } - - explicit FontList(lottiejson11::Json::object const &json) noexcept(false) { - if (const auto fontsData = getOptionalObjectArray(json, "list")) { - for (const auto &fontData : fontsData.value()) { - fonts.emplace_back(fontData); - } - } - } - - lottiejson11::Json::object toJson() const { - lottiejson11::Json::array fontArray; - - for (const auto &font : fonts) { - fontArray.push_back(font.toJson()); - } - - lottiejson11::Json::object result; - result.insert(std::make_pair("list", fontArray)); - return result; - } - -public: - std::vector fonts; -}; - -} - -#endif /* Font_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/Glyph.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/Glyph.cpp deleted file mode 100644 index 071050db7a..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/Glyph.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Glyph.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/Glyph.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/Glyph.hpp deleted file mode 100644 index d5c1522850..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/Glyph.hpp +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef Glyph_hpp -#define Glyph_hpp - -#include "Lottie/Private/Model/ShapeItems/ShapeItem.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include -#include - -namespace lottie { - -class Glyph { -public: - Glyph( - std::string const &character_, - float fontSize_, - std::string const &fontFamily_, - std::string const &fontStyle_, - float width_, - std::optional>> shapes_ - ) : - character(character_), - fontSize(fontSize_), - fontFamily(fontFamily_), - fontStyle(fontStyle_), - width(width_), - shapes(shapes_) { - } - - explicit Glyph(lottiejson11::Json::object const &json) noexcept(false) : - character(""), - fontSize(0.0), - fontFamily(""), - fontStyle(""), - width(0.0) { - character = getString(json, "ch"); - fontSize = (float)getDouble(json, "size"); - fontFamily = getString(json, "fFamily"); - fontStyle = getString(json, "style"); - width = (float)getDouble(json, "w"); - - if (const auto shapeContainer = getOptionalObject(json, "data")) { - internalHasData = true; - - if (const auto shapesData = getOptionalObjectArray(shapeContainer.value(), "shapes")) { - shapes = std::vector>(); - - for (const auto &shapeData : shapesData.value()) { - shapes->push_back(parseShapeItem(shapeData)); - } - } - } - } - - lottiejson11::Json::object toJson() const { - lottiejson11::Json::object result; - - result.insert(std::make_pair("ch", character)); - result.insert(std::make_pair("size", fontSize)); - result.insert(std::make_pair("fFamily", fontFamily)); - result.insert(std::make_pair("style", fontStyle)); - result.insert(std::make_pair("w", width)); - - if (internalHasData || shapes.has_value()) { - lottiejson11::Json::object shapeContainer; - - if (shapes.has_value()) { - lottiejson11::Json::array shapeArray; - - for (const auto &shape : shapes.value()) { - lottiejson11::Json::object shapeJson; - shape->toJson(shapeJson); - shapeArray.push_back(shapeJson); - } - - shapeContainer.insert(std::make_pair("shapes", shapeArray)); - } - result.insert(std::make_pair("data", shapeContainer)); - } - - return result; - } - -public: - /// The character - std::string character; - - /// The font size of the character - float fontSize; - - /// The font family of the character - std::string fontFamily; - - /// The Style of the character - std::string fontStyle; - - /// The Width of the character - float width; - - /// The Shape Data of the Character - std::optional>> shapes; - - bool internalHasData = false; -}; - -} - -#endif /* Glyph_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/TextAnimator.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/TextAnimator.cpp deleted file mode 100644 index 7cd9b25715..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/TextAnimator.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "TextAnimator.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/TextAnimator.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/TextAnimator.hpp deleted file mode 100644 index 6724c7e3fa..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/TextAnimator.hpp +++ /dev/null @@ -1,183 +0,0 @@ -#ifndef TextAnimator_hpp -#define TextAnimator_hpp - -#include -#import -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include -#include - -namespace lottie { - -class TextAnimator { -public: - TextAnimator( - std::optional &name_, - std::optional> anchor_, - std::optional> position_, - std::optional> scale_, - std::optional> skew_, - std::optional> skewAxis_, - std::optional> rotation_, - std::optional> opacity_, - std::optional> strokeColor_, - std::optional> fillColor_, - std::optional> strokeWidth_, - std::optional> tracking_ - ) : - name(name_), - anchor(anchor_), - position(position_), - scale(scale_), - skew(skew_), - skewAxis(skewAxis_), - rotation(rotation_), - opacity(opacity_), - strokeColor(strokeColor_), - fillColor(fillColor_), - strokeWidth(strokeWidth_), - tracking(tracking_) { - } - - explicit TextAnimator(lottiejson11::Json const &jsonAny) { - if (!jsonAny.is_object()) { - throw LottieParsingException(); - } - lottiejson11::Json::object const &json = jsonAny.object_items(); - - if (const auto nameData = getOptionalString(json, "nm")) { - name = nameData.value(); - } - _extraS = getOptionalAny(json, "s"); - - lottiejson11::Json::object const &animatorContainer = getObject(json, "a"); - - if (const auto fillColorData = getOptionalObject(animatorContainer, "fc")) { - fillColor = KeyframeGroup(fillColorData.value()); - } - if (const auto strokeColorData = getOptionalObject(animatorContainer, "sc")) { - strokeColor = KeyframeGroup(strokeColorData.value()); - } - if (const auto strokeWidthData = getOptionalObject(animatorContainer, "sw")) { - strokeWidth = KeyframeGroup(strokeWidthData.value()); - } - if (const auto trackingData = getOptionalObject(animatorContainer, "t")) { - tracking = KeyframeGroup(trackingData.value()); - } - if (const auto anchorData = getOptionalObject(animatorContainer, "a")) { - anchor = KeyframeGroup(anchorData.value()); - } - if (const auto positionData = getOptionalObject(animatorContainer, "p")) { - position = KeyframeGroup(positionData.value()); - } - if (const auto scaleData = getOptionalObject(animatorContainer, "s")) { - scale = KeyframeGroup(scaleData.value()); - } - if (const auto skewData = getOptionalObject(animatorContainer, "sk")) { - skew = KeyframeGroup(skewData.value()); - } - if (const auto skewAxisData = getOptionalObject(animatorContainer, "sa")) { - skewAxis = KeyframeGroup(skewAxisData.value()); - } - if (const auto rotationData = getOptionalObject(animatorContainer, "r")) { - rotation = KeyframeGroup(rotationData.value()); - } - if (const auto opacityData = getOptionalObject(animatorContainer, "o")) { - opacity = KeyframeGroup(opacityData.value()); - } - } - - lottiejson11::Json::object toJson() const { - lottiejson11::Json::object animatorContainer; - - if (fillColor.has_value()) { - animatorContainer.insert(std::make_pair("fc", fillColor->toJson())); - } - if (strokeColor.has_value()) { - animatorContainer.insert(std::make_pair("sc", strokeColor->toJson())); - } - if (strokeWidth.has_value()) { - animatorContainer.insert(std::make_pair("sw", strokeWidth->toJson())); - } - if (tracking.has_value()) { - animatorContainer.insert(std::make_pair("t", tracking->toJson())); - } - if (anchor.has_value()) { - animatorContainer.insert(std::make_pair("a", anchor->toJson())); - } - if (position.has_value()) { - animatorContainer.insert(std::make_pair("p", position->toJson())); - } - if (scale.has_value()) { - animatorContainer.insert(std::make_pair("s", scale->toJson())); - } - if (skew.has_value()) { - animatorContainer.insert(std::make_pair("sk", skew->toJson())); - } - if (skewAxis.has_value()) { - animatorContainer.insert(std::make_pair("sa", skewAxis->toJson())); - } - if (rotation.has_value()) { - animatorContainer.insert(std::make_pair("r", rotation->toJson())); - } - if (opacity.has_value()) { - animatorContainer.insert(std::make_pair("o", opacity->toJson())); - } - - lottiejson11::Json::object result; - result.insert(std::make_pair("a", animatorContainer)); - - if (name.has_value()) { - result.insert(std::make_pair("nm", name.value())); - } - if (_extraS.has_value()) { - result.insert(std::make_pair("s", _extraS.value())); - } - - return result; - } - -public: - std::optional name; - - /// Anchor - std::optional> anchor; - - /// Position - std::optional> position; - - /// Scale - std::optional> scale; - - /// Skew - std::optional> skew; - - /// Skew Axis - std::optional> skewAxis; - - /// Rotation - std::optional> rotation; - - /// Opacity - std::optional> opacity; - - /// Stroke Color - std::optional> strokeColor; - - /// Fill Color - std::optional> fillColor; - - /// Stroke Width - std::optional> strokeWidth; - - /// Tracking - std::optional> tracking; - - std::optional _extraS; -}; - -} - -#endif /* TextAnimator_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/TextDocument.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/TextDocument.cpp deleted file mode 100644 index 95c3be2b67..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/TextDocument.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "TextDocument.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/TextDocument.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/TextDocument.hpp deleted file mode 100644 index 83ea39ebcc..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Model/Text/TextDocument.hpp +++ /dev/null @@ -1,190 +0,0 @@ -#ifndef TextDocument_hpp -#define TextDocument_hpp - -#include -#import -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include -#include - -namespace lottie { - -enum class TextJustification: int { - Left = 0, - Right = 1, - Center = 2 -}; - -class TextDocument { -public: - TextDocument( - std::string const &text_, - float fontSize_, - std::string const &fontFamily_, - TextJustification justification_, - int tracking_, - float lineHeight_, - std::optional baseline_, - std::optional fillColorData_, - std::optional strokeColorData_, - std::optional strokeWidth_, - std::optional strokeOverFill_, - std::optional textFramePosition_, - std::optional textFrameSize_ - ) : - text(text_), - fontSize(fontSize_), - fontFamily(fontFamily_), - justification(justification_), - tracking(tracking_), - lineHeight(lineHeight_), - baseline(baseline_), - fillColorData(fillColorData_), - strokeColorData(strokeColorData_), - strokeWidth(strokeWidth_), - strokeOverFill(strokeOverFill_), - textFramePosition(textFramePosition_), - textFrameSize(textFrameSize_) { - } - - explicit TextDocument(lottiejson11::Json const &jsonAny) noexcept(false) : - text(""), - fontSize(0.0), - fontFamily(""), - justification(TextJustification::Left), - tracking(0), - lineHeight(0.0) { - if (!jsonAny.is_object()) { - throw LottieParsingException(); - } - - lottiejson11::Json::object const &json = jsonAny.object_items(); - - text = getString(json, "t"); - fontSize = (float)getDouble(json, "s"); - fontFamily = getString(json, "f"); - - auto justificationRawValue = getInt(json, "j"); - switch (justificationRawValue) { - case 0: - justification = TextJustification::Left; - break; - case 1: - justification = TextJustification::Right; - break; - case 2: - justification = TextJustification::Center; - break; - default: - throw LottieParsingException(); - } - - tracking = getInt(json, "tr"); - lineHeight = (float)getDouble(json, "lh"); - if (const auto baselineValue = getOptionalDouble(json, "ls")) { - baseline = (float)baselineValue.value(); - } - - if (const auto fillColorDataValue = getOptionalAny(json, "fc")) { - fillColorData = Color(fillColorDataValue.value()); - } - - if (const auto strokeColorDataValue = getOptionalAny(json, "sc")) { - strokeColorData = Color(strokeColorDataValue.value()); - } - - if (const auto strokeWidthValue = getOptionalDouble(json, "sw")) { - strokeWidth = (float)strokeWidthValue.value(); - } - if (const auto strokeOverFillValue = getOptionalBool(json, "of")) { - strokeOverFill = (float)strokeOverFillValue.value(); - } - - if (const auto textFramePositionData = getOptionalAny(json, "ps")) { - textFramePosition = Vector3D(textFramePositionData.value()); - } - if (const auto textFrameSizeData = getOptionalAny(json, "sz")) { - textFrameSize = Vector3D(textFrameSizeData.value()); - } - } - - lottiejson11::Json::object toJson() const { - lottiejson11::Json::object result; - - result.insert(std::make_pair("t", text)); - result.insert(std::make_pair("s", fontSize)); - result.insert(std::make_pair("f", fontFamily)); - result.insert(std::make_pair("j", (int)justification)); - result.insert(std::make_pair("tr", tracking)); - result.insert(std::make_pair("lh", lineHeight)); - - if (baseline.has_value()) { - result.insert(std::make_pair("ls", baseline.value())); - } - - if (fillColorData.has_value()) { - result.insert(std::make_pair("fc", fillColorData->toJson())); - } - if (strokeColorData.has_value()) { - result.insert(std::make_pair("sc", strokeColorData->toJson())); - } - - if (strokeWidth.has_value()) { - result.insert(std::make_pair("sw", strokeWidth.value())); - } - if (strokeOverFill.has_value()) { - result.insert(std::make_pair("of", strokeOverFill.value())); - } - if (textFramePosition.has_value()) { - result.insert(std::make_pair("ps", textFramePosition->toJson())); - } - if (textFrameSize.has_value()) { - result.insert(std::make_pair("sz", textFrameSize->toJson())); - } - - return result; - } - -public: - /// The Text - std::string text; - - /// The Font size - float fontSize; - - /// The Font Family - std::string fontFamily; - - /// Justification - TextJustification justification; - - /// Tracking - int tracking; - - /// Line Height - float lineHeight; - - /// Baseline - std::optional baseline; - - /// Fill Color data - std::optional fillColorData; - - /// Scroke Color data - std::optional strokeColorData; - - /// Stroke Width - std::optional strokeWidth; - - /// Stroke Over Fill - std::optional strokeOverFill; - - std::optional textFramePosition; - - std::optional textFrameSize; -}; - -} - -#endif /* TextDocument_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Parsing/JsonParsing.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Parsing/JsonParsing.cpp deleted file mode 100644 index f72968be59..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Parsing/JsonParsing.cpp +++ /dev/null @@ -1,219 +0,0 @@ -#include "JsonParsing.hpp" - -#include - -namespace lottie { - -thread_local int isExceptionExpectedLevel = 0; - -LottieParsingException::Guard::Guard() { - assert(isExceptionExpectedLevel >= 0); - isExceptionExpectedLevel++; -} - -LottieParsingException::Guard::~Guard() { - assert(isExceptionExpectedLevel - 1 >= 0); - isExceptionExpectedLevel--; -} - -LottieParsingException::LottieParsingException() { - if (isExceptionExpectedLevel == 0) { - assert(true); - } -} - -const char* LottieParsingException::what() const throw() { - return "Lottie parsing exception"; -} - -lottiejson11::Json getAny(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - throw LottieParsingException(); - } - return value->second; -} - -std::optional getOptionalAny(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - return std::nullopt; - } - return value->second; -} - -lottiejson11::Json::object getObject(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - throw LottieParsingException(); - } - if (!value->second.is_object()) { - throw LottieParsingException(); - } - return value->second.object_items(); -} - -std::optional getOptionalObject(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - return std::nullopt; - } - if (!value->second.is_object()) { - throw LottieParsingException(); - } - return value->second.object_items(); -} - -std::vector getObjectArray(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - throw LottieParsingException(); - } - if (!value->second.is_array()) { - throw LottieParsingException(); - } - - std::vector result; - for (const auto &item : value->second.array_items()) { - if (!item.is_object()) { - throw LottieParsingException(); - } - result.push_back(item.object_items()); - } - - return result; -} - -std::optional> getOptionalObjectArray(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - return std::nullopt; - } - if (!value->second.is_array()) { - throw LottieParsingException(); - } - - std::vector result; - for (const auto &item : value->second.array_items()) { - if (!item.is_object()) { - throw LottieParsingException(); - } - result.push_back(item.object_items()); - } - - return result; -} - -std::vector getAnyArray(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - throw LottieParsingException(); - } - if (!value->second.is_array()) { - throw LottieParsingException(); - } - - return value->second.array_items(); -} - -std::optional> getOptionalAnyArray(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - throw std::nullopt; - } - if (!value->second.is_array()) { - throw LottieParsingException(); - } - - return value->second.array_items(); -} - -std::string getString(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - throw LottieParsingException(); - } - if (!value->second.is_string()) { - throw LottieParsingException(); - } - return value->second.string_value(); -} - -std::optional getOptionalString(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - return std::nullopt; - } - if (!value->second.is_string()) { - throw LottieParsingException(); - } - return value->second.string_value(); -} - -int32_t getInt(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - throw LottieParsingException(); - } - if (!value->second.is_number()) { - throw LottieParsingException(); - } - return value->second.int_value(); -} - -std::optional getOptionalInt(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - return std::nullopt; - } - if (!value->second.is_number()) { - throw LottieParsingException(); - } - return value->second.int_value(); -} - -double getDouble(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - throw LottieParsingException(); - } - if (!value->second.is_number()) { - throw LottieParsingException(); - } - return value->second.number_value(); -} - -std::optional getOptionalDouble(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - return std::nullopt; - } - if (!value->second.is_number()) { - throw LottieParsingException(); - } - return value->second.number_value(); -} - -bool getBool(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - throw LottieParsingException(); - } - if (!value->second.is_bool()) { - throw LottieParsingException(); - } - return value->second.bool_value(); -} - -std::optional getOptionalBool(lottiejson11::Json::object const &object, std::string const &key) noexcept(false) { - auto value = object.find(key); - if (value == object.end()) { - return std::nullopt; - } - if (!value->second.is_bool()) { - throw LottieParsingException(); - } - return value->second.bool_value(); -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Parsing/JsonParsing.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Parsing/JsonParsing.hpp deleted file mode 100644 index a0bd7951b3..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Parsing/JsonParsing.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef JsonParsing_hpp -#define JsonParsing_hpp - -#include - -#include -#include -#include - -namespace lottie { - -class LottieParsingException: public std::exception { -public: - class Guard { - public: - Guard(); - ~Guard(); - }; - -public: - LottieParsingException(); - - virtual const char* what() const throw(); -}; - -lottiejson11::Json getAny(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); -std::optional getOptionalAny(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); - -lottiejson11::Json::object getObject(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); -std::optional getOptionalObject(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); - -std::vector getObjectArray(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); -std::optional> getOptionalObjectArray(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); - -std::vector getAnyArray(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); -std::optional> getOptionalAnyArray(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); - -std::string getString(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); -std::optional getOptionalString(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); - -int32_t getInt(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); -std::optional getOptionalInt(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); - -double getDouble(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); -std::optional getOptionalDouble(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); - -bool getBool(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); -std::optional getOptionalBool(lottiejson11::Json::object const &object, std::string const &key) noexcept(false); - -} - -#endif /* JsonParsing_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/BezierPath.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/BezierPath.cpp deleted file mode 100644 index f73b382dc1..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/BezierPath.cpp +++ /dev/null @@ -1,732 +0,0 @@ -#include - -#include -#include - -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -namespace lottie { - -BezierTrimPathPosition::BezierTrimPathPosition(float start_, float end_) : -start(start_), -end(end_) { -} - -BezierPathContents::BezierPathContents(CurveVertex const &startPoint) : -elements({ PathElement(startPoint) }) { -} - -BezierPathContents::BezierPathContents() : -elements({}), -closed(false) { -} - -BezierPathContents::BezierPathContents(lottiejson11::Json const &jsonAny) noexcept(false) : -elements({}) { - lottiejson11::Json::object const *json = nullptr; - if (jsonAny.is_object()) { - json = &jsonAny.object_items(); - } else if (jsonAny.is_array()) { - if (jsonAny.array_items().empty()) { - throw LottieParsingException(); - } - if (!jsonAny.array_items()[0].is_object()) { - throw LottieParsingException(); - } - json = &jsonAny.array_items()[0].object_items(); - } - - if (const auto closedData = getOptionalBool(*json, "c")) { - closed = closedData.value(); - } - - auto vertexContainer = getAnyArray(*json, "v"); - auto inPointsContainer = getAnyArray(*json, "i"); - auto outPointsContainer = getAnyArray(*json, "o"); - - if (vertexContainer.size() != inPointsContainer.size() || inPointsContainer.size() != outPointsContainer.size()) { - throw LottieParsingException(); - } - if (vertexContainer.empty()) { - return; - } - - /// Create first point - Vector2D firstPoint = Vector2D(vertexContainer[0]); - Vector2D firstInPoint = Vector2D(inPointsContainer[0]); - Vector2D firstOutPoint = Vector2D(outPointsContainer[0]); - CurveVertex firstVertex = CurveVertex::relative( - firstPoint, - firstInPoint, - firstOutPoint - ); - PathElement previousElement(firstVertex); - elements.push_back(previousElement); - - for (size_t i = 1; i < vertexContainer.size(); i++) { - Vector2D point = Vector2D(vertexContainer[i]); - Vector2D inPoint = Vector2D(inPointsContainer[i]); - Vector2D outPoint = Vector2D(outPointsContainer[i]); - CurveVertex vertex = CurveVertex::relative( - point, - inPoint, - outPoint - ); - auto pathElement = previousElement.pathElementTo(vertex); - elements.push_back(pathElement); - previousElement = pathElement; - } - - if (closed.value_or(false)) { - auto closeElement = previousElement.pathElementTo(firstVertex); - elements.push_back(closeElement); - } -} - -lottiejson11::Json BezierPathContents::toJson() const { - lottiejson11::Json::object result; - - lottiejson11::Json::array vertices; - lottiejson11::Json::array inPoints; - lottiejson11::Json::array outPoints; - - for (const auto &element : elements) { - vertices.push_back(element.vertex.point.toJson()); - inPoints.push_back(element.vertex.inTangentRelative().toJson()); - outPoints.push_back(element.vertex.outTangentRelative().toJson()); - } - - result.insert(std::make_pair("v", vertices)); - result.insert(std::make_pair("i", inPoints)); - result.insert(std::make_pair("o", outPoints)); - - if (closed.has_value()) { - result.insert(std::make_pair("c", closed.value())); - } - - return lottiejson11::Json(result); -} - -std::shared_ptr BezierPathContents::cgPath() const { - auto cgPath = CGPath::makePath(); - - std::optional previousElement; - for (const auto &element : elements) { - if (previousElement.has_value()) { - if (previousElement->vertex.outTangentRelative().isZero() && element.vertex.inTangentRelative().isZero()) { - cgPath->addLineTo(element.vertex.point); - } else { - cgPath->addCurveTo(element.vertex.point, previousElement->vertex.outTangent, element.vertex.inTangent); - } - } else { - cgPath->moveTo(element.vertex.point); - } - previousElement = element; - } - if (closed.value_or(true)) { - cgPath->closeSubpath(); - } - return cgPath; -} - -float BezierPathContents::length() { - if (_length.has_value()) { - return _length.value(); - } else { - float result = 0.0; - for (size_t i = 1; i < elements.size(); i++) { - result += elements[i].length(elements[i - 1]); - } - _length = result; - return result; - } -} - -void BezierPathContents::moveToStartPoint(CurveVertex const &vertex) { - elements = { PathElement(vertex) }; - _length = std::nullopt; -} - -void BezierPathContents::addVertex(CurveVertex const &vertex) { - addElement(PathElement(vertex)); -} - -void BezierPathContents::reserveCapacity(size_t capacity) { - elements.reserve(capacity); -} - -void BezierPathContents::setElementCount(size_t count) { - elements.resize(count, PathElement(CurveVertex::absolute(Vector2D(0.0, 0.0), Vector2D(0.0, 0.0), Vector2D(0.0, 0.0)))); -} - -void BezierPathContents::invalidateLength() { - _length.reset(); -} - -void BezierPathContents::addCurve(Vector2D const &toPoint, Vector2D const &outTangent, Vector2D const &inTangent) { - if (elements.empty()) { - return; - } - auto previous = elements[elements.size() - 1]; - auto newVertex = CurveVertex::absolute(toPoint, inTangent, toPoint); - updateVertex( - CurveVertex::absolute(previous.vertex.point, previous.vertex.inTangent, outTangent), - (int)elements.size() - 1, - false - ); - addVertex(newVertex); -} - -void BezierPathContents::addLine(Vector2D const &toPoint) { - if (elements.empty()) { - return; - } - auto previous = elements[elements.size() - 1]; - auto newVertex = CurveVertex::relative(toPoint, Vector2D::Zero(), Vector2D::Zero()); - updateVertex( - CurveVertex::absolute(previous.vertex.point, previous.vertex.inTangent, previous.vertex.point), - (int)elements.size() - 1, - false - ); - addVertex(newVertex); -} - -void BezierPathContents::close() { - closed = true; -} - -void BezierPathContents::addElement(PathElement const &pathElement) { - elements.push_back(pathElement); -} - -void BezierPathContents::updateVertex(CurveVertex const &vertex, int atIndex, bool remeasure) { - if (remeasure) { - PathElement newElement(CurveVertex::absolute(Vector2D::Zero(), Vector2D::Zero(), Vector2D::Zero())); - if (atIndex > 0) { - auto previousElement = elements[atIndex - 1]; - newElement = previousElement.pathElementTo(vertex); - } else { - newElement = PathElement(vertex); - } - elements[atIndex] = newElement; - - if (atIndex + 1 < elements.size()) { - auto nextElement = elements[atIndex + 1]; - elements[atIndex + 1] = newElement.pathElementTo(nextElement.vertex); - } - - } else { - auto oldElement = elements[atIndex]; - elements[atIndex] = oldElement.updateVertex(vertex); - } -} - -std::vector> BezierPathContents::trim(float fromLength, float toLength, float offsetLength) { - if (elements.size() <= 1) { - return {}; - } - - if (fromLength == toLength) { - return {}; - } - - float lengthValue = length(); - - /// Normalize lengths to the curve length. - auto start = fmod(fromLength + offsetLength, lengthValue); - auto end = fmod(toLength + offsetLength, lengthValue); - - if (start < 0.0) { - start = lengthValue + start; - } - - if (end < 0.0) { - end = lengthValue + end; - } - - if (start == lengthValue) { - start = 0.0; - } - if (end == 0.0) { - end = lengthValue; - } - - if ( - (start == 0.0 && end == lengthValue) || - start == end || - (start == lengthValue && end == 0.0) - ) { - /// The trim encompasses the entire path. Return. - return { shared_from_this() }; - } - - if (start > end) { - // Start is greater than end. Two paths are returned. - return trimPathAtLengths({ - BezierTrimPathPosition(0.0, end), - BezierTrimPathPosition(start, lengthValue) - }); - } - - return trimPathAtLengths({ BezierTrimPathPosition(start, end) }); -} - -// MARK: Private - -std::vector> BezierPathContents::trimPathAtLengths(std::vector const &positions) { - if (positions.empty()) { - return {}; - } - auto remainingPositions = positions; - - auto trim = remainingPositions[0]; - remainingPositions.erase(remainingPositions.begin()); - - std::vector> paths; - - float runningLength = 0.0; - bool finishedTrimming = false; - auto pathElements = elements; - - auto currentPath = std::make_shared(); - int i = 0; - - while (!finishedTrimming) { - if (pathElements.size() <= i) { - /// Do this for rounding errors - paths.push_back(currentPath); - finishedTrimming = true; - continue; - } - /// Loop through and add elements within start->end range. - /// Get current element - auto element = pathElements[i]; - float elementLength = 0.0; - if (i != 0) { - elementLength = element.length(pathElements[i - 1]); - } - - /// Calculate new running length. - auto newLength = runningLength + elementLength; - - if (newLength < trim.start) { - /// Element is not included in the trim, continue. - runningLength = newLength; - i = i + 1; - /// Increment index, we are done with this element. - continue; - } - - if (newLength == trim.start) { - /// Current element IS the start element. - /// For start we want to add a zero length element. - currentPath->moveToStartPoint(element.vertex); - runningLength = newLength; - i = i + 1; - /// Increment index, we are done with this element. - continue; - } - - if (runningLength < trim.start && trim.start < newLength && currentPath->elements.size() == 0) { - /// The start of the trim is between this element and the previous, trim. - /// Get previous element. - auto previousElement = pathElements[i - 1]; - /// Trim it - auto trimLength = trim.start - runningLength; - auto trimResults = element.splitElementAtPosition(previousElement, trimLength); - /// Add the right span start. - currentPath->moveToStartPoint(trimResults.rightSpan.start.vertex); - - pathElements[i] = trimResults.rightSpan.end; - pathElements[i - 1] = trimResults.rightSpan.start; - runningLength = runningLength + trimResults.leftSpan.end.length(trimResults.leftSpan.start); - /// Dont increment index or the current length, the end of this path can be within this span. - continue; - } - - if (trim.start < newLength && newLength < trim.end) { - /// Element lies within the trim span. - currentPath->addElement(element); - runningLength = newLength; - i = i + 1; - continue; - } - - if (newLength == trim.end) { - /// Element is the end element. - /// The element could have a new length if it's added right after the start node. - currentPath->addElement(element); - /// We are done with this span. - runningLength = newLength; - i = i + 1; - /// Allow the path to be finalized. - /// Fall through to finalize path and move to next position - } - - if (runningLength < trim.end && trim.end < newLength) { - /// New element must be cut for end. - /// Get previous element. - auto previousElement = pathElements[i - 1]; - /// Trim it - auto trimLength = trim.end - runningLength; - auto trimResults = element.splitElementAtPosition(previousElement, trimLength); - /// Add the left span end. - - currentPath->updateVertex(trimResults.leftSpan.start.vertex, (int)currentPath->elements.size() - 1, false); - currentPath->addElement(trimResults.leftSpan.end); - - pathElements[i] = trimResults.rightSpan.end; - pathElements[i - 1] = trimResults.rightSpan.start; - runningLength = runningLength + trimResults.leftSpan.end.length(trimResults.leftSpan.start); - /// Dont increment index or the current length, the start of the next path can be within this span. - /// We are done with this span. - /// Allow the path to be finalized. - /// Fall through to finalize path and move to next position - } - - paths.push_back(currentPath); - currentPath = std::make_shared(); - if (remainingPositions.size() > 0) { - trim = remainingPositions[0]; - remainingPositions.erase(remainingPositions.begin()); - } else { - finishedTrimming = true; - } - } - return paths; -} - -BezierPath::BezierPath(CurveVertex const &startPoint) : -_contents(std::make_shared(startPoint)) { -} - -BezierPath::BezierPath() : -_contents(std::make_shared()) { -} - -BezierPath::BezierPath(lottiejson11::Json const &jsonAny) noexcept(false) : -_contents(std::make_shared(jsonAny)) { -} - -lottiejson11::Json BezierPath::toJson() const { - return _contents->toJson(); -} - -float BezierPath::length() { - return _contents->length(); -} - -void BezierPath::moveToStartPoint(CurveVertex const &vertex) { - _contents->moveToStartPoint(vertex); -} - -void BezierPath::addVertex(CurveVertex const &vertex) { - _contents->addVertex(vertex); -} - -void BezierPath::reserveCapacity(size_t capacity) { - _contents->reserveCapacity(capacity); -} - -void BezierPath::setElementCount(size_t count) { - _contents->setElementCount(count); -} - -void BezierPath::invalidateLength() { - _contents->invalidateLength(); -} - -void BezierPath::addCurve(Vector2D const &toPoint, Vector2D const &outTangent, Vector2D const &inTangent) { - _contents->addCurve(toPoint, outTangent, inTangent); -} - -void BezierPath::addLine(Vector2D const &toPoint) { - _contents->addLine(toPoint); -} - -void BezierPath::close() { - _contents->close(); -} - -void BezierPath::addElement(PathElement const &pathElement) { - _contents->addElement(pathElement); -} - -void BezierPath::updateVertex(CurveVertex const &vertex, int atIndex, bool remeasure) { - _contents->updateVertex(vertex, atIndex, remeasure); -} - -std::vector BezierPath::trim(float fromLength, float toLength, float offsetLength) { - std::vector result; - - auto resultContents = _contents->trim(fromLength, toLength, offsetLength); - for (const auto &resultContent : resultContents) { - result.emplace_back(resultContent); - } - - return result; -} - -std::vector const &BezierPath::elements() const { - return _contents->elements; -} - -std::vector &BezierPath::mutableElements() { - return _contents->elements; -} - -std::optional const &BezierPath::closed() const { - return _contents->closed; -} -void BezierPath::setClosed(std::optional const &closed) { - _contents->closed = closed; -} - -std::shared_ptr BezierPath::cgPath() const { - return _contents->cgPath(); -} - -BezierPath BezierPath::copyUsingTransform(Transform2D const &transform) const { - if (transform == Transform2D::identity()) { - return (*this); - } - BezierPath result; - result._contents->closed = _contents->closed; - result.reserveCapacity(_contents->elements.size()); - for (const auto &element : _contents->elements) { - result._contents->elements.emplace_back(element.vertex.transformed(transform)); - } - return result; -} - -BezierPath::BezierPath(std::shared_ptr contents) : -_contents(contents) { -} - -BezierPathsBoundingBoxContext::BezierPathsBoundingBoxContext() : -pointsX((float *)malloc(1024 * 4)), -pointsY((float *)malloc(1024 * 4)), -pointsSize(1024) { -} - -BezierPathsBoundingBoxContext::~BezierPathsBoundingBoxContext() { - free(pointsX); - free(pointsY); -} - -static CGRect calculateBoundingRectOpt(float const *pointsX, float const *pointsY, int count) { - float minX = 0.0; - float maxX = 0.0; - vDSP_minv(pointsX, 1, &minX, count); - vDSP_maxv(pointsX, 1, &maxX, count); - - float minY = 0.0; - float maxY = 0.0; - vDSP_minv(pointsY, 1, &minY, count); - vDSP_maxv(pointsY, 1, &maxY, count); - - return CGRect(minX, minY, maxX - minX, maxY - minY); -} - -CGRect bezierPathsBoundingBoxParallel(BezierPathsBoundingBoxContext &context, std::vector const &paths) { - int pointCount = 0; - - float *pointsX = context.pointsX; - float *pointsY = context.pointsY; - int pointsSize = context.pointsSize; - - for (const auto &path : paths) { - PathElement const *pathElements = path.elements().data(); - int pathElementCount = (int)path.elements().size(); - - for (int i = 0; i < pathElementCount; i++) { - const auto &element = pathElements[i]; - - if (pointsSize < pointCount + 1) { - pointsSize = (pointCount + 1) * 2; - pointsX = (float *)realloc(pointsX, pointsSize * 4); - pointsY = (float *)realloc(pointsY, pointsSize * 4); - } - pointsX[pointCount] = (float)element.vertex.point.x; - pointsY[pointCount] = (float)element.vertex.point.y; - pointCount++; - - if (i != 0) { - const auto &previousElement = pathElements[i - 1]; - if (previousElement.vertex.outTangentRelative().isZero() && element.vertex.inTangentRelative().isZero()) { - } else { - if (pointsSize < pointCount + 1) { - pointsSize = (pointCount + 2) * 2; - pointsX = (float *)realloc(pointsX, pointsSize * 4); - pointsY = (float *)realloc(pointsY, pointsSize * 4); - } - pointsX[pointCount] = (float)previousElement.vertex.outTangent.x; - pointsY[pointCount] = (float)previousElement.vertex.outTangent.y; - pointCount++; - pointsX[pointCount] = (float)element.vertex.inTangent.x; - pointsY[pointCount] = (float)element.vertex.inTangent.y; - pointCount++; - } - } - } - } - - context.pointsX = pointsX; - context.pointsY = pointsY; - context.pointsSize = pointsSize; - - if (pointCount == 0) { - return CGRect(0.0, 0.0, 0.0, 0.0); - } - - return calculateBoundingRectOpt(pointsX, pointsY, pointCount); -} - -CGRect bezierPathsBoundingBoxParallel(BezierPathsBoundingBoxContext &context, BezierPath const &path) { - int pointCount = 0; - - float *pointsX = context.pointsX; - float *pointsY = context.pointsY; - int pointsSize = context.pointsSize; - - PathElement const *pathElements = path.elements().data(); - int pathElementCount = (int)path.elements().size(); - - for (int i = 0; i < pathElementCount; i++) { - const auto &element = pathElements[i]; - - if (pointsSize < pointCount + 1) { - pointsSize = (pointCount + 1) * 2; - pointsX = (float *)realloc(pointsX, pointsSize * 4); - pointsY = (float *)realloc(pointsY, pointsSize * 4); - } - pointsX[pointCount] = (float)element.vertex.point.x; - pointsY[pointCount] = (float)element.vertex.point.y; - pointCount++; - - if (i != 0) { - const auto &previousElement = pathElements[i - 1]; - if (previousElement.vertex.outTangentRelative().isZero() && element.vertex.inTangentRelative().isZero()) { - } else { - if (pointsSize < pointCount + 1) { - pointsSize = (pointCount + 2) * 2; - pointsX = (float *)realloc(pointsX, pointsSize * 4); - pointsY = (float *)realloc(pointsY, pointsSize * 4); - } - pointsX[pointCount] = (float)previousElement.vertex.outTangent.x; - pointsY[pointCount] = (float)previousElement.vertex.outTangent.y; - pointCount++; - pointsX[pointCount] = (float)element.vertex.inTangent.x; - pointsY[pointCount] = (float)element.vertex.inTangent.y; - pointCount++; - } - } - } - - context.pointsX = pointsX; - context.pointsY = pointsY; - context.pointsSize = pointsSize; - - if (pointCount == 0) { - return CGRect(0.0, 0.0, 0.0, 0.0); - } - - return calculateBoundingRectOpt(pointsX, pointsY, pointCount); -} - -CGRect bezierPathsBoundingBox(std::vector const &paths) { - int pointCount = 0; - - float *pointsX = (float *)malloc(128 * 4); - float *pointsY = (float *)malloc(128 * 4); - int pointsSize = 128; - - for (const auto &path : paths) { - PathElement const *pathElements = path.elements().data(); - int pathElementCount = (int)path.elements().size(); - - for (int i = 0; i < pathElementCount; i++) { - const auto &element = pathElements[i]; - - if (pointsSize < pointCount + 1) { - pointsSize = (pointCount + 1) * 2; - pointsX = (float *)realloc(pointsX, pointsSize * 4); - pointsY = (float *)realloc(pointsY, pointsSize * 4); - } - pointsX[pointCount] = (float)element.vertex.point.x; - pointsY[pointCount] = (float)element.vertex.point.y; - pointCount++; - - if (i != 0) { - const auto &previousElement = pathElements[i - 1]; - if (previousElement.vertex.outTangentRelative().isZero() && element.vertex.inTangentRelative().isZero()) { - } else { - if (pointsSize < pointCount + 1) { - pointsSize = (pointCount + 2) * 2; - pointsX = (float *)realloc(pointsX, pointsSize * 4); - pointsY = (float *)realloc(pointsY, pointsSize * 4); - } - pointsX[pointCount] = (float)previousElement.vertex.outTangent.x; - pointsY[pointCount] = (float)previousElement.vertex.outTangent.y; - pointCount++; - pointsX[pointCount] = (float)element.vertex.inTangent.x; - pointsY[pointCount] = (float)element.vertex.inTangent.y; - pointCount++; - } - } - } - } - - free(pointsX); - free(pointsY); - - if (pointCount == 0) { - return CGRect(0.0, 0.0, 0.0, 0.0); - } - - return calculateBoundingRectOpt(pointsX, pointsY, pointCount); -} - -PathContents::PathContents(BezierPathContents const &bezierPath) { - std::optional previousElement; - for (const auto &element : bezierPath.elements) { - if (previousElement.has_value()) { - _elements.emplace_back(element.vertex.point, previousElement->vertex.outTangent, element.vertex.inTangent); - } else { - _elements.emplace_back(element.vertex.point, Vector2D(0.0, 0.0), Vector2D(0.0, 0.0)); - } - previousElement = element; - } - - if (bezierPath.closed.value_or(true)) { - _isClosed = true; - } else { - _isClosed = false; - } -} - -PathContents::~PathContents() { -} - -std::shared_ptr PathContents::bezierPath() const { - auto result = std::make_shared(); - - bool isFirst = true; - for (const auto &element : _elements) { - if (isFirst) { - isFirst = false; - } else { - result->elements.push_back(PathElement(CurveVertex::absolute( - element.point, - element.cp1, - element.cp2 - ))); - } - } - - result->closed = _isClosed; - - return result; -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/CompoundBezierPath.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/CompoundBezierPath.cpp deleted file mode 100644 index 31df703956..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/CompoundBezierPath.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "CompoundBezierPath.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/CompoundBezierPath.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/CompoundBezierPath.hpp deleted file mode 100644 index 58d02eb283..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/CompoundBezierPath.hpp +++ /dev/null @@ -1,163 +0,0 @@ -#ifndef CompoundBezierPath_hpp -#define CompoundBezierPath_hpp - -#include - -namespace lottie { - -/// A collection of BezierPath objects that can be trimmed and added. -/// -class CompoundBezierPath: public std::enable_shared_from_this { -public: - CompoundBezierPath() : - paths({}) { - } - - CompoundBezierPath(BezierPath const &path) : - paths({ path }) { - } - - CompoundBezierPath(std::vector paths_, std::optional length_) : - paths(paths_), _length(length_) { - } - - CompoundBezierPath(std::vector paths_) : - paths(paths_) { - } - -public: - std::vector paths; - - float length() { - if (_length.has_value()) { - return _length.value(); - } else { - float l = 0.0; - for (auto &path : paths) { - l += path.length(); - } - _length = l; - return l; - } - } - -private: - std::optional _length; - -public: - std::shared_ptr addingPath(BezierPath const &path) const { - auto newPaths = paths; - newPaths.push_back(path); - return std::make_shared(newPaths); - } - - void appendPath(BezierPath const &path) { - paths.push_back(path); - _length.reset(); - } - - std::shared_ptr combine(std::shared_ptr compoundBezier) { - auto newPaths = paths; - for (const auto &path : compoundBezier->paths) { - newPaths.push_back(path); - } - return std::make_shared(newPaths); - } - - std::shared_ptr trim(float fromPosition, float toPosition, float offset) { - if (fromPosition == toPosition) { - return std::make_shared(); - } - - float lengthValue = length(); - - /// Normalize lengths to the curve length. - float startPosition = fmod(fromPosition + offset, 1.0); - float endPosition = fmod(toPosition + offset, 1.0); - - if (startPosition < 0.0) { - startPosition = 1.0 + startPosition; - } - - if (endPosition < 0.0) { - endPosition = 1.0 + endPosition; - } - - if (startPosition == 1.0) { - startPosition = 0.0; - } - if (endPosition == 0.0) { - endPosition = 1.0; - } - - if ((startPosition == 0.0 && endPosition == 1.0) || - startPosition == endPosition || - (startPosition == 1.0 && endPosition == 0.0)) { - /// The trim encompasses the entire path. Return. - return shared_from_this(); - } - - std::vector positions; - if (endPosition < startPosition) { - positions = { - BezierTrimPathPosition(0.0, endPosition * lengthValue), - BezierTrimPathPosition(startPosition * lengthValue, lengthValue) - }; - } else { - positions = { BezierTrimPathPosition(startPosition * lengthValue, endPosition * lengthValue) }; - } - - auto compoundPath = std::make_shared(); - auto trim = positions[0]; - positions.erase(positions.begin()); - float pathStartPosition = 0.0; - - bool finishedTrimming = false; - int i = 0; - - while (!finishedTrimming) { - if (paths.size() <= i) { - /// Rounding errors - finishedTrimming = true; - continue; - } - auto path = paths[i]; - - auto pathEndPosition = pathStartPosition + path.length(); - - if (pathEndPosition < trim.start) { - /// Path is not included in the trim, continue. - pathStartPosition = pathEndPosition; - i = i + 1; - continue; - } else if (trim.start <= pathStartPosition && pathEndPosition <= trim.end) { - /// Full Path is inside of trim. Add full path. - compoundPath = compoundPath->addingPath(path); - } else { - auto trimPaths = path.trim(trim.start > pathStartPosition ? (trim.start - pathStartPosition) : 0, trim.end < pathEndPosition ? (trim.end - pathStartPosition) : path.length(), 0.0); - if (!trimPaths.empty()) { - compoundPath = compoundPath->addingPath(trimPaths[0]); - } - } - - if (trim.end <= pathEndPosition) { - /// We are done with the current trim. - /// Advance trim but remain on the same path in case the next trim overlaps it. - if (positions.size() > 0) { - trim = positions[0]; - positions.erase(positions.begin()); - } else { - finishedTrimming = true; - } - } else { - pathStartPosition = pathEndPosition; - i = i + 1; - } - } - return compoundPath; - } -}; - -} - -#endif /* CompoundBezierPath_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/CoordinateSpace.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/CoordinateSpace.cpp deleted file mode 100644 index 695b8dc4e9..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/CoordinateSpace.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "CoordinateSpace.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/CoordinateSpace.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/CoordinateSpace.hpp deleted file mode 100644 index 37a7b7054c..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/CoordinateSpace.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef CoordinateSpace_hpp -#define CoordinateSpace_hpp - -namespace lottie { - -enum class CoordinateSpace { - Type2d, - Type3d -}; - -} - -#endif /* CoordinateSpace_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/CurveVertex.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/CurveVertex.cpp deleted file mode 100644 index cbdd11762a..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/CurveVertex.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/PathElement.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/PathElement.cpp deleted file mode 100644 index af059629cd..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Private/Utility/Primitives/PathElement.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/DynamicProperties/AnimationKeypath.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/DynamicProperties/AnimationKeypath.cpp deleted file mode 100644 index 8f90bfc95e..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/DynamicProperties/AnimationKeypath.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "AnimationKeypath.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/DynamicProperties/AnimationKeypath.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/DynamicProperties/AnimationKeypath.hpp deleted file mode 100644 index 8679106d12..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/DynamicProperties/AnimationKeypath.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef AnimationKeypath_hpp -#define AnimationKeypath_hpp - -#include -#include - -namespace lottie { - -/// `AnimationKeypath` is an object that describes a keypath search for nodes in the -/// animation JSON. `AnimationKeypath` matches views and properties inside of `AnimationView` -/// to their backing `Animation` model by name. -/// -/// A keypath can be used to set properties on an existing animation, or can be validated -/// with an existing `Animation`. -/// -/// `AnimationKeypath` can describe a specific object, or can use wildcards for fuzzy matching -/// of objects. Acceptable wildcards are either "*" (star) or "**" (double star). -/// Single star will search a single depth for the next object. -/// Double star will search any depth. -/// -/// Read More at https://airbnb.io/lottie/#/ios?id=dynamic-animation-properties -/// -/// EG: -/// @"Layer.Shape Group.Stroke 1.Color" -/// Represents a specific color node on a specific stroke. -/// -/// @"**.Stroke 1.Color" -/// Represents the color node for every Stroke named "Stroke 1" in the animation. -class AnimationKeypath { -public: - /// Creates a keypath from a dot-separated string. The string is separated by "." - /*public init(keypath: String) { - keys = keypath.components(separatedBy: ".") - }*/ - - /// Creates a keypath from a list of strings. - AnimationKeypath(std::vector const &keys) : - _keys(keys) { - } - - std::vector const &keys() const { - return _keys; - } - -private: - std::vector _keys; -}; - -} - -#endif /* AnimationKeypath_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/DynamicProperties/AnyValueProvider.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/DynamicProperties/AnyValueProvider.cpp deleted file mode 100644 index f56124c957..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/DynamicProperties/AnyValueProvider.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "AnyValueProvider.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/DynamicProperties/AnyValueProvider.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/DynamicProperties/AnyValueProvider.hpp deleted file mode 100644 index a9b708afbd..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/DynamicProperties/AnyValueProvider.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef AnyValueProvider_hpp -#define AnyValueProvider_hpp - -#include "Lottie/Public/Primitives/AnimationTime.hpp" -#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp" -#include "Lottie/Public/Primitives/AnyValue.hpp" - -#include -#include - -namespace lottie { - -/// `AnyValueProvider` is a protocol that return animation data for a property at a -/// given time. Every frame an `AnimationView` queries all of its properties and asks -/// if their ValueProvider has an update. If it does the AnimationView will read the -/// property and update that portion of the animation. -/// -/// Value Providers can be used to dynamically set animation properties at run time. -class AnyValueProvider { -public: - /// The Type of the value provider - virtual AnyValue::Type valueType() const = 0; - - /// Asks the provider if it has an update for the given frame. - virtual bool hasUpdate(AnimationFrameTime frame) const = 0; -}; - -/// A base protocol for strongly-typed Value Providers -template -class ValueProvider: public AnyValueProvider { -public: - /// Asks the provider to update the container with its value for the frame. - virtual T value(AnimationFrameTime frame) = 0; -}; - -} - -#endif /* AnyValueProvider_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/FontProvider/AnimationFontProvider.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/FontProvider/AnimationFontProvider.cpp deleted file mode 100644 index a6a4774df7..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/FontProvider/AnimationFontProvider.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "AnimationFontProvider.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/FontProvider/AnimationFontProvider.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/FontProvider/AnimationFontProvider.hpp deleted file mode 100644 index c14d46f8d9..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/FontProvider/AnimationFontProvider.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef AnimationFontProvider_hpp -#define AnimationFontProvider_hpp - -#include "Lottie/Public/Primitives/CTFont.hpp" - -#include - -namespace lottie { - -/// Font provider is a protocol that is used to supply fonts to `AnimationView`. -/// -class AnimationFontProvider { -public: - virtual std::shared_ptr fontFor(std::string const &family, float size) = 0; -}; - -/// Default Font provider. -class DefaultFontProvider: public AnimationFontProvider { -public: - DefaultFontProvider() { - } - - virtual ~DefaultFontProvider() = default; - - virtual std::shared_ptr fontFor(std::string const &family, float size) override { - //CTFontCreateWithName(family as CFString, size, nil) - return nullptr; - } -}; - -} - -#endif /* AnimationFontProvider_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/ImageProvider/AnimationImageProvider.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/ImageProvider/AnimationImageProvider.hpp deleted file mode 100644 index 7efe74f8c8..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/ImageProvider/AnimationImageProvider.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef AnimationImageProvider_hpp -#define AnimationImageProvider_hpp - -#include "Lottie/Public/Primitives/CALayer.hpp" -#include "Lottie/Private/Model/Assets/ImageAsset.hpp" - -namespace lottie { - -class AnimationImageProvider { -public: - virtual std::shared_ptr imageForAsset(ImageAsset const &imageAsset) = 0; -}; - -} - -#endif /* AnimationImageProvider_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/Interpolatable.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/Interpolatable.cpp deleted file mode 100644 index aa58f615c4..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/Interpolatable.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "Interpolatable.hpp" - -namespace lottie { - -float remapFloat(float value, float fromLow, float fromHigh, float toLow, float toHigh) { - return toLow + (value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow); -} - -float clampFloat(float value, float a, float b) { - float minValue = a <= b ? a : b; - float maxValue = a <= b ? b : a; - return std::max(std::min(value, maxValue), minValue); -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/Interpolatable.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/Interpolatable.hpp deleted file mode 100644 index b57223466a..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/Interpolatable.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef Interpolatable_hpp -#define Interpolatable_hpp - -#include - -namespace lottie { - -float remapFloat(float value, float fromLow, float fromHigh, float toLow, float toHigh); - -float clampFloat(float value, float a, float b); - -} - -#endif /* Interpolatable_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/Keyframe.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/Keyframe.cpp deleted file mode 100644 index e699e6daf8..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/Keyframe.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Keyframe.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/Keyframe.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/Keyframe.hpp deleted file mode 100644 index a3d12b226f..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/Keyframe.hpp +++ /dev/null @@ -1,259 +0,0 @@ -#ifndef Keyframe_hpp -#define Keyframe_hpp - -#include "Lottie/Public/Primitives/AnimationTime.hpp" -#include -#include "Lottie/Public/Keyframes/Interpolatable.hpp" -#include "Lottie/Public/Keyframes/ValueInterpolators.hpp" - -#include - -namespace lottie { - -/// A keyframe with a single value, and timing information -/// about when the value should be displayed and how it -/// should be interpolated. -template -class Keyframe { -public: - /// Initialize a value-only keyframe with no time data. - Keyframe( - T const &value_, - std::optional spatialInTangent_, - std::optional spatialOutTangent_ - ) : - value(value_), - time(0), - isHold(true), - inTangent(std::nullopt), - outTangent(std::nullopt), - spatialInTangent(spatialInTangent_), - spatialOutTangent(spatialOutTangent_) { - } - - /// Initialize a keyframe - Keyframe( - T value_, - AnimationFrameTime time_, - bool isHold_, - std::optional inTangent_, - std::optional outTangent_, - std::optional spatialInTangent_, - std::optional spatialOutTangent_ - ) : - value(value_), - time(time_), - isHold(isHold_), - inTangent(inTangent_), - outTangent(outTangent_), - spatialInTangent(spatialInTangent_), - spatialOutTangent(spatialOutTangent_) { - } - - bool operator==(Keyframe const &rhs) { - return value == rhs.value - && time == rhs.time - && isHold == rhs.isHold - && inTangent == rhs.inTangent - && outTangent == rhs.outTangent - && spatialInTangent == rhs.spatialInTangent - && spatialOutTangent == rhs.spatialOutTangent; - } - - bool operator!=(Keyframe const &rhs) { - return !(*this == rhs); - } - -public: - T interpolate(Keyframe const &to, float progress) { - std::optional spatialOutTangent2d; - if (spatialOutTangent) { - spatialOutTangent2d = Vector2D(spatialOutTangent->x, spatialOutTangent->y); - } - std::optional spatialInTangent2d; - if (to.spatialInTangent) { - spatialInTangent2d = Vector2D(to.spatialInTangent->x, to.spatialInTangent->y); - } - return ValueInterpolator::interpolate(value, to.value, progress, spatialOutTangent2d, spatialInTangent2d); - } - - /// Interpolates the keyTime into a value from 0-1 - float interpolatedProgress(Keyframe const &to, float keyTime) { - float startTime = time; - float endTime = to.time; - if (keyTime <= startTime) { - return 0.0; - } - if (endTime <= keyTime) { - return 1.0; - } - - if (isHold) { - return 0.0; - } - - Vector2D outTanPoint = Vector2D::Zero(); - if (outTangent.has_value()) { - outTanPoint = outTangent.value(); - } - Vector2D inTanPoint = Vector2D(1.0, 1.0); - if (to.inTangent.has_value()) { - inTanPoint = to.inTangent.value(); - } - float progress = remapFloat(keyTime, startTime, endTime, 0.0f, 1.0f); - if (!outTanPoint.isZero() || inTanPoint != Vector2D(1.0f, 1.0f)) { - /// Cubic interpolation - progress = cubicBezierInterpolate(progress, Vector2D::Zero(), outTanPoint, inTanPoint, Vector2D(1.0, 1.0)); - } - return progress; - } - -public: - /// The value of the keyframe - T value; - /// The time in frames of the keyframe. - AnimationFrameTime time; - /// A hold keyframe freezes interpolation until the next keyframe that is not a hold. - bool isHold; - /// The in tangent for the time interpolation curve. - std::optional inTangent; - /// The out tangent for the time interpolation curve. - std::optional outTangent; - - /// The spatial in tangent of the vector. - std::optional spatialInTangent; - /// The spatial out tangent of the vector. - std::optional spatialOutTangent; -}; - -template -class KeyframeData { -public: - KeyframeData( - std::optional startValue_, - std::optional endValue_, - std::optional time_, - std::optional hold_, - std::optional inTangent_, - std::optional outTangent_, - std::optional spatialInTangent_, - std::optional spatialOutTangent_ - ) : - startValue(startValue_), - endValue(endValue_), - time(time_), - hold(hold_), - inTangent(inTangent_), - outTangent(outTangent_), - spatialInTangent(spatialInTangent_), - spatialOutTangent(spatialOutTangent_) { - } - - explicit KeyframeData(lottiejson11::Json const &json) noexcept(false) { - if (!json.is_object()) { - throw LottieParsingException(); - } - - if (const auto startValueData = getOptionalAny(json.object_items(), "s")) { - startValue = T(startValueData.value()); - } - - if (const auto endValueData = getOptionalAny(json.object_items(), "e")) { - endValue = T(endValueData.value()); - } - - if (const auto timeValue = getOptionalDouble(json.object_items(), "t")) { - time = (float)timeValue.value(); - } - - hold = getOptionalInt(json.object_items(), "h"); - - if (const auto inTangentData = getOptionalObject(json.object_items(), "i")) { - inTangent = Vector2D(inTangentData.value()); - } - - if (const auto outTangentData = getOptionalObject(json.object_items(), "o")) { - outTangent = Vector2D(outTangentData.value()); - } - - if (const auto spatialInTangentData = getOptionalAny(json.object_items(), "ti")) { - spatialInTangent = Vector3D(spatialInTangentData.value()); - } - - if (const auto spatialOutTangentData = getOptionalAny(json.object_items(), "to")) { - spatialOutTangent = Vector3D(spatialOutTangentData.value()); - } - - if (const auto nDataValue = getOptionalAny(json.object_items(), "n")) { - nData = nDataValue.value(); - } - } - - lottiejson11::Json::object toJson() const { - lottiejson11::Json::object result; - - if (startValue.has_value()) { - result.insert(std::make_pair("s", startValue->toJson())); - } - if (endValue.has_value()) { - result.insert(std::make_pair("e", endValue->toJson())); - } - if (time.has_value()) { - result.insert(std::make_pair("t", time.value())); - } - if (hold.has_value()) { - result.insert(std::make_pair("h", hold.value())); - } - if (inTangent.has_value()) { - result.insert(std::make_pair("i", inTangent->toJson())); - } - if (outTangent.has_value()) { - result.insert(std::make_pair("o", outTangent->toJson())); - } - if (spatialInTangent.has_value()) { - result.insert(std::make_pair("ti", spatialInTangent->toJson())); - } - if (spatialOutTangent.has_value()) { - result.insert(std::make_pair("to", spatialOutTangent->toJson())); - } - if (nData.has_value()) { - result.insert(std::make_pair("n", nData.value())); - } - - return result; - } - -public: - /// The start value of the keyframe - std::optional startValue; - /// The End value of the keyframe. Note: Newer versions animation json do not have this field. - std::optional endValue; - /// The time in frames of the keyframe. - std::optional time; - /// A hold keyframe freezes interpolation until the next keyframe that is not a hold. - std::optional hold; - - /// The in tangent for the time interpolation curve. - std::optional inTangent; - /// The out tangent for the time interpolation curve. - std::optional outTangent; - - /// The spacial in tangent of the vector. - std::optional spatialInTangent; - /// The spacial out tangent of the vector. - std::optional spatialOutTangent; - - std::optional nData; - - bool isHold() const { - if (hold.has_value()) { - return hold.value() > 0; - } else { - return false; - } - } -}; - -} - -#endif /* Keyframe_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/ValueInterpolators.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/ValueInterpolators.cpp deleted file mode 100644 index 650d25e041..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/ValueInterpolators.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "ValueInterpolators.hpp" - -#include - -namespace lottie { - -void batchInterpolate(std::vector const &from, std::vector const &to, BezierPath &resultPath, float amount) { - int elementCount = (int)from.size(); - if (elementCount > (int)to.size()) { - elementCount = (int)to.size(); - } - - static_assert(sizeof(PathElement) == 4 * 2 * 3); - - resultPath.setElementCount(elementCount); - float floatAmount = (float)amount; - vDSP_vintb((float *)&from[0], 1, (float *)&to[0], 1, &floatAmount, (float *)&resultPath.elements()[0], 1, elementCount * 2 * 3); -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/ValueInterpolators.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/ValueInterpolators.hpp deleted file mode 100644 index 4cc473bfc9..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Keyframes/ValueInterpolators.hpp +++ /dev/null @@ -1,227 +0,0 @@ -#ifndef ValueInterpolators_hpp -#define ValueInterpolators_hpp - -#include -#import -#include -#include "Lottie/Private/Model/Text/TextDocument.hpp" -#include "Lottie/Public/Primitives/GradientColorSet.hpp" -#include "Lottie/Public/Primitives/DashPattern.hpp" - -#include -#include - -namespace lottie { - -template -struct ValueInterpolator { -}; - -template<> -struct ValueInterpolator { -public: - static float interpolate(float value, float to, float amount, std::optional spatialOutTangent, std::optional spatialInTangent) { - return value + ((to - value) * amount); - } -}; - -template<> -struct ValueInterpolator { -public: - static Vector1D interpolate(Vector1D const &value, Vector1D const &to, float amount, std::optional spatialOutTangent, std::optional spatialInTangent) { - return Vector1D(ValueInterpolator::interpolate(value.value, to.value, amount, spatialOutTangent, spatialInTangent)); - } -}; - -template<> -struct ValueInterpolator { -public: - static Vector2D interpolate(Vector2D const &value, Vector2D const &to, float amount, Vector2D spatialOutTangent, Vector2D spatialInTangent) { - auto cp1 = value + spatialOutTangent; - auto cp2 = to + spatialInTangent; - - return value.interpolate(to, cp1, cp2, amount); - } - - static Vector2D interpolate(Vector2D const &value, Vector2D const &to, float amount) { - return value.interpolate(to, amount); - } -}; - -template<> -struct ValueInterpolator { -public: - static Vector3D interpolate(Vector3D const &value, Vector3D const &to, float amount, std::optional spatialOutTangent, std::optional spatialInTangent) { - if (spatialOutTangent && spatialInTangent) { - Vector2D from2d(value.x, value.y); - Vector2D to2d(to.x, to.y); - - auto cp1 = from2d + spatialOutTangent.value(); - auto cp2 = to2d + spatialInTangent.value(); - - Vector2D result2d = from2d.interpolate(to2d, cp1, cp2, amount); - - return Vector3D( - result2d.x, - result2d.y, - ValueInterpolator::interpolate(value.z, to.z, amount, spatialOutTangent, spatialInTangent) - ); - } - - return Vector3D( - ValueInterpolator::interpolate(value.x, to.x, amount, spatialOutTangent, spatialInTangent), - ValueInterpolator::interpolate(value.y, to.y, amount, spatialOutTangent, spatialInTangent), - ValueInterpolator::interpolate(value.z, to.z, amount, spatialOutTangent, spatialInTangent) - ); - } -}; - -template<> -struct ValueInterpolator { -public: - static Color interpolate(Color const &value, Color const &to, float amount, std::optional spatialOutTangent, std::optional spatialInTangent) { - return Color( - ValueInterpolator::interpolate(value.r, to.r, amount, spatialOutTangent, spatialInTangent), - ValueInterpolator::interpolate(value.g, to.g, amount, spatialOutTangent, spatialInTangent), - ValueInterpolator::interpolate(value.b, to.b, amount, spatialOutTangent, spatialInTangent), - ValueInterpolator::interpolate(value.a, to.a, amount, spatialOutTangent, spatialInTangent) - ); - } -}; - -void batchInterpolate(std::vector const &from, std::vector const &to, BezierPath &resultPath, float amount); - -template<> -struct ValueInterpolator { -public: - static CurveVertex interpolate(CurveVertex const &value, CurveVertex const &to, float amount, Vector2D spatialOutTangent, Vector2D spatialInTangent) { - return CurveVertex::absolute( - ValueInterpolator::interpolate(value.point, to.point, amount, spatialOutTangent, spatialInTangent), - ValueInterpolator::interpolate(value.inTangent, to.inTangent, amount, spatialOutTangent, spatialInTangent), - ValueInterpolator::interpolate(value.outTangent, to.outTangent, amount, spatialOutTangent, spatialInTangent) - ); - } - - static CurveVertex interpolate(CurveVertex const &value, CurveVertex const &to, float amount) { - return CurveVertex::absolute( - ValueInterpolator::interpolate(value.point, to.point, amount), - ValueInterpolator::interpolate(value.inTangent, to.inTangent, amount), - ValueInterpolator::interpolate(value.outTangent, to.outTangent, amount) - ); - } -}; - -template<> -struct ValueInterpolator { -public: - static BezierPath interpolate(BezierPath const &value, BezierPath const &to, float amount, std::optional spatialOutTangent, std::optional spatialInTangent) { - BezierPath newPath; - newPath.reserveCapacity(std::max(value.elements().size(), to.elements().size())); - //TODO:probably a bug in the upstream code, uncomment - //newPath.setClosed(value.closed()); - size_t elementCount = std::min(value.elements().size(), to.elements().size()); - - if (spatialInTangent && spatialOutTangent) { - Vector2D spatialInTangentValue = spatialInTangent.value(); - Vector2D spatialOutTangentValue = spatialOutTangent.value(); - - for (size_t i = 0; i < elementCount; i++) { - const auto &fromVertex = value.elements()[i].vertex; - const auto &toVertex = to.elements()[i].vertex; - - newPath.addVertex(ValueInterpolator::interpolate(fromVertex, toVertex, amount, spatialOutTangentValue, spatialInTangentValue)); - } - } else { - for (size_t i = 0; i < elementCount; i++) { - const auto &fromVertex = value.elements()[i].vertex; - const auto &toVertex = to.elements()[i].vertex; - - newPath.addVertex(ValueInterpolator::interpolate(fromVertex, toVertex, amount)); - } - } - return newPath; - } - - static void setInplace(BezierPath const &value, BezierPath &resultPath) { - resultPath.reserveCapacity(value.elements().size()); - resultPath.setElementCount(value.elements().size()); - resultPath.invalidateLength(); - - memcpy(resultPath.mutableElements().data(), value.elements().data(), value.elements().size() * sizeof(PathElement)); - } - - static void interpolateInplace(BezierPath const &value, BezierPath const &to, float amount, std::optional spatialOutTangent, std::optional spatialInTangent, BezierPath &resultPath) { - /*if (value.elements().size() != to.elements().size()) { - return to; - }*/ - - //TODO:probably a bug in the upstream code, uncomment - //newPath.setClosed(value.closed()); - - int elementCount = (int)std::min(value.elements().size(), to.elements().size()); - - resultPath.reserveCapacity(std::max(value.elements().size(), to.elements().size())); - resultPath.setElementCount(elementCount); - resultPath.invalidateLength(); - - if (spatialInTangent && spatialOutTangent) { - Vector2D spatialInTangentValue = spatialInTangent.value(); - Vector2D spatialOutTangentValue = spatialOutTangent.value(); - - for (int i = 0; i < elementCount; i++) { - const auto &fromVertex = value.elements()[i].vertex; - const auto &toVertex = to.elements()[i].vertex; - - auto vertex = ValueInterpolator::interpolate(fromVertex, toVertex, amount, spatialOutTangentValue, spatialInTangentValue); - - resultPath.updateVertex(vertex, i, false); - } - } else { - batchInterpolate(value.elements(), to.elements(), resultPath, amount); - } - } -}; - -template<> -struct ValueInterpolator { -public: - static TextDocument interpolate(TextDocument const &value, TextDocument const &to, float amount, std::optional spatialOutTangent, std::optional spatialInTangent) { - if (amount == 1.0) { - return to; - } else { - return value; - } - } -}; - -template<> -struct ValueInterpolator { -public: - static GradientColorSet interpolate(GradientColorSet const &value, GradientColorSet const &to, float amount, std::optional spatialOutTangent, std::optional spatialInTangent) { - assert(value.colors.size() == to.colors.size()); - std::vector colors; - size_t colorCount = std::min(value.colors.size(), to.colors.size()); - for (size_t i = 0; i < colorCount; i++) { - colors.push_back(ValueInterpolator::interpolate(value.colors[i], to.colors[i], amount, spatialOutTangent, spatialInTangent)); - } - return GradientColorSet(colors); - } -}; - -template<> -struct ValueInterpolator { -public: - static DashPattern interpolate(DashPattern const &value, DashPattern const &to, float amount, std::optional spatialOutTangent, std::optional spatialInTangent) { - assert(value.values.size() == to.values.size()); - std::vector values; - size_t colorCount = std::min(value.values.size(), to.values.size()); - for (size_t i = 0; i < colorCount; i++) { - values.push_back(ValueInterpolator::interpolate(value.values[i], to.values[i], amount, spatialOutTangent, spatialInTangent)); - } - return DashPattern(std::move(values)); - } -}; - -} - -#endif /* ValueInterpolators_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/AnimationTime.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/AnimationTime.cpp deleted file mode 100644 index c804b75b10..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/AnimationTime.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "AnimationTime.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/AnimationTime.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/AnimationTime.hpp deleted file mode 100644 index a2a7ec3fdd..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/AnimationTime.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef AnimationTime_hpp -#define AnimationTime_hpp - -namespace lottie { - -/// Defines animation time in Frames (Seconds * Framerate). -typedef float AnimationFrameTime; - -/// Defines animation time by a progress from 0 (beginning of the animation) to 1 (end of the animation) -typedef float AnimationProgressTime; - -} - -#endif /* AnimationTime_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/AnyValue.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/AnyValue.cpp deleted file mode 100644 index 1af508b3de..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/AnyValue.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "AnyValue.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/AnyValue.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/AnyValue.hpp deleted file mode 100644 index f730fad652..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/AnyValue.hpp +++ /dev/null @@ -1,245 +0,0 @@ -#ifndef AnyValue_hpp -#define AnyValue_hpp - -#include -#import -#include -#include "Lottie/Private/Model/Text/TextDocument.hpp" -#include "Lottie/Private/Model/ShapeItems/GradientFill.hpp" -#include "Lottie/Private/Model/Objects/DashElement.hpp" - -#include -#include - -namespace lottie { - -class AnyValue { -public: - enum class Type { - Float, - Vector1D, - Vector2D, - Vector3D, - Color, - BezierPath, - TextDocument, - GradientColorSet, - DashPattern - }; - -public: - AnyValue(float value) : - _type(Type::Float), - _floatValue(value) { - } - - AnyValue(Vector1D const &value) : - _type(Type::Vector1D), - _vector1DValue(value) { - } - - AnyValue(Vector2D const &value) : - _type(Type::Vector2D), - _vector2DValue(value) { - } - - AnyValue(Vector3D const & value) : - _type(Type::Vector3D), - _vector3DValue(value) { - } - - AnyValue(Color const &value) : - _type(Type::Color), - _colorValue(value) { - } - - AnyValue(BezierPath const &value) : - _type(Type::BezierPath), - _bezierPathValue(value) { - } - - AnyValue(TextDocument const &value) : - _type(Type::TextDocument), - _textDocumentValue(value) { - } - - AnyValue(GradientColorSet const &value) : - _type(Type::GradientColorSet), - _gradientColorSetValue(value) { - } - - AnyValue(DashPattern const &value) : - _type(Type::DashPattern), - _dashPatternValue(value) { - } - - template::value>> - float get() { - return asFloat(); - } - - template::value>> - Vector1D get() { - return asVector1D(); - } - - template::value>> - Vector2D get() { - return asVector2D(); - } - - template::value>> - Vector3D get() { - return asVector3D(); - } - - template::value>> - Color get() { - return asColor(); - } - - template::value>> - BezierPath get() { - return asBezierPath(); - } - - template::value>> - TextDocument get() { - return asTextDocument(); - } - - template::value>> - GradientColorSet get() { - return asGradientColorSet(); - } - - template::value>> - DashPattern get() { - return asDashPattern(); - } - -public: - Type type() { - return _type; - } - - float asFloat() { - return _floatValue.value(); - } - - Vector1D asVector1D() { - return _vector1DValue.value(); - } - - Vector2D asVector2D() { - return _vector2DValue.value(); - } - - Vector3D asVector3D() { - return _vector3DValue.value(); - } - - Color asColor() { - return _colorValue.value(); - } - - BezierPath asBezierPath() { - return _bezierPathValue.value(); - } - - TextDocument asTextDocument() { - return _textDocumentValue.value(); - } - - GradientColorSet asGradientColorSet() { - return _gradientColorSetValue.value(); - } - - DashPattern asDashPattern() { - return _dashPatternValue.value(); - } - -private: - Type _type; - - std::optional _floatValue; - std::optional _vector1DValue; - std::optional _vector2DValue; - std::optional _vector3DValue; - std::optional _colorValue; - std::optional _bezierPathValue; - std::optional _textDocumentValue; - std::optional _gradientColorSetValue; - std::optional _dashPatternValue; -}; - -template -struct AnyValueType { -}; - -template<> -struct AnyValueType { - static AnyValue::Type type() { - return AnyValue::Type::Float; - } -}; - -template<> -struct AnyValueType { - static AnyValue::Type type() { - return AnyValue::Type::Vector1D; - } -}; - -template<> -struct AnyValueType { - static AnyValue::Type type() { - return AnyValue::Type::Vector2D; - } -}; - -template<> -struct AnyValueType { - static AnyValue::Type type() { - return AnyValue::Type::Vector3D; - } -}; - -template<> -struct AnyValueType { - static AnyValue::Type type() { - return AnyValue::Type::Color; - } -}; - -template<> -struct AnyValueType { - static AnyValue::Type type() { - return AnyValue::Type::BezierPath; - } -}; - -template<> -struct AnyValueType { - static AnyValue::Type type() { - return AnyValue::Type::TextDocument; - } -}; - -template<> -struct AnyValueType { - static AnyValue::Type type() { - return AnyValue::Type::GradientColorSet; - } -}; - -template<> -struct AnyValueType { - static AnyValue::Type type() { - return AnyValue::Type::DashPattern; - } -}; - -} - -#endif /* AnyValue_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CALayer.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CALayer.cpp deleted file mode 100644 index add81ca973..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CALayer.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "CALayer.hpp" - -namespace lottie { - -std::shared_ptr CAShapeLayer::renderableItem() { - if (!_path) { - return nullptr; - } - - std::optional fill; - if (_fillColor) { - fill = ShapeRenderableItem::Fill( - _fillColor.value(), - _fillRule - ); - } - - std::optional stroke; - if (_strokeColor) { - stroke = ShapeRenderableItem::Stroke( - _strokeColor.value(), - _lineWidth, - _lineJoin, - _lineCap, - _lineDashPhase, - _dashPattern - ); - } - - return std::make_shared( - _path, - fill, - stroke - ); -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CALayer.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CALayer.hpp deleted file mode 100644 index c0c0a61006..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CALayer.hpp +++ /dev/null @@ -1,212 +0,0 @@ -#ifndef CALayer_hpp -#define CALayer_hpp - -#import -#include -#include -#include -#include "Lottie/Private/Model/ShapeItems/Fill.hpp" -#include "Lottie/Private/Model/Layers/LayerModel.hpp" -#include -#include "Lottie/Private/Model/ShapeItems/GradientFill.hpp" - -#include -#include -#include - -namespace lottie { - -class CALayer: public std::enable_shared_from_this { -public: - CALayer() { - } - - virtual ~CALayer() = default; - - void addSublayer(std::shared_ptr layer) { - _sublayers.push_back(layer); - } - - void insertSublayer(std::shared_ptr layer, int index) { - _sublayers.insert(_sublayers.begin() + index, layer); - } - - virtual bool implementsDraw() const { - return false; - } - - virtual bool isInvertedMatte() const { - return false; - } - - virtual std::shared_ptr renderableItem() { - return nullptr; - } - - bool isHidden() const { - return _isHidden; - } - void setIsHidden(bool isHidden) { - _isHidden = isHidden; - } - - float opacity() const { - return _opacity; - } - void setOpacity(float opacity) { - _opacity = opacity; - } - - Vector2D const &size() const { - return _size; - } - void setSize(Vector2D const &size) { - _size = size; - } - - Transform2D const &transform() const { - return _transform; - } - void setTransform(Transform2D const &transform) { - _transform = transform; - } - - std::shared_ptr const &mask() const { - return _mask; - } - void setMask(std::shared_ptr mask) { - _mask = mask; - } - - bool masksToBounds() const { - return _masksToBounds; - } - void setMasksToBounds(bool masksToBounds) { - _masksToBounds = masksToBounds; - } - - std::vector> const &sublayers() const { - return _sublayers; - } - - std::optional const &compositingFilter() const { - return _compositingFilter; - } - void setCompositingFilter(std::optional const &compositingFilter) { - _compositingFilter = compositingFilter; - } - -protected: - template - std::shared_ptr shared_from_base() { - return std::static_pointer_cast(shared_from_this()); - } - -private: - void removeSublayer(CALayer *layer) { - for (auto it = _sublayers.begin(); it != _sublayers.end(); it++) { - if (it->get() == layer) { - _sublayers.erase(it); - break; - } - } - } - -private: - std::vector> _sublayers; - bool _isHidden = false; - float _opacity = 1.0; - Vector2D _size = Vector2D(0.0, 0.0); - Transform2D _transform = Transform2D::identity(); - std::shared_ptr _mask; - bool _masksToBounds = false; - std::optional _compositingFilter; -}; - -class CAShapeLayer: public CALayer { -public: - CAShapeLayer() { - } - - virtual ~CAShapeLayer() = default; - - std::optional const &strokeColor() { - return _strokeColor; - } - void setStrokeColor(std::optional const &strokeColor) { - _strokeColor = strokeColor; - } - - std::optional const &fillColor() { - return _fillColor; - } - void setFillColor(std::optional const &fillColor) { - _fillColor = fillColor; - } - - FillRule fillRule() { - return _fillRule; - } - void setFillRule(FillRule fillRule) { - _fillRule = fillRule; - } - - std::shared_ptr const &path() const { - return _path; - } - void setPath(std::shared_ptr const &path) { - _path = path; - } - - float lineWidth() const { - return _lineWidth; - } - void setLineWidth(float lineWidth) { - _lineWidth = lineWidth; - } - - LineJoin lineJoin() const { - return _lineJoin; - } - void setLineJoin(LineJoin lineJoin) { - _lineJoin = lineJoin; - } - - LineCap lineCap() const { - return _lineCap; - } - void setLineCap(LineCap lineCap) { - _lineCap = lineCap; - } - - float lineDashPhase() const { - return _lineDashPhase; - } - void setLineDashPhase(float lineDashPhase) { - _lineDashPhase = lineDashPhase; - } - - std::vector const &dashPattern() const { - return _dashPattern; - } - void setDashPattern(std::vector const &dashPattern) { - _dashPattern = dashPattern; - } - - std::shared_ptr renderableItem() override; - -private: - std::optional _strokeColor; - std::optional _fillColor = Color(0.0, 0.0, 0.0, 1.0); - FillRule _fillRule = FillRule::NonZeroWinding; - std::shared_ptr _path; - float _lineWidth = 1.0; - LineJoin _lineJoin = LineJoin::Miter; - LineCap _lineCap = LineCap::Butt; - float _lineDashPhase = 0.0; - std::vector _dashPattern; -}; - -} - -#endif /* CALayer_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CGPath.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CGPath.cpp deleted file mode 100644 index e985e18392..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CGPath.cpp +++ /dev/null @@ -1,193 +0,0 @@ -#include - -#include - -namespace lottie { - -namespace { - -void addPointToBoundingRect(bool *isFirst, CGRect *rect, Vector2D const *point) { - if (*isFirst) { - *isFirst = false; - - rect->x = point->x; - rect->y = point->y; - rect->width = 0.0; - rect->height = 0.0; - - return; - } - if (point->x > rect->x + rect->width) { - rect->width = point->x - rect->x; - } - if (point->y > rect->y + rect->height) { - rect->height = point->y - rect->y; - } - if (point->x < rect->x) { - rect->width += rect->x - point->x; - rect->x = point->x; - } - if (point->y < rect->y) { - rect->height += rect->y - point->y; - rect->y = point->y; - } -} - -} - -Vector2D transformVector(Vector2D const &v, Transform2D const &m) { - float transformedX = m.rows().columns[0][0] * v.x + m.rows().columns[1][0] * v.y + m.rows().columns[2][0] * 1.0f; - float transformedY = m.rows().columns[0][1] * v.x + m.rows().columns[1][1] * v.y + m.rows().columns[2][1] * 1.0f; - return Vector2D(transformedX, transformedY); -} - -class CGPathImpl: public CGPath { -public: - CGPathImpl(); - virtual ~CGPathImpl(); - - virtual CGRect boundingBox() const override; - - virtual bool empty() const override; - - virtual std::shared_ptr copyUsingTransform(Transform2D const &transform) const override; - - virtual void addLineTo(Vector2D const &point) override; - virtual void addCurveTo(Vector2D const &point, Vector2D const &control1, Vector2D const &control2) override; - virtual void moveTo(Vector2D const &point) override; - virtual void closeSubpath() override; - virtual void addRect(CGRect const &rect) override; - virtual void addPath(std::shared_ptr const &path) override; - virtual bool isEqual(CGPath *other) const override; - virtual void enumerate(std::function) override; - -private: - std::vector _items; -}; - -CGPathImpl::CGPathImpl() { -} - -CGPathImpl::~CGPathImpl() { -} - -CGRect CGPathImpl::boundingBox() const { - bool isFirst = true; - CGRect result(0.0, 0.0, 0.0, 0.0); - - for (const auto &item : _items) { - switch (item.type) { - case CGPathItem::Type::MoveTo: { - addPointToBoundingRect(&isFirst, &result, &item.points[0]); - break; - } - case CGPathItem::Type::LineTo: { - addPointToBoundingRect(&isFirst, &result, &item.points[0]); - break; - } - case CGPathItem::Type::CurveTo: { - addPointToBoundingRect(&isFirst, &result, &item.points[0]); - addPointToBoundingRect(&isFirst, &result, &item.points[1]); - addPointToBoundingRect(&isFirst, &result, &item.points[2]); - break; - } - case CGPathItem::Type::Close: { - break; - } - default: { - break; - } - } - } - - return result; -} - -bool CGPathImpl::empty() const { - return _items.empty(); -} - -std::shared_ptr CGPathImpl::copyUsingTransform(Transform2D const &transform) const { - auto result = std::make_shared(); - - if (transform == Transform2D::identity()) { - result->_items = _items; - return result; - } - - result->_items.reserve(_items.capacity()); - for (auto &sourceItem : _items) { - CGPathItem &item = result->_items.emplace_back(sourceItem.type); - item.points[0] = transformVector(sourceItem.points[0], transform); - item.points[1] = transformVector(sourceItem.points[1], transform); - item.points[2] = transformVector(sourceItem.points[2], transform); - } - - return result; -} - -void CGPathImpl::addLineTo(Vector2D const &point) { - CGPathItem &item = _items.emplace_back(CGPathItem::Type::LineTo); - item.points[0] = point; -} - -void CGPathImpl::addCurveTo(Vector2D const &point, Vector2D const &control1, Vector2D const &control2) { - CGPathItem &item = _items.emplace_back(CGPathItem::Type::CurveTo); - item.points[0] = control1; - item.points[1] = control2; - item.points[2] = point; -} - -void CGPathImpl::moveTo(Vector2D const &point) { - CGPathItem &item = _items.emplace_back(CGPathItem::Type::MoveTo); - item.points[0] = point; -} - -void CGPathImpl::closeSubpath() { - _items.emplace_back(CGPathItem::Type::Close); -} - -void CGPathImpl::addRect(CGRect const &rect) { - assert(false); - //CGPathAddRect(_path, nil, ::CGRectMake(rect.x, rect.y, rect.width, rect.height)); -} - -void CGPathImpl::addPath(std::shared_ptr const &path) { - if (_items.size() == 0) { - _items = std::static_pointer_cast(path)->_items; - } else { - size_t totalItemCount = _items.size() + std::static_pointer_cast(path)->_items.size(); - if (_items.capacity() < totalItemCount) { - _items.reserve(totalItemCount); - } - for (const auto &item : std::static_pointer_cast(path)->_items) { - _items.push_back(item); - } - } -} - -bool CGPathImpl::isEqual(CGPath *other) const { - if (_items.size() != ((CGPathImpl *)other)->_items.size()) { - return false; - } - - for (size_t i = 0; i < _items.size(); i++) { - if (_items[i] != ((CGPathImpl *)other)->_items[i]) { - return false; - } - } - - return true; -} - -void CGPathImpl::enumerate(std::function f) { - for (const auto &item : _items) { - f(item); - } -} - -std::shared_ptr CGPath::makePath() { - return std::static_pointer_cast(std::make_shared()); -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CGPath.mm b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CGPath.mm deleted file mode 100644 index 93a5e242a1..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CGPath.mm +++ /dev/null @@ -1,223 +0,0 @@ -#include - -#include -#import - -namespace { - -void addPointToBoundingRect(bool *isFirst, CGRect *rect, CGPoint *point) { - if (*isFirst) { - *isFirst = false; - - rect->origin.x = point->x; - rect->origin.y = point->y; - rect->size.width = 0.0; - rect->size.height = 0.0; - - return; - } - if (point->x > rect->origin.x + rect->size.width) { - rect->size.width = point->x - rect->origin.x; - } - if (point->y > rect->origin.y + rect->size.height) { - rect->size.height = point->y - rect->origin.y; - } - if (point->x < rect->origin.x) { - rect->size.width += rect->origin.x - point->x; - rect->origin.x = point->x; - } - if (point->y < rect->origin.y) { - rect->size.height += rect->origin.y - point->y; - rect->origin.y = point->y; - } -} - -} - -CGRect calculatePathBoundingBox(CGPathRef path) { - __block CGRect result = CGRectMake(0.0, 0.0, 0.0, 0.0); - __block bool isFirst = true; - - CGPathApplyWithBlock(path, ^(const CGPathElement * _Nonnull element) { - switch (element->type) { - case kCGPathElementMoveToPoint: { - addPointToBoundingRect(&isFirst, &result, &element->points[0]); - break; - } - case kCGPathElementAddLineToPoint: { - addPointToBoundingRect(&isFirst, &result, &element->points[0]); - break; - } - case kCGPathElementAddCurveToPoint: { - addPointToBoundingRect(&isFirst, &result, &element->points[0]); - addPointToBoundingRect(&isFirst, &result, &element->points[1]); - addPointToBoundingRect(&isFirst, &result, &element->points[2]); - break; - } - case kCGPathElementAddQuadCurveToPoint: { - addPointToBoundingRect(&isFirst, &result, &element->points[0]); - addPointToBoundingRect(&isFirst, &result, &element->points[1]); - break; - } - case kCGPathElementCloseSubpath: { - break; - } - } - }); - - return result; -} - -namespace lottie { - -CGPathCocoaImpl::CGPathCocoaImpl() { - _path = CGPathCreateMutable(); -} - -CGPathCocoaImpl::CGPathCocoaImpl(CGMutablePathRef path) { - CFRetain(path); - _path = path; -} - -CGPathCocoaImpl::~CGPathCocoaImpl() { - CGPathRelease(_path); -} - -CGRect CGPathCocoaImpl::boundingBox() const { - auto rect = calculatePathBoundingBox(_path); - return CGRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); -} - -bool CGPathCocoaImpl::empty() const { - return CGPathIsEmpty(_path); -} - -std::shared_ptr CGPathCocoaImpl::copyUsingTransform(Transform2D const &transform) const { - CGAffineTransform affineTransform = CGAffineTransformMake( - transform.rows().columns[0][0], transform.rows().columns[0][1], - transform.rows().columns[1][0], transform.rows().columns[1][1], - transform.rows().columns[2][0], transform.rows().columns[2][1] - ); - - CGPathRef resultPath = CGPathCreateCopyByTransformingPath(_path, &affineTransform); - if (resultPath == nil) { - return nullptr; - } - - CGMutablePathRef resultMutablePath = CGPathCreateMutableCopy(resultPath); - CGPathRelease(resultPath); - auto result = std::make_shared(resultMutablePath); - CGPathRelease(resultMutablePath); - - return result; -} - -void CGPathCocoaImpl::addLineTo(Vector2D const &point) { - CGPathAddLineToPoint(_path, nil, point.x, point.y); -} - -void CGPathCocoaImpl::addCurveTo(Vector2D const &point, Vector2D const &control1, Vector2D const &control2) { - CGPathAddCurveToPoint(_path, nil, control1.x, control1.y, control2.x, control2.y, point.x, point.y); -} - -void CGPathCocoaImpl::moveTo(Vector2D const &point) { - CGPathMoveToPoint(_path, nil, point.x, point.y); -} - -void CGPathCocoaImpl::closeSubpath() { - CGPathCloseSubpath(_path); -} - -void CGPathCocoaImpl::addRect(CGRect const &rect) { - CGPathAddRect(_path, nil, ::CGRectMake(rect.x, rect.y, rect.width, rect.height)); -} - -void CGPathCocoaImpl::addPath(std::shared_ptr const &path) { - if (CGPathIsEmpty(_path)) { - _path = CGPathCreateMutableCopy(std::static_pointer_cast(path)->_path); - } else { - CGPathAddPath(_path, nil, std::static_pointer_cast(path)->_path); - } -} - -CGPathRef CGPathCocoaImpl::nativePath() const { - return _path; -} - -bool CGPathCocoaImpl::isEqual(CGPath *other) const { - CGPathCocoaImpl *otherImpl = (CGPathCocoaImpl *)other; - return CGPathEqualToPath(_path, otherImpl->_path); -} - -void CGPathCocoaImpl::enumerate(std::function f) { - CGPathApplyWithBlock(_path, ^(const CGPathElement * _Nonnull element) { - CGPathItem item(CGPathItem::Type::MoveTo); - - switch (element->type) { - case kCGPathElementMoveToPoint: { - item.type = CGPathItem::Type::MoveTo; - item.points[0] = Vector2D(element->points[0].x, element->points[0].y); - f(item); - break; - } - case kCGPathElementAddLineToPoint: { - item.type = CGPathItem::Type::LineTo; - item.points[0] = Vector2D(element->points[0].x, element->points[0].y); - f(item); - break; - } - case kCGPathElementAddCurveToPoint: { - item.type = CGPathItem::Type::CurveTo; - item.points[0] = Vector2D(element->points[0].x, element->points[0].y); - item.points[1] = Vector2D(element->points[1].x, element->points[1].y); - item.points[2] = Vector2D(element->points[2].x, element->points[2].y); - f(item); - break; - } - case kCGPathElementAddQuadCurveToPoint: { - break; - } - case kCGPathElementCloseSubpath: { - item.type = CGPathItem::Type::Close; - f(item); - break; - } - } - }); -} - -void CGPathCocoaImpl::withNativePath(std::shared_ptr const &path, std::function f) { - CGMutablePathRef result = CGPathCreateMutable(); - - path->enumerate([result](CGPathItem const &element) { - switch (element.type) { - case CGPathItem::Type::MoveTo: { - CGPathMoveToPoint(result, nullptr, element.points[0].x, element.points[0].y); - break; - } - case CGPathItem::Type::LineTo: { - CGPathAddLineToPoint(result, nullptr, element.points[0].x, element.points[0].y); - break; - } - case CGPathItem::Type::CurveTo: { - CGPathAddCurveToPoint(result, nullptr, element.points[0].x, element.points[0].y, element.points[1].x, element.points[1].y, element.points[2].x, element.points[2].y); - break; - } - case CGPathItem::Type::Close: { - CGPathCloseSubpath(result); - break; - } - default: - break; - } - }); - - f(result); - CFRelease(result); -} - -/*std::shared_ptr CGPath::makePath() { - return std::static_pointer_cast(std::make_shared()); -}*/ - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CTFont.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CTFont.cpp deleted file mode 100644 index 24022559bf..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CTFont.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "CTFont.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CTFont.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CTFont.hpp deleted file mode 100644 index 351d4bfc22..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/CTFont.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef CTFont_hpp -#define CTFont_hpp - -namespace lottie { - -class CTFont { - -}; - -} - -#endif /* CTFont_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/Color.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/Color.cpp deleted file mode 100644 index d627e71da4..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/Color.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include - -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include - -namespace lottie { - -Color::Color(float r_, float g_, float b_, float a_, ColorFormatDenominator denominator) { - float denominatorValue = 1.0; - switch (denominator) { - case ColorFormatDenominator::One: { - denominatorValue = 1.0; - break; - } - case ColorFormatDenominator::OneHundred: { - denominatorValue = 100.0; - break; - } - case ColorFormatDenominator::TwoFiftyFive: { - denominatorValue = 255.0; - break; - } - } - - r = r_ / denominatorValue; - g = g_ / denominatorValue; - b = b_ / denominatorValue; - a = a_ / denominatorValue; -} - -Color::Color(lottiejson11::Json const &jsonAny) noexcept(false) : - r(0.0), g(0.0), b(0.0), a(0.0) { - if (!jsonAny.is_array()) { - throw LottieParsingException(); - } - - for (const auto &item : jsonAny.array_items()) { - if (!item.is_number()) { - throw LottieParsingException(); - } - } - - size_t index = 0; - - float r1 = 0.0; - if (index < jsonAny.array_items().size()) { - if (!jsonAny.array_items()[index].is_number()) { - throw LottieParsingException(); - } - r1 = jsonAny.array_items()[index].number_value(); - index++; - } - - float g1 = 0.0; - if (index < jsonAny.array_items().size()) { - if (!jsonAny.array_items()[index].is_number()) { - throw LottieParsingException(); - } - g1 = jsonAny.array_items()[index].number_value(); - index++; - } - - float b1 = 0.0; - if (index < jsonAny.array_items().size()) { - if (!jsonAny.array_items()[index].is_number()) { - throw LottieParsingException(); - } - b1 = jsonAny.array_items()[index].number_value(); - index++; - } - - float a1 = 0.0; - if (index < jsonAny.array_items().size()) { - if (!jsonAny.array_items()[index].is_number()) { - throw LottieParsingException(); - } - a1 = jsonAny.array_items()[index].number_value(); - index++; - } - - if (r1 > 1.0 && r1 > 1.0 && b1 > 1.0 && a1 > 1.0) { - r1 = r1 / 255.0; - g1 = g1 / 255.0; - b1 = b1 / 255.0; - a1 = a1 / 255.0; - } - - r = r1; - g = g1; - b = b1; - a = a1; -} - -lottiejson11::Json Color::toJson() const { - lottiejson11::Json::array result; - - result.push_back(lottiejson11::Json(r)); - result.push_back(lottiejson11::Json(g)); - result.push_back(lottiejson11::Json(b)); - result.push_back(lottiejson11::Json(a)); - - return result; -} - -Color Color::fromString(std::string const &string) { - if (string.empty()) { - return Color(0.0, 0.0, 0.0, 0.0); - } - - std::string workString = string; - if (workString[0] == '#') { - workString.erase(workString.begin()); - } - - std::istringstream converter(workString); - uint32_t rgbValue; - converter >> std::hex >> rgbValue; - - return Color( - ((float)((rgbValue & 0xFF0000) >> 16)) / 255.0, - ((float)((rgbValue & 0x00FF00) >> 8)) / 255.0, - ((float)(rgbValue & 0x0000FF)) / 255.0, - 1.0 - ); -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/DashPattern.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/DashPattern.cpp deleted file mode 100644 index 33426de338..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/DashPattern.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "DashPattern.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/DashPattern.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/DashPattern.hpp deleted file mode 100644 index e6255ec821..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/DashPattern.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef DashPattern_hpp -#define DashPattern_hpp - -#include - -namespace lottie { - -struct DashPattern { - DashPattern(std::vector &&values_) : - values(std::move(values_)) { - } - - std::vector values; -}; - -} - -#endif /* DashPattern_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/GradientColorSet.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/GradientColorSet.cpp deleted file mode 100644 index 3a92ce0d41..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/GradientColorSet.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "GradientColorSet.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/GradientColorSet.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/GradientColorSet.hpp deleted file mode 100644 index abf576690f..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/GradientColorSet.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef GradientColorSet_hpp -#define GradientColorSet_hpp - -#include "Lottie/Private/Parsing/JsonParsing.hpp" - -#include - -namespace lottie { - -struct GradientColorSet { - GradientColorSet() { - } - - explicit GradientColorSet(lottiejson11::Json const &jsonAny) noexcept(false) { - if (!jsonAny.is_array()) { - throw LottieParsingException(); - } - - for (const auto &item : jsonAny.array_items()) { - if (!item.is_number()) { - throw LottieParsingException(); - } - colors.push_back(item.number_value()); - } - } - - lottiejson11::Json toJson() const { - lottiejson11::Json::array result; - - for (auto value : colors) { - result.push_back(value); - } - - return result; - } - - std::vector colors; -}; - -} - -#endif /* GradientColorSet_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/Vectors.mm b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/Vectors.mm deleted file mode 100644 index 3695d35aa0..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/Primitives/Vectors.mm +++ /dev/null @@ -1,912 +0,0 @@ -#include -#include - -#include "Lottie/Private/Parsing/JsonParsing.hpp" -#include "Lottie/Public/Keyframes/Interpolatable.hpp" - -#include - -#import - -namespace lottie { - -/*explicit Transform2D(Transform3D const &t) { - CGAffineTransform at = CATransform3DGetAffineTransform(nativeTransform(t)); - _rows.columns[0] = simd_make_float3(at.a, at.b, 0.0); - _rows.columns[1] = simd_make_float3(at.c, at.d, 0.0); - _rows.columns[2] = simd_make_float3(at.tx, at.ty, 1.0); -} - - Transform3D transform3D() { - CGAffineTransform at = CGAffineTransformMake( - _rows.columns[0][0], _rows.columns[0][1], - _rows.columns[1][0], _rows.columns[1][1], - _rows.columns[2][0], _rows.columns[2][1] - ); - return fromNativeTransform(CATransform3DMakeAffineTransform(at)); - }*/ - -/*struct Transform3D { - float m11, m12, m13, m14; - float m21, m22, m23, m24; - float m31, m32, m33, m34; - float m41, m42, m43, m44; - - Transform3D( - float m11_, float m12_, float m13_, float m14_, - float m21_, float m22_, float m23_, float m24_, - float m31_, float m32_, float m33_, float m34_, - float m41_, float m42_, float m43_, float m44_ - ) : - m11(m11_), m12(m12_), m13(m13_), m14(m14_), - m21(m21_), m22(m22_), m23(m23_), m24(m24_), - m31(m31_), m32(m32_), m33(m33_), m34(m34_), - m41(m41_), m42(m42_), m43(m43_), m44(m44_) { - } - - bool operator==(Transform3D const &rhs) const { - return m11 == rhs.m11 && m12 == rhs.m12 && m13 == rhs.m13 && m14 == rhs.m14 && - m21 == rhs.m21 && m22 == rhs.m22 && m23 == rhs.m23 && m24 == rhs.m24 && - m31 == rhs.m31 && m32 == rhs.m32 && m33 == rhs.m33 && m34 == rhs.m34 && - m41 == rhs.m41 && m42 == rhs.m42 && m43 == rhs.m43 && m44 == rhs.m44; - } - - bool operator!=(Transform3D const &rhs) const { - return !(*this == rhs); - } - - inline bool isIdentity() const { - return m11 == 1.0 && m12 == 0.0 && m13 == 0.0 && m14 == 0.0 && - m21 == 0.0 && m22 == 1.0 && m23 == 0.0 && m24 == 0.0 && - m31 == 0.0 && m32 == 0.0 && m33 == 1.0 && m34 == 0.0 && - m41 == 0.0 && m42 == 0.0 && m43 == 0.0 && m44 == 1.0; - } - - static Transform3D makeTranslation(float tx, float ty, float tz) { - return Transform3D( - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - tx, ty, tz, 1 - ); - } - - static Transform3D makeScale(float sx, float sy, float sz) { - return Transform3D( - sx, 0, 0, 0, - 0, sy, 0, 0, - 0, 0, sz, 0, - 0, 0, 0, 1 - ); - } - - static Transform3D makeRotation(float radians); - - static Transform3D makeSkew(float skew, float skewAxis) { - float mCos = cos(degreesToRadians(skewAxis)); - float mSin = sin(degreesToRadians(skewAxis)); - float aTan = tan(degreesToRadians(skew)); - - Transform3D transform1( - mCos, - mSin, - 0.0, - 0.0, - -mSin, - mCos, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ); - - Transform3D transform2( - 1.0, - 0.0, - 0.0, - 0.0, - aTan, - 1.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ); - - Transform3D transform3( - mCos, - -mSin, - 0.0, - 0.0, - mSin, - mCos, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ); - - return transform3 * transform2 * transform1; - } - - static Transform3D makeTransform( - Vector2D const &anchor, - Vector2D const &position, - Vector2D const &scale, - float rotation, - std::optional skew, - std::optional skewAxis - ) { - Transform3D result = Transform3D::identity(); - if (skew.has_value() && skewAxis.has_value()) { - result = Transform3D::identity().translated(position).rotated(rotation).skewed(-skew.value(), skewAxis.value()).scaled(Vector2D(scale.x * 0.01, scale.y * 0.01)).translated(Vector2D(-anchor.x, -anchor.y)); - } else { - result = Transform3D::identity().translated(position).rotated(rotation).scaled(Vector2D(scale.x * 0.01, scale.y * 0.01)).translated(Vector2D(-anchor.x, -anchor.y)); - } - - return result; - } - - Transform3D rotated(float degrees) const; - - Transform3D translated(Vector2D const &translation) const; - - Transform3D scaled(Vector2D const &scale) const; - - Transform3D skewed(float skew, float skewAxis) const { - return Transform3D::makeSkew(skew, skewAxis) * (*this); - } - - static Transform3D identity() { - return Transform3D( - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - ); - } - - Transform3D operator*(Transform3D const &b) const; -};*/ - -/*Transform2D t2d(Transform3D const &testMatrix) { - ::CATransform3D nativeTest; - - nativeTest.m11 = testMatrix.m11; - nativeTest.m12 = testMatrix.m12; - nativeTest.m13 = testMatrix.m13; - nativeTest.m14 = testMatrix.m14; - - nativeTest.m21 = testMatrix.m21; - nativeTest.m22 = testMatrix.m22; - nativeTest.m23 = testMatrix.m23; - nativeTest.m24 = testMatrix.m24; - - nativeTest.m31 = testMatrix.m31; - nativeTest.m32 = testMatrix.m32; - nativeTest.m33 = testMatrix.m33; - nativeTest.m34 = testMatrix.m34; - - nativeTest.m41 = testMatrix.m41; - nativeTest.m42 = testMatrix.m42; - nativeTest.m43 = testMatrix.m43; - nativeTest.m44 = testMatrix.m44; - - CGAffineTransform at = CATransform3DGetAffineTransform(nativeTest); - Transform2D result = Transform2D::identity(); - simd_float3x3 *rows = (simd_float3x3 *)&result.rows(); - rows->columns[0] = simd_make_float3(at.a, at.b, 0.0); - rows->columns[1] = simd_make_float3(at.c, at.d, 0.0); - rows->columns[2] = simd_make_float3(at.tx, at.ty, 1.0); - - return result; -} - -Transform3D t3d(Transform2D const &t) { - CGAffineTransform at = CGAffineTransformMake( - t.rows().columns[0][0], t.rows().columns[0][1], - t.rows().columns[1][0], t.rows().columns[1][1], - t.rows().columns[2][0], t.rows().columns[2][1] - ); - ::CATransform3D value = CATransform3DMakeAffineTransform(at); - - Transform3D result = Transform3D::identity(); - result.m11 = value.m11; - result.m12 = value.m12; - result.m13 = value.m13; - result.m14 = value.m14; - - result.m21 = value.m21; - result.m22 = value.m22; - result.m23 = value.m23; - result.m24 = value.m24; - - result.m31 = value.m31; - result.m32 = value.m32; - result.m33 = value.m33; - result.m34 = value.m34; - - result.m41 = value.m41; - result.m42 = value.m42; - result.m43 = value.m43; - result.m44 = value.m44; - - return result; -} - -Transform3D Transform3D::operator*(Transform3D const &b) const { - if (isIdentity()) { - return b; - } - if (b.isIdentity()) { - return *this; - } - - return t3d((t2d(*this) * t2d(b))); -}*/ - -Vector1D::Vector1D(lottiejson11::Json const &json) noexcept(false) { - if (json.is_number()) { - value = json.number_value(); - } else if (json.is_array()) { - if (json.array_items().empty()) { - throw LottieParsingException(); - } - if (!json.array_items()[0].is_number()) { - throw LottieParsingException(); - } - value = json.array_items()[0].number_value(); - } else { - throw LottieParsingException(); - } -} - -lottiejson11::Json Vector1D::toJson() const { - return lottiejson11::Json(value); -} - -Vector2D::Vector2D(lottiejson11::Json const &json) noexcept(false) { - x = 0.0; - y = 0.0; - - if (json.is_array()) { - int index = 0; - - if (json.array_items().size() > index) { - if (!json.array_items()[index].is_number()) { - throw LottieParsingException(); - } - x = json.array_items()[index].number_value(); - index++; - } - - if (json.array_items().size() > index) { - if (!json.array_items()[index].is_number()) { - throw LottieParsingException(); - } - y = json.array_items()[index].number_value(); - index++; - } - } else if (json.is_object()) { - auto xAny = getAny(json.object_items(), "x"); - if (xAny.is_number()) { - x = xAny.number_value(); - } else if (xAny.is_array()) { - if (xAny.array_items().empty()) { - throw LottieParsingException(); - } - if (!xAny.array_items()[0].is_number()) { - throw LottieParsingException(); - } - x = xAny.array_items()[0].number_value(); - } - - auto yAny = getAny(json.object_items(), "y"); - if (yAny.is_number()) { - y = yAny.number_value(); - } else if (yAny.is_array()) { - if (yAny.array_items().empty()) { - throw LottieParsingException(); - } - if (!yAny.array_items()[0].is_number()) { - throw LottieParsingException(); - } - y = yAny.array_items()[0].number_value(); - } - } else { - throw LottieParsingException(); - } -} - -lottiejson11::Json Vector2D::toJson() const { - lottiejson11::Json::object result; - - result.insert(std::make_pair("x", x)); - result.insert(std::make_pair("y", y)); - - return lottiejson11::Json(result); -} - -Vector3D::Vector3D(lottiejson11::Json const &json) noexcept(false) { - if (!json.is_array()) { - throw LottieParsingException(); - } - - int index = 0; - - x = 0.0; - y = 0.0; - z = 0.0; - - if (json.array_items().size() > index) { - if (!json.array_items()[index].is_number()) { - throw LottieParsingException(); - } - x = json.array_items()[index].number_value(); - index++; - } - - if (json.array_items().size() > index) { - if (!json.array_items()[index].is_number()) { - throw LottieParsingException(); - } - y = json.array_items()[index].number_value(); - index++; - } - - if (json.array_items().size() > index) { - if (!json.array_items()[index].is_number()) { - throw LottieParsingException(); - } - z = json.array_items()[index].number_value(); - index++; - } -} - -lottiejson11::Json Vector3D::toJson() const { - lottiejson11::Json::array result; - - result.push_back(lottiejson11::Json(x)); - result.push_back(lottiejson11::Json(y)); - result.push_back(lottiejson11::Json(z)); - - return lottiejson11::Json(result); -} - -Transform2D Transform2D::_identity = Transform2D( - simd_float3x3({ - simd_make_float3(1.0f, 0.0f, 0.0f), - simd_make_float3(0.0f, 1.0f, 0.0f), - simd_make_float3(0.0f, 0.0f, 1.0f) - }) -); - -Transform2D Transform2D::makeTranslation(float tx, float ty) { - return Transform2D(simd_float3x3({ - simd_make_float3(1.0f, 0.0f, 0.0f), - simd_make_float3(0.0f, 1.0f, 0.0f), - simd_make_float3(tx, ty, 1.0f) - })); -} - -Transform2D Transform2D::makeScale(float sx, float sy) { - return Transform2D(simd_float3x3({ - simd_make_float3(sx, 0.0f, 0.0f), - simd_make_float3(0.0f, sy, 0.0f), - simd_make_float3(0.0f, 0.0f, 1.0f) - })); -} - -Transform2D Transform2D::makeRotation(float radians) { - float c = cos(radians); - float s = sin(radians); - - return Transform2D(simd_float3x3({ - simd_make_float3(c, s, 0.0f), - simd_make_float3(-s, c, 0.0f), - simd_make_float3(0.0f, 0.0f, 1.0f) - })); -} - -Transform2D Transform2D::makeSkew(float skew, float skewAxis) { - if (std::abs(skew) <= FLT_EPSILON && std::abs(skewAxis) <= FLT_EPSILON) { - return Transform2D::identity(); - } - - float mCos = cos(degreesToRadians(skewAxis)); - float mSin = sin(degreesToRadians(skewAxis)); - float aTan = tan(degreesToRadians(skew)); - - simd_float3x3 simd1 = simd_float3x3({ - simd_make_float3(mCos, -mSin, 0.0), - simd_make_float3(mSin, mCos, 0.0), - simd_make_float3(0.0, 0.0, 1.0) - }); - - simd_float3x3 simd2 = simd_float3x3({ - simd_make_float3(1.0, 0.0, 0.0), - simd_make_float3(aTan, 1.0, 0.0), - simd_make_float3(0.0, 0.0, 1.0) - }); - - simd_float3x3 simd3 = simd_float3x3({ - simd_make_float3(mCos, mSin, 0.0), - simd_make_float3(-mSin, mCos, 0.0), - simd_make_float3(0.0, 0.0, 1.0) - }); - - simd_float3x3 result = simd_mul(simd_mul(simd3, simd2), simd1); - Transform2D resultTransform(result); - - return resultTransform; -} - -Transform2D Transform2D::makeTransform( - Vector2D const &anchor, - Vector2D const &position, - Vector2D const &scale, - float rotation, - std::optional skew, - std::optional skewAxis -) { - Transform2D result = Transform2D::identity(); - if (skew.has_value() && skewAxis.has_value()) { - result = Transform2D::identity().translated(position).rotated(rotation).skewed(-skew.value(), skewAxis.value()).scaled(Vector2D(scale.x * 0.01, scale.y * 0.01)).translated(Vector2D(-anchor.x, -anchor.y)); - } else { - result = Transform2D::identity().translated(position).rotated(rotation).scaled(Vector2D(scale.x * 0.01, scale.y * 0.01)).translated(Vector2D(-anchor.x, -anchor.y)); - } - - return result; -} - -Transform2D Transform2D::rotated(float degrees) const { - return Transform2D::makeRotation(degreesToRadians(degrees)) * (*this); -} - -Transform2D Transform2D::translated(Vector2D const &translation) const { - return Transform2D::makeTranslation(translation.x, translation.y) * (*this); -} - -Transform2D Transform2D::scaled(Vector2D const &scale) const { - return Transform2D::makeScale(scale.x, scale.y) * (*this); -} - -Transform2D Transform2D::skewed(float skew, float skewAxis) const { - return Transform2D::makeSkew(skew, skewAxis) * (*this); -} - -float interpolate(float value, float to, float amount) { - return value + ((to - value) * amount); -} - -Vector1D interpolate( - Vector1D const &from, - Vector1D const &to, - float amount -) { - return Vector1D(interpolate(from.value, to.value, amount)); -} - -Vector2D interpolate( - Vector2D const &from, - Vector2D const &to, - float amount -) { - return Vector2D(interpolate(from.x, to.x, amount), interpolate(from.y, to.y, amount)); -} - - -Vector3D interpolate( - Vector3D const &from, - Vector3D const &to, - float amount -) { - return Vector3D(interpolate(from.x, to.x, amount), interpolate(from.y, to.y, amount), interpolate(from.z, to.z, amount)); -} - -static float cubicRoot(float value) { - return pow(value, 1.0 / 3.0); -} - -static float SolveQuadratic(float a, float b, float c) { - float result = (-b + sqrt((b * b) - 4 * a * c)) / (2 * a); - if (isInRangeOrEqual(result, 0.0, 1.0)) { - return result; - } - - result = (-b - sqrt((b * b) - 4 * a * c)) / (2 * a); - if (isInRangeOrEqual(result, 0.0, 1.0)) { - return result; - } - - return -1.0; -} - -inline bool isApproximatelyEqual(float value, float other) { - return std::abs(value - other) <= FLT_EPSILON; -} - -static float SolveCubic(float a, float b, float c, float d) { - if (isApproximatelyEqual(a, 0.0f)) { - return SolveQuadratic(b, c, d); - } - if (isApproximatelyEqual(d, 0.0f)) { - return 0.0; - } - b /= a; - c /= a; - d /= a; - float q = (3.0 * c - (b * b)) / 9.0; - float r = (-27.0 * d + b * (9.0 * c - 2.0 * (b * b))) / 54.0; - float disc = (q * q * q) + (r * r); - float term1 = b / 3.0; - - if (disc > 0.0) { - float s = r + sqrt(disc); - s = (s < 0) ? -cubicRoot(-s) : cubicRoot(s); - float t = r - sqrt(disc); - t = (t < 0) ? -cubicRoot(-t) : cubicRoot(t); - - float result = -term1 + s + t; - if (isInRangeOrEqual(result, 0.0, 1.0)) { - return result; - } - } else if (isApproximatelyEqual(disc, 0.0f)) { - float r13 = (r < 0) ? -cubicRoot(-r) : cubicRoot(r); - - float result = -term1 + 2.0 * r13; - if (isInRangeOrEqual(result, 0.0, 1.0)) { - return result; - } - - result = -(r13 + term1); - if (isInRangeOrEqual(result, 0.0, 1.0)) { - return result; - } - } else { - q = -q; - float dum1 = q * q * q; - dum1 = acos(r / sqrt(dum1)); - float r13 = 2.0 * sqrt(q); - - float result = -term1 + r13 * cos(dum1 / 3.0); - if (isInRangeOrEqual(result, 0.0, 1.0)) { - return result; - } - result = -term1 + r13 * cos((dum1 + 2.0 * M_PI) / 3.0); - if (isInRangeOrEqual(result, 0.0, 1.0)) { - return result; - } - result = -term1 + r13 * cos((dum1 + 4.0 * M_PI) / 3.0); - if (isInRangeOrEqual(result, 0.0, 1.0)) { - return result; - } - } - - return -1.0; -} - -float cubicBezierInterpolate(float value, Vector2D const &P0, Vector2D const &P1, Vector2D const &P2, Vector2D const &P3) { - float t = 0.0; - if (isApproximatelyEqual(value, P0.x)) { - // Handle corner cases explicitly to prevent rounding errors - t = 0.0; - } else if (isApproximatelyEqual(value, P3.x)) { - t = 1.0; - } else { - // Calculate t - float a = -P0.x + 3 * P1.x - 3 * P2.x + P3.x; - float b = 3 * P0.x - 6 * P1.x + 3 * P2.x; - float c = -3 * P0.x + 3 * P1.x; - float d = P0.x - value; - float tTemp = SolveCubic(a, b, c, d); - if (isApproximatelyEqual(tTemp, -1.0f)) { - return -1.0; - } - t = tTemp; - } - - // Calculate y from t - float oneMinusT = 1.0 - t; - return (oneMinusT * oneMinusT * oneMinusT) * P0.y + 3 * t * (oneMinusT * oneMinusT) * P1.y + 3 * (t * t) * (1 - t) * P2.y + (t * t * t) * P3.y; -} - -struct InterpolationPoint2D { - InterpolationPoint2D(Vector2D const point_, float distance_) : - point(point_), distance(distance_) { - } - - Vector2D point; - float distance; -}; - -namespace { - float interpolateFloat(float value, float to, float amount) { - return value + ((to - value) * amount); - } -} - -Vector2D Vector2D::pointOnPath(Vector2D const &to, Vector2D const &outTangent, Vector2D const &inTangent, float amount) const { - auto a = interpolate(outTangent, amount); - auto b = outTangent.interpolate(inTangent, amount); - auto c = inTangent.interpolate(to, amount); - auto d = a.interpolate(b, amount); - auto e = b.interpolate(c, amount); - auto f = d.interpolate(e, amount); - return f; -} - -Vector2D Vector2D::interpolate(Vector2D const &to, float amount) const { - return Vector2D( - interpolateFloat(x, to.x, amount), - interpolateFloat(y, to.y, amount) - ); -} - -Vector2D Vector2D::interpolate( - Vector2D const &to, - Vector2D const &outTangent, - Vector2D const &inTangent, - float amount, - int maxIterations, - int samples, - float accuracy -) const { - if (amount == 0.0) { - return *this; - } - if (amount == 1.0) { - return to; - } - - if (colinear(outTangent, inTangent) && outTangent.colinear(inTangent, to)) { - return interpolate(to, amount); - } - - float step = 1.0 / (float)samples; - - std::vector points; - points.push_back(InterpolationPoint2D(*this, 0.0)); - float totalLength = 0.0; - - Vector2D previousPoint = *this; - float previousAmount = 0.0; - - int closestPoint = 0; - - while (previousAmount < 1.0) { - previousAmount = previousAmount + step; - - if (previousAmount < amount) { - closestPoint = closestPoint + 1; - } - - auto newPoint = pointOnPath(to, outTangent, inTangent, previousAmount); - auto distance = previousPoint.distanceTo(newPoint); - totalLength = totalLength + distance; - points.push_back(InterpolationPoint2D(newPoint, totalLength)); - previousPoint = newPoint; - } - - float accurateDistance = amount * totalLength; - auto point = points[closestPoint]; - - bool foundPoint = false; - - float pointAmount = ((float)closestPoint) * step; - float nextPointAmount = pointAmount + step; - - int refineIterations = 0; - while (!foundPoint) { - refineIterations = refineIterations + 1; - /// First see if the next point is still less than the projected length. - auto nextPoint = points[std::min(closestPoint + 1, (int)points.size() - 1)]; - if (nextPoint.distance < accurateDistance) { - point = nextPoint; - closestPoint = closestPoint + 1; - pointAmount = ((float)closestPoint) * step; - nextPointAmount = pointAmount + step; - if (closestPoint == (int)points.size()) { - foundPoint = true; - } - continue; - } - if (accurateDistance < point.distance) { - closestPoint = closestPoint - 1; - if (closestPoint < 0) { - foundPoint = true; - continue; - } - point = points[closestPoint]; - pointAmount = ((float)closestPoint) * step; - nextPointAmount = pointAmount + step; - continue; - } - - /// Now we are certain the point is the closest point under the distance - auto pointDiff = nextPoint.distance - point.distance; - auto proposedPointAmount = remapFloat((accurateDistance - point.distance) / pointDiff, 0.0, 1.0, pointAmount, nextPointAmount); - - auto newPoint = pointOnPath(to, outTangent, inTangent, proposedPointAmount); - auto newDistance = point.distance + point.point.distanceTo(newPoint); - pointAmount = proposedPointAmount; - point = InterpolationPoint2D(newPoint, newDistance); - if (accurateDistance - newDistance <= accuracy || - newDistance - accurateDistance <= accuracy) { - foundPoint = true; - } - - if (refineIterations == maxIterations) { - foundPoint = true; - } - } - return point.point; -} - -::CATransform3D nativeTransform(Transform2D const &value) { - CGAffineTransform at = CGAffineTransformMake( - value.rows().columns[0][0], value.rows().columns[0][1], - value.rows().columns[1][0], value.rows().columns[1][1], - value.rows().columns[2][0], value.rows().columns[2][1] - ); - return CATransform3DMakeAffineTransform(at); - - /*::CATransform3D result; - - result.m11 = value.m11; - result.m12 = value.m12; - result.m13 = value.m13; - result.m14 = value.m14; - - result.m21 = value.m21; - result.m22 = value.m22; - result.m23 = value.m23; - result.m24 = value.m24; - - result.m31 = value.m31; - result.m32 = value.m32; - result.m33 = value.m33; - result.m34 = value.m34; - - result.m41 = value.m41; - result.m42 = value.m42; - result.m43 = value.m43; - result.m44 = value.m44; - - return result;*/ -} - -Transform2D fromNativeTransform(::CATransform3D const &value) { - CGAffineTransform at = CATransform3DGetAffineTransform(value); - return Transform2D( - simd_float3x3({ - simd_make_float3(at.a, at.b, 0.0), - simd_make_float3(at.c, at.d, 0.0), - simd_make_float3(at.tx, at.ty, 1.0) - }) - ); - - /*Transform2D result = Transform2D::identity(); - - result.m11 = value.m11; - result.m12 = value.m12; - result.m13 = value.m13; - result.m14 = value.m14; - - result.m21 = value.m21; - result.m22 = value.m22; - result.m23 = value.m23; - result.m24 = value.m24; - - result.m31 = value.m31; - result.m32 = value.m32; - result.m33 = value.m33; - result.m34 = value.m34; - - result.m41 = value.m41; - result.m42 = value.m42; - result.m43 = value.m43; - result.m44 = value.m44; - - return result;*/ -} - -/*Transform3D Transform3D::makeRotation(float radians) { - if (std::abs(radians) <= FLT_EPSILON) { - return Transform3D::identity(); - } - - float s = sin(radians); - float c = cos(radians); - - ::CGAffineTransform t = CGAffineTransformMake(c, s, -s, c, 0.0f, 0.0f); - return fromNativeTransform(CATransform3DMakeAffineTransform(t)); -} - -Transform3D Transform3D::rotated(float degrees) const { - return Transform3D::makeRotation(degreesToRadians(degrees)) * (*this); -} - -Transform3D Transform3D::translated(Vector2D const &translation) const { - return Transform3D::makeTranslation(translation.x, translation.y, 0.0f) * (*this); -} - -Transform3D Transform3D::scaled(Vector2D const &scale) const { - return Transform3D::makeScale(scale.x, scale.y, 1.0) * (*this); -} - -bool Transform3D::isInvertible() const { - return Transform2D(*this).isInvertible(); - //return std::abs(m11 * m22 - m12 * m21) >= 0.00000001; -} - -Transform3D Transform3D::inverted() const { - return Transform2D(*this).inverted().transform3D(); -}*/ - -bool CGRect::intersects(CGRect const &other) const { - return CGRectIntersectsRect(CGRectMake(x, y, width, height), CGRectMake(other.x, other.y, other.width, other.height)); -} - -bool CGRect::contains(CGRect const &other) const { - return CGRectContainsRect(CGRectMake(x, y, width, height), CGRectMake(other.x, other.y, other.width, other.height)); -} - -CGRect CGRect::intersection(CGRect const &other) const { - auto result = CGRectIntersection(CGRectMake(x, y, width, height), CGRectMake(other.x, other.y, other.width, other.height)); - return CGRect(result.origin.x, result.origin.y, result.size.width, result.size.height); -} - -CGRect CGRect::unionWith(CGRect const &other) const { - auto result = CGRectUnion(CGRectMake(x, y, width, height), CGRectMake(other.x, other.y, other.width, other.height)); - return CGRect(result.origin.x, result.origin.y, result.size.width, result.size.height); -} - -CGRect CGRect::applyingTransform(Transform2D const &transform) const { - if (transform.isIdentity()) { - return *this; - } - - Vector2D sourceTopLeft = Vector2D(x, y); - Vector2D sourceTopRight = Vector2D(x + width, y); - Vector2D sourceBottomLeft = Vector2D(x, y + height); - Vector2D sourceBottomRight = Vector2D(x + width, y + height); - - simd_float4 xs = simd_make_float4(sourceTopLeft.x, sourceTopRight.x, sourceBottomLeft.x, sourceBottomRight.x); - simd_float4 ys = simd_make_float4(sourceTopLeft.y, sourceTopRight.y, sourceBottomLeft.y, sourceBottomRight.y); - - simd_float4 rx = xs * transform.rows().columns[0][0] + ys * transform.rows().columns[1][0] + transform.rows().columns[2][0]; - simd_float4 ry = xs * transform.rows().columns[0][1] + ys * transform.rows().columns[1][1] + transform.rows().columns[2][1]; - - Vector2D topLeft = Vector2D(rx[0], ry[0]); - Vector2D topRight = Vector2D(rx[1], ry[1]); - Vector2D bottomLeft = Vector2D(rx[2], ry[2]); - Vector2D bottomRight = Vector2D(rx[3], ry[3]); - - float minX = simd_reduce_min(simd_make_float4(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x)); - float minY = simd_reduce_min(simd_make_float4(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y)); - float maxX = simd_reduce_max(simd_make_float4(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x)); - float maxY = simd_reduce_max(simd_make_float4(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y)); - - return CGRect(minX, minY, maxX - minX, maxY - minY); -} - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/TextProvider/AnimationTextProvider.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/TextProvider/AnimationTextProvider.cpp deleted file mode 100644 index 6ba1e020c8..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/TextProvider/AnimationTextProvider.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "AnimationTextProvider.hpp" - -namespace lottie { - -} diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/TextProvider/AnimationTextProvider.hpp b/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/TextProvider/AnimationTextProvider.hpp deleted file mode 100644 index dc5d324628..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/Lottie/Public/TextProvider/AnimationTextProvider.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef AnimationTextProvider_hpp -#define AnimationTextProvider_hpp - -#include -#include - -namespace lottie { - -/// Text provider is a protocol that is used to supply text to `AnimationView`. -class AnimationTextProvider { -public: - virtual std::string textFor(std::string const &keypathName, std::string const &sourceText) = 0; -}; - -/// Text provider that simply map values from dictionary -class DictionaryTextProvider: public AnimationTextProvider { -public: - DictionaryTextProvider(std::map const &values) : - _values(values) { - } - - virtual std::string textFor(std::string const &keypathName, std::string const &sourceText) override { - const auto it = _values.find(keypathName); - if (it != _values.end()) { - return it->second; - } else { - return sourceText; - } - } - -private: - std::map _values; -}; - -/// Default text provider. Uses text in the animation file -class DefaultTextProvider: public AnimationTextProvider { -public: - DefaultTextProvider() { - } - - virtual ~DefaultTextProvider() = default; - - virtual std::string textFor(std::string const &keypathName, std::string const &sourceText) override { - return sourceText; - } -}; - -} - -#endif /* AnimationTextProvider_hpp */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/LottieAnimation.mm b/submodules/TelegramUI/Components/LottieCpp/Sources/LottieAnimation.mm deleted file mode 100644 index db68b68370..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/LottieAnimation.mm +++ /dev/null @@ -1,60 +0,0 @@ -#include - -#include "Lottie/Private/Model/Animation.hpp" - -#include - -@interface LottieAnimation () { -@public - std::shared_ptr _animation; -} - -@end - -@implementation LottieAnimation - -- (instancetype _Nullable)initWithData:(NSData * _Nonnull)data { - self = [super init]; - if (self != nil) { - std::string errorText; - auto json = lottiejson11::Json::parse(std::string((uint8_t const *)data.bytes, ((uint8_t const *)data.bytes) + data.length), errorText); - if (!json.is_object()) { - return nil; - } - - try { - _animation = lottie::Animation::fromJson(json.object_items()); - } catch(...) { - return nil; - } - } - return self; -} - -- (NSInteger)frameCount { - return (NSInteger)(_animation->endFrame - _animation->startFrame); -} - -- (NSInteger)framesPerSecond { - return (NSInteger)(_animation->framerate); -} - -- (CGSize)size { - return CGSizeMake(_animation->width, _animation->height); -} - -- (NSData * _Nonnull)toJson { - lottiejson11::Json::object json = _animation->toJson(); - std::string jsonString = lottiejson11::Json(json).dump(); - return [[NSData alloc] initWithBytes:jsonString.data() length:jsonString.size()]; -} - -@end - -@implementation LottieAnimation (Internal) - -- (std::shared_ptr)animationImpl { - return _animation; -} - -@end diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/LottieAnimationContainer.mm b/submodules/TelegramUI/Components/LottieCpp/Sources/LottieAnimationContainer.mm deleted file mode 100644 index 5f06c01222..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/LottieAnimationContainer.mm +++ /dev/null @@ -1,85 +0,0 @@ -#include - -#include "Lottie/Private/MainThread/LayerContainers/MainThreadAnimationLayer.hpp" -#include "LottieAnimationInternal.h" -#include - -@interface LottieAnimationContainer () { -@public - std::shared_ptr _layer; - std::shared_ptr _bezierPathsBoundingBoxContext; -} - -@end - -@implementation LottieAnimationContainer - -- (instancetype _Nonnull)initWithAnimation:(LottieAnimation * _Nonnull)animation { - self = [super init]; - if (self != nil) { - _bezierPathsBoundingBoxContext = std::make_shared(); - - _animation = animation; - - _layer = std::make_shared( - *[animation animationImpl].get(), - std::make_shared(), - std::make_shared(), - std::make_shared() - ); - } - return self; -} - -- (void)update:(NSInteger)frame { - _layer->setCurrentFrame(frame); -} - -- (LottieRenderNode * _Nullable)getCurrentRenderTreeForSize:(CGSize)size { - return nil; -} - -- (std::shared_ptr)internalGetRootRenderTreeNode { - auto renderNode = _layer->renderTreeNode(); - return renderNode; -} - -- (int64_t)getRootRenderNodeProxy { - std::shared_ptr renderNode = [self internalGetRootRenderTreeNode]; - return (int64_t)renderNode.get(); -} - -- (LottieRenderNodeProxy)getRenderNodeProxyById:(int64_t)nodeId __attribute__((objc_direct)) { - lottie::RenderTreeNode *node = (lottie::RenderTreeNode *)nodeId; - - LottieRenderNodeProxy result; - - result.internalId = nodeId; - result.isValid = node->renderData.isValid; - - - result.isInvertedMatte = node->renderData.isInvertedMatte; - if (node->mask()) { - result.maskId = (int64_t)node->mask().get(); - } else { - result.maskId = 0; - } - result.subnodeCount = (int)node->subnodes().size(); - - return result; -} - -- (LottieRenderNodeProxy)getRenderNodeSubnodeProxyById:(int64_t)nodeId index:(int)index __attribute__((objc_direct)) { - lottie::RenderTreeNode *node = (lottie::RenderTreeNode *)nodeId; - return [self getRenderNodeProxyById:(int64_t)node->subnodes()[index].get()]; -} - -@end - -@implementation LottieAnimationContainer (Internal) - -- (std::shared_ptr)layer { - return _layer; -} - -@end diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/LottieAnimationContainerInternal.h b/submodules/TelegramUI/Components/LottieCpp/Sources/LottieAnimationContainerInternal.h deleted file mode 100644 index c5f3a105cc..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/LottieAnimationContainerInternal.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef LottieAnimationContainerInternal_h -#define LottieAnimationContainerInternal_h - -#include "Lottie/Private/MainThread/LayerContainers/MainThreadAnimationLayer.hpp" -#include - -@interface LottieAnimationContainer (Internal) - -@property (nonatomic, readonly) std::shared_ptr layer; - -@end - -#endif /* LottieAnimationContainerInternal_h */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/LottieAnimationInternal.h b/submodules/TelegramUI/Components/LottieCpp/Sources/LottieAnimationInternal.h deleted file mode 100644 index d314f023d5..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/LottieAnimationInternal.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef LottieAnimationInternal_h -#define LottieAnimationInternal_h - -#include -#include "Lottie/Private/Model/Animation.hpp" - -#include - -@interface LottieAnimation (Internal) - -- (std::shared_ptr)animationImpl; - -@end - -#endif /* LottieAnimationInternal_h */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/LottieRenderTree.h b/submodules/TelegramUI/Components/LottieCpp/Sources/LottieRenderTree.h deleted file mode 100644 index e4158c3ccb..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/LottieRenderTree.h +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef LottieRenderTree_h -#define LottieRenderTree_h - -#import - -#ifdef __cplusplus -extern "C" { -#endif - -typedef NS_ENUM(NSUInteger, LottiePathItemType) { - LottiePathItemTypeMoveTo, - LottiePathItemTypeLineTo, - LottiePathItemTypeCurveTo, - LottiePathItemTypeClose -}; - -typedef struct { - LottiePathItemType type; - CGPoint points[4]; -} LottiePathItem; - -typedef struct { - CGFloat r; - CGFloat g; - CGFloat b; - CGFloat a; -} LottieColor; - -typedef NS_ENUM(NSUInteger, LottieFillRule) { - LottieFillRuleEvenOdd, - LottieFillRuleWinding -}; - -typedef NS_ENUM(NSUInteger, LottieGradientType) { - LottieGradientTypeLinear, - LottieGradientTypeRadial -}; - -@interface LottieColorStop : NSObject - -@property (nonatomic, readonly, direct) LottieColor color; -@property (nonatomic, readonly, direct) CGFloat location; - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithColor:(LottieColor)color location:(CGFloat)location __attribute__((objc_direct)); - -@end - -@interface LottiePath : NSObject - -- (void)enumerateItems:(void (^ _Nonnull)(LottiePathItem * _Nonnull))iterate __attribute__((objc_direct)); - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithCustomData:(NSData * _Nonnull)customData __attribute__((objc_direct)); - -@end - -@interface LottieRenderContentShading : NSObject - -@end - -@interface LottieRenderContentSolidShading : LottieRenderContentShading - -@property (nonatomic, readonly, direct) LottieColor color; -@property (nonatomic, readonly, direct) CGFloat opacity; - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithColor:(LottieColor)color opacity:(CGFloat)opacity __attribute__((objc_direct)); - -@end - -@interface LottieRenderContentGradientShading : LottieRenderContentShading - -@property (nonatomic, readonly, direct) CGFloat opacity; -@property (nonatomic, readonly, direct) LottieGradientType gradientType; -@property (nonatomic, strong, readonly, direct) NSArray * _Nonnull colorStops; -@property (nonatomic, readonly, direct) CGPoint start; -@property (nonatomic, readonly, direct) CGPoint end; - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithOpacity:(CGFloat)opacity gradientType:(LottieGradientType)gradientType colorStops:(NSArray * _Nonnull)colorStops start:(CGPoint)start end:(CGPoint)end __attribute__((objc_direct)); - -@end - -@interface LottieRenderContentFill : NSObject - -@property (nonatomic, strong, readonly, direct) LottieRenderContentShading * _Nonnull shading; -@property (nonatomic, readonly, direct) LottieFillRule fillRule; - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithShading:(LottieRenderContentShading * _Nonnull)shading fillRule:(LottieFillRule)fillRule __attribute__((objc_direct)); - -@end - -@interface LottieRenderContentStroke : NSObject - -@property (nonatomic, strong, readonly, direct) LottieRenderContentShading * _Nonnull shading; -@property (nonatomic, readonly, direct) CGFloat lineWidth; -@property (nonatomic, readonly, direct) CGLineJoin lineJoin; -@property (nonatomic, readonly, direct) CGLineCap lineCap; -@property (nonatomic, readonly, direct) CGFloat miterLimit; -@property (nonatomic, readonly, direct) CGFloat dashPhase; -@property (nonatomic, strong, readonly, direct) NSArray * _Nullable dashPattern; - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithShading:(LottieRenderContentShading * _Nonnull)shading lineWidth:(CGFloat)lineWidth lineJoin:(CGLineJoin)lineJoin lineCap:(CGLineCap)lineCap miterLimit:(CGFloat)miterLimit dashPhase:(CGFloat)dashPhase dashPattern:(NSArray * _Nullable)dashPattern __attribute__((objc_direct)); - -@end - -@interface LottieRenderContent : NSObject - -@property (nonatomic, strong, readonly, direct) LottiePath * _Nonnull path; -@property (nonatomic, strong, readonly, direct) LottieRenderContentStroke * _Nullable stroke; -@property (nonatomic, strong, readonly, direct) LottieRenderContentFill * _Nullable fill; - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithPath:(LottiePath * _Nonnull)path stroke:(LottieRenderContentStroke * _Nullable)stroke fill:(LottieRenderContentFill * _Nullable)fill __attribute__((objc_direct)); - -@end - -@interface LottieRenderNode : NSObject - -@property (nonatomic, readonly, direct) CGPoint position; -@property (nonatomic, readonly, direct) CGRect bounds; -@property (nonatomic, readonly, direct) CATransform3D transform; -@property (nonatomic, readonly, direct) CGFloat opacity; -@property (nonatomic, readonly, direct) bool masksToBounds; -@property (nonatomic, readonly, direct) bool isHidden; - -@property (nonatomic, readonly, direct) CGRect globalRect; -@property (nonatomic, readonly, direct) CATransform3D globalTransform; -@property (nonatomic, readonly, direct) LottieRenderContent * _Nullable renderContent; -@property (nonatomic, readonly, direct) bool hasSimpleContents; -@property (nonatomic, readonly, direct) bool isInvertedMatte; -@property (nonatomic, readonly, direct) NSArray * _Nonnull subnodes; -@property (nonatomic, readonly, direct) LottieRenderNode * _Nullable mask; - -- (instancetype _Nonnull)init NS_UNAVAILABLE; -- (instancetype _Nonnull)initWithPosition:(CGPoint)position bounds:(CGRect)bounds transform:(CATransform3D)transform opacity:(CGFloat)opacity masksToBounds:(bool)masksToBounds isHidden:(bool)isHidden globalRect:(CGRect)globalRect globalTransform:(CATransform3D)globalTransform renderContent:(LottieRenderContent * _Nullable)renderContent hasSimpleContents:(bool)hasSimpleContents isInvertedMatte:(bool)isInvertedMatte subnodes:(NSArray * _Nonnull)subnodes mask:(LottieRenderNode * _Nullable)mask __attribute__((objc_direct)); - -@end - -#ifdef __cplusplus -} -#endif - -#endif /* LottieRenderTree_h */ diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/LottieRenderTree.mm b/submodules/TelegramUI/Components/LottieCpp/Sources/LottieRenderTree.mm deleted file mode 100644 index 9cdf512213..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/LottieRenderTree.mm +++ /dev/null @@ -1,426 +0,0 @@ -#include "LottieRenderTree.h" - -#include -#include -#import -#include "Lottie/Public/Primitives/CALayer.hpp" -#include - -namespace { - -} - -@interface LottiePath () { - std::vector _paths; - NSData *_customData; -} - -@end - -@implementation LottiePath - -- (instancetype)initWithPaths:(std::vector)paths __attribute__((objc_direct)) { - self = [super init]; - if (self != nil) { - _paths = paths; - } - return self; -} - -- (instancetype _Nonnull)initWithCustomData:(NSData * _Nonnull)customData __attribute__((objc_direct)) { - self = [super init]; - if (self != nil) { - _customData = customData; - } - return self; -} - -- (void)enumerateItems:(void (^ _Nonnull)(LottiePathItem * _Nonnull))iterate { - LottiePathItem item; - - if (_customData != nil) { - int dataOffset = 0; - int dataLength = (int)_customData.length; - uint8_t const *dataBytes = (uint8_t const *)_customData.bytes; - while (dataOffset < dataLength) { - uint8_t itemType = dataBytes[dataOffset]; - dataOffset += 1; - - switch (itemType) { - case 0: { - Float32 px; - memcpy(&px, dataBytes + dataOffset, 4); - dataOffset += 4; - - Float32 py; - memcpy(&py, dataBytes + dataOffset, 4); - dataOffset += 4; - - item.type = LottiePathItemTypeMoveTo; - item.points[0] = CGPointMake(px, py); - iterate(&item); - - break; - } - case 1: { - Float32 px; - memcpy(&px, dataBytes + dataOffset, 4); - dataOffset += 4; - - Float32 py; - memcpy(&py, dataBytes + dataOffset, 4); - dataOffset += 4; - - item.type = LottiePathItemTypeLineTo; - item.points[0] = CGPointMake(px, py); - iterate(&item); - - break; - } - case 2: { - Float32 p1x; - memcpy(&p1x, dataBytes + dataOffset, 4); - dataOffset += 4; - - Float32 p1y; - memcpy(&p1y, dataBytes + dataOffset, 4); - dataOffset += 4; - - Float32 p2x; - memcpy(&p2x, dataBytes + dataOffset, 4); - dataOffset += 4; - - Float32 p2y; - memcpy(&p2y, dataBytes + dataOffset, 4); - dataOffset += 4; - - Float32 px; - memcpy(&px, dataBytes + dataOffset, 4); - dataOffset += 4; - - Float32 py; - memcpy(&py, dataBytes + dataOffset, 4); - dataOffset += 4; - - item.type = LottiePathItemTypeCurveTo; - item.points[0] = CGPointMake(p1x, p1y); - item.points[1] = CGPointMake(p2x, p2y); - item.points[2] = CGPointMake(px, py); - iterate(&item); - - break; - } - case 3: { - item.type = LottiePathItemTypeClose; - iterate(&item); - break; - } - default: { - break; - } - } - } - } else { - for (const auto &path : _paths) { - std::optional previousElement; - for (const auto &element : path.elements()) { - if (previousElement.has_value()) { - if (previousElement->vertex.outTangentRelative().isZero() && element.vertex.inTangentRelative().isZero()) { - item.type = LottiePathItemTypeLineTo; - item.points[0] = CGPointMake(element.vertex.point.x, element.vertex.point.y); - iterate(&item); - } else { - item.type = LottiePathItemTypeCurveTo; - item.points[2] = CGPointMake(element.vertex.point.x, element.vertex.point.y); - item.points[1] = CGPointMake(element.vertex.inTangent.x, element.vertex.inTangent.y); - item.points[0] = CGPointMake(previousElement->vertex.outTangent.x, previousElement->vertex.outTangent.y); - iterate(&item); - } - } else { - item.type = LottiePathItemTypeMoveTo; - item.points[0] = CGPointMake(element.vertex.point.x, element.vertex.point.y); - iterate(&item); - } - previousElement = element; - } - if (path.closed().value_or(true)) { - item.type = LottiePathItemTypeClose; - iterate(&item); - } - } - } -} - -@end - -@implementation LottieColorStop : NSObject - -- (instancetype _Nonnull)initWithColor:(LottieColor)color location:(CGFloat)location __attribute__((objc_direct)) { - self = [super init]; - if (self != nil) { - _color = color; - _location = location; - } - return self; -} - -@end - -@implementation LottieRenderContentShading - -- (instancetype _Nonnull)init { - self = [super init]; - if (self != nil) { - } - return self; -} - -@end - -static LottieColor lottieColorFromColor(lottie::Color color) { - LottieColor result; - result.r = color.r; - result.g = color.g; - result.b = color.b; - result.a = color.a; - - return result; -} - -@implementation LottieRenderContentSolidShading - -- (instancetype _Nonnull)initWithSolidShading:(lottie::RenderTreeNodeContentItem::SolidShading *)solidShading __attribute__((objc_direct)) { - self = [super init]; - if (self != nil) { - _color = lottieColorFromColor(solidShading->color); - _opacity = solidShading->opacity; - } - return self; -} - -- (instancetype _Nonnull)initWithColor:(LottieColor)color opacity:(CGFloat)opacity { - self = [super init]; - if (self != nil) { - _color = color; - _opacity = opacity; - } - return self; -} - -@end - -@implementation LottieRenderContentGradientShading - -- (instancetype _Nonnull)initWithGradientShading:(lottie::RenderTreeNodeContentItem::GradientShading *)gradientShading __attribute__((objc_direct)) { - self = [super init]; - if (self != nil) { - _opacity = gradientShading->opacity; - - switch (gradientShading->gradientType) { - case lottie::GradientType::Radial: { - _gradientType = LottieGradientTypeRadial; - break; - } - default: { - _gradientType = LottieGradientTypeLinear; - break; - } - } - - NSMutableArray *colorStops = [[NSMutableArray alloc] initWithCapacity:gradientShading->colors.size()]; - for (size_t i = 0; i < gradientShading->colors.size(); i++) { - [colorStops addObject:[[LottieColorStop alloc] initWithColor:lottieColorFromColor(gradientShading->colors[i]) location:gradientShading->locations[i]]]; - } - _colorStops = colorStops; - - _start = CGPointMake(gradientShading->start.x, gradientShading->start.y); - _end = CGPointMake(gradientShading->end.x, gradientShading->end.y); - } - return self; -} - -- (instancetype _Nonnull)initWithOpacity:(CGFloat)opacity gradientType:(LottieGradientType)gradientType colorStops:(NSArray * _Nonnull)colorStops start:(CGPoint)start end:(CGPoint)end __attribute__((objc_direct)) { - self = [super init]; - if (self != nil) { - _opacity = opacity; - _gradientType = gradientType; - _colorStops = colorStops; - _start = start; - _end = end; - } - return self; -} - -@end - -@implementation LottieRenderContentFill - -- (instancetype _Nonnull)initWithFill:(std::shared_ptr const &)fill __attribute__((objc_direct)) { - self = [super init]; - if (self != nil) { - switch (fill->shading->type()) { - case lottie::RenderTreeNodeContentItem::ShadingType::Solid: { - _shading = [[LottieRenderContentSolidShading alloc] initWithSolidShading:(lottie::RenderTreeNodeContentItem::SolidShading *)fill->shading.get()]; - break; - } - case lottie::RenderTreeNodeContentItem::ShadingType::Gradient: { - _shading = [[LottieRenderContentGradientShading alloc] initWithGradientShading:(lottie::RenderTreeNodeContentItem::GradientShading *)fill->shading.get()]; - break; - } - default: { - abort(); - } - } - - switch (fill->rule) { - case lottie::FillRule::EvenOdd: { - _fillRule = LottieFillRuleEvenOdd; - break; - } - default: { - _fillRule = LottieFillRuleWinding; - break; - } - } - } - return self; -} - -- (instancetype _Nonnull)initWithShading:(LottieRenderContentShading * _Nonnull)shading fillRule:(LottieFillRule)fillRule __attribute__((objc_direct)) { - self = [super init]; - if (self != nil) { - _shading = shading; - _fillRule = fillRule; - } - return self; -} - -@end - -@implementation LottieRenderContentStroke - -- (instancetype _Nonnull)initWithStroke:(std::shared_ptr const &)stroke __attribute__((objc_direct)) { - self = [super init]; - if (self != nil) { - switch (stroke->shading->type()) { - case lottie::RenderTreeNodeContentItem::ShadingType::Solid: { - _shading = [[LottieRenderContentSolidShading alloc] initWithSolidShading:(lottie::RenderTreeNodeContentItem::SolidShading *)stroke->shading.get()]; - break; - } - case lottie::RenderTreeNodeContentItem::ShadingType::Gradient: { - _shading = [[LottieRenderContentGradientShading alloc] initWithGradientShading:(lottie::RenderTreeNodeContentItem::GradientShading *)stroke->shading.get()]; - break; - } - default: { - abort(); - } - } - - _lineWidth = stroke->lineWidth; - - switch (stroke->lineJoin) { - case lottie::LineJoin::Miter: { - _lineJoin = kCGLineJoinMiter; - break; - } - case lottie::LineJoin::Round: { - _lineJoin = kCGLineJoinRound; - break; - } - case lottie::LineJoin::Bevel: { - _lineJoin = kCGLineJoinBevel; - break; - } - default: { - _lineJoin = kCGLineJoinBevel; - break; - } - } - - switch (stroke->lineCap) { - case lottie::LineCap::Butt: { - _lineCap = kCGLineCapButt; - break; - } - case lottie::LineCap::Round: { - _lineCap = kCGLineCapRound; - break; - } - case lottie::LineCap::Square: { - _lineCap = kCGLineCapSquare; - break; - } - default: { - _lineCap = kCGLineCapSquare; - break; - } - } - - _miterLimit = stroke->miterLimit; - - _dashPhase = stroke->dashPhase; - - if (!stroke->dashPattern.empty()) { - NSMutableArray *dashPattern = [[NSMutableArray alloc] initWithCapacity:stroke->dashPattern.size()]; - for (auto value : stroke->dashPattern) { - [dashPattern addObject:@(value)]; - } - _dashPattern = dashPattern; - } - } - return self; -} - -- (instancetype _Nonnull)initWithShading:(LottieRenderContentShading * _Nonnull)shading lineWidth:(CGFloat)lineWidth lineJoin:(CGLineJoin)lineJoin lineCap:(CGLineCap)lineCap miterLimit:(CGFloat)miterLimit dashPhase:(CGFloat)dashPhase dashPattern:(NSArray * _Nullable)dashPattern __attribute__((objc_direct)) { - self = [super init]; - if (self != nil) { - _shading = shading; - _lineWidth = lineWidth; - _lineJoin = lineJoin; - _lineCap = lineCap; - _miterLimit = miterLimit; - _dashPhase = dashPhase; - _dashPattern = dashPattern; - } - return self; -} - -@end - -@implementation LottieRenderContent - -- (instancetype _Nonnull)initWithPath:(LottiePath * _Nonnull)path stroke:(LottieRenderContentStroke * _Nullable)stroke fill:(LottieRenderContentFill * _Nullable)fill __attribute__((objc_direct)) { - self = [super init]; - if (self != nil) { - _path = path; - _stroke = stroke; - _fill = fill; - } - return self; -} - -@end - -@implementation LottieRenderNode - -- (instancetype _Nonnull)initWithPosition:(CGPoint)position bounds:(CGRect)bounds transform:(CATransform3D)transform opacity:(CGFloat)opacity masksToBounds:(bool)masksToBounds isHidden:(bool)isHidden globalRect:(CGRect)globalRect globalTransform:(CATransform3D)globalTransform renderContent:(LottieRenderContent * _Nullable)renderContent hasSimpleContents:(bool)hasSimpleContents isInvertedMatte:(bool)isInvertedMatte subnodes:(NSArray * _Nonnull)subnodes mask:(LottieRenderNode * _Nullable)mask __attribute__((objc_direct)) { - self = [super init]; - if (self != nil) { - _position = position; - _bounds = bounds; - _transform = transform; - _opacity = opacity; - _masksToBounds = masksToBounds; - _isHidden = isHidden; - _globalRect = globalRect; - _globalTransform= globalTransform; - _renderContent = renderContent; - _hasSimpleContents = hasSimpleContents; - _isInvertedMatte = isInvertedMatte; - _subnodes = subnodes; - _mask = mask; - } - return self; -} - -@end diff --git a/submodules/TelegramUI/Components/LottieCpp/Sources/lottiejson11/lottiejson11.cpp b/submodules/TelegramUI/Components/LottieCpp/Sources/lottiejson11/lottiejson11.cpp deleted file mode 100644 index f5a69b64e8..0000000000 --- a/submodules/TelegramUI/Components/LottieCpp/Sources/lottiejson11/lottiejson11.cpp +++ /dev/null @@ -1,790 +0,0 @@ -/* Copyright (c) 2013 Dropbox, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include - -namespace lottiejson11 { - -static const int max_depth = 200; - -using std::string; -using std::vector; -using std::map; -using std::make_shared; -using std::initializer_list; -using std::move; - -/* Helper for representing null - just a do-nothing struct, plus comparison - * operators so the helpers in JsonValue work. We can't use nullptr_t because - * it may not be orderable. - */ -struct NullStruct { - bool operator==(NullStruct) const { return true; } - bool operator<(NullStruct) const { return false; } -}; - -/* * * * * * * * * * * * * * * * * * * * - * Serialization - */ - -static void dump(NullStruct, string &out) { - out += "null"; -} - -static void dump(double value, string &out) { - if (std::isfinite(value)) { - char buf[32]; - snprintf(buf, sizeof buf, "%.17g", value); - out += buf; - } else { - out += "null"; - } -} - -static void dump(int value, string &out) { - char buf[32]; - snprintf(buf, sizeof buf, "%d", value); - out += buf; -} - -static void dump(bool value, string &out) { - out += value ? "true" : "false"; -} - -static void dump(const string &value, string &out) { - out += '"'; - for (size_t i = 0; i < value.length(); i++) { - const char ch = value[i]; - if (ch == '\\') { - out += "\\\\"; - } else if (ch == '"') { - out += "\\\""; - } else if (ch == '\b') { - out += "\\b"; - } else if (ch == '\f') { - out += "\\f"; - } else if (ch == '\n') { - out += "\\n"; - } else if (ch == '\r') { - out += "\\r"; - } else if (ch == '\t') { - out += "\\t"; - } else if (static_cast(ch) <= 0x1f) { - char buf[8]; - snprintf(buf, sizeof buf, "\\u%04x", ch); - out += buf; - } else if (static_cast(ch) == 0xe2 && static_cast(value[i+1]) == 0x80 - && static_cast(value[i+2]) == 0xa8) { - out += "\\u2028"; - i += 2; - } else if (static_cast(ch) == 0xe2 && static_cast(value[i+1]) == 0x80 - && static_cast(value[i+2]) == 0xa9) { - out += "\\u2029"; - i += 2; - } else { - out += ch; - } - } - out += '"'; -} - -static void dump(const Json::array &values, string &out) { - bool first = true; - out += "["; - for (const auto &value : values) { - if (!first) - out += ", "; - value.dump(out); - first = false; - } - out += "]"; -} - -static void dump(const Json::object &values, string &out) { - bool first = true; - out += "{"; - for (const auto &kv : values) { - if (!first) - out += ", "; - dump(kv.first, out); - out += ": "; - kv.second.dump(out); - first = false; - } - out += "}"; -} - -void Json::dump(string &out) const { - m_ptr->dump(out); -} - -/* * * * * * * * * * * * * * * * * * * * - * Value wrappers - */ - -template -class Value : public JsonValue { -protected: - - // Constructors - explicit Value(const T &value) : m_value(value) {} - explicit Value(T &&value) : m_value(std::move(value)) {} - - // Get type tag - Json::Type type() const override { - return tag; - } - - // Comparisons - bool equals(const JsonValue * other) const override { - return m_value == static_cast *>(other)->m_value; - } - bool less(const JsonValue * other) const override { - return m_value < static_cast *>(other)->m_value; - } - - const T m_value; - void dump(string &out) const override { lottiejson11::dump(m_value, out); } -}; - -class JsonDouble final : public Value { - double number_value() const override { return m_value; } - int int_value() const override { return static_cast(m_value); } - bool equals(const JsonValue * other) const override { return m_value == other->number_value(); } - bool less(const JsonValue * other) const override { return m_value < other->number_value(); } -public: - explicit JsonDouble(double value) : Value(value) {} -}; - -class JsonInt final : public Value { - double number_value() const override { return m_value; } - int int_value() const override { return m_value; } - bool equals(const JsonValue * other) const override { return m_value == other->number_value(); } - bool less(const JsonValue * other) const override { return m_value < other->number_value(); } -public: - explicit JsonInt(int value) : Value(value) {} -}; - -class JsonBoolean final : public Value { - bool bool_value() const override { return m_value; } -public: - explicit JsonBoolean(bool value) : Value(value) {} -}; - -class JsonString final : public Value { - const string &string_value() const override { return m_value; } -public: - explicit JsonString(const string &value) : Value(value) {} - explicit JsonString(string &&value) : Value(std::move(value)) {} -}; - -class JsonArray final : public Value { - const Json::array &array_items() const override { return m_value; } - const Json & operator[](size_t i) const override; -public: - explicit JsonArray(const Json::array &value) : Value(value) {} - explicit JsonArray(Json::array &&value) : Value(std::move(value)) {} -}; - -class JsonObject final : public Value { - const Json::object &object_items() const override { return m_value; } - const Json & operator[](const string &key) const override; -public: - explicit JsonObject(const Json::object &value) : Value(value) {} - explicit JsonObject(Json::object &&value) : Value(std::move(value)) {} -}; - -class JsonNull final : public Value { -public: - JsonNull() : Value({}) {} -}; - -/* * * * * * * * * * * * * * * * * * * * - * Static globals - static-init-safe - */ -struct Statics { - const std::shared_ptr null = make_shared(); - const std::shared_ptr t = make_shared(true); - const std::shared_ptr f = make_shared(false); - const string empty_string; - const vector empty_vector; - const map empty_map; - Statics() {} -}; - -static const Statics & statics() { - static const Statics s {}; - return s; -} - -static const Json & static_null() { - // This has to be separate, not in Statics, because Json() accesses statics().null. - static const Json json_null; - return json_null; -} - -/* * * * * * * * * * * * * * * * * * * * - * Constructors - */ - -Json::Json() noexcept : m_ptr(statics().null) {} -Json::Json(std::nullptr_t) noexcept : m_ptr(statics().null) {} -Json::Json(double value) : m_ptr(make_shared(value)) {} -Json::Json(int value) : m_ptr(make_shared(value)) {} -Json::Json(bool value) : m_ptr(value ? statics().t : statics().f) {} -Json::Json(const string &value) : m_ptr(make_shared(value)) {} -Json::Json(string &&value) : m_ptr(make_shared(std::move(value))) {} -Json::Json(const char * value) : m_ptr(make_shared(value)) {} -Json::Json(const Json::array &values) : m_ptr(make_shared(values)) {} -Json::Json(Json::array &&values) : m_ptr(make_shared(std::move(values))) {} -Json::Json(const Json::object &values) : m_ptr(make_shared(values)) {} -Json::Json(Json::object &&values) : m_ptr(make_shared(std::move(values))) {} - -/* * * * * * * * * * * * * * * * * * * * - * Accessors - */ - -Json::Type Json::type() const { return m_ptr->type(); } -double Json::number_value() const { return m_ptr->number_value(); } -int Json::int_value() const { return m_ptr->int_value(); } -bool Json::bool_value() const { return m_ptr->bool_value(); } -const string & Json::string_value() const { return m_ptr->string_value(); } -const vector & Json::array_items() const { return m_ptr->array_items(); } -const map & Json::object_items() const { return m_ptr->object_items(); } -const Json & Json::operator[] (size_t i) const { return (*m_ptr)[i]; } -const Json & Json::operator[] (const string &key) const { return (*m_ptr)[key]; } - -double JsonValue::number_value() const { return 0; } -int JsonValue::int_value() const { return 0; } -bool JsonValue::bool_value() const { return false; } -const string & JsonValue::string_value() const { return statics().empty_string; } -const vector & JsonValue::array_items() const { return statics().empty_vector; } -const map & JsonValue::object_items() const { return statics().empty_map; } -const Json & JsonValue::operator[] (size_t) const { return static_null(); } -const Json & JsonValue::operator[] (const string &) const { return static_null(); } - -const Json & JsonObject::operator[] (const string &key) const { - auto iter = m_value.find(key); - return (iter == m_value.end()) ? static_null() : iter->second; -} -const Json & JsonArray::operator[] (size_t i) const { - if (i >= m_value.size()) return static_null(); - else return m_value[i]; -} - -/* * * * * * * * * * * * * * * * * * * * - * Comparison - */ - -bool Json::operator== (const Json &other) const { - if (m_ptr == other.m_ptr) - return true; - if (m_ptr->type() != other.m_ptr->type()) - return false; - - return m_ptr->equals(other.m_ptr.get()); -} - -bool Json::operator< (const Json &other) const { - if (m_ptr == other.m_ptr) - return false; - if (m_ptr->type() != other.m_ptr->type()) - return m_ptr->type() < other.m_ptr->type(); - - return m_ptr->less(other.m_ptr.get()); -} - -/* * * * * * * * * * * * * * * * * * * * - * Parsing - */ - -/* esc(c) - * - * Format char c suitable for printing in an error message. - */ -static inline string esc(char c) { - char buf[12]; - if (static_cast(c) >= 0x20 && static_cast(c) <= 0x7f) { - snprintf(buf, sizeof buf, "'%c' (%d)", c, c); - } else { - snprintf(buf, sizeof buf, "(%d)", c); - } - return string(buf); -} - -static inline bool in_range(long x, long lower, long upper) { - return (x >= lower && x <= upper); -} - -namespace { -/* JsonParser - * - * Object that tracks all state of an in-progress parse. - */ -struct JsonParser final { - - /* State - */ - const string &str; - size_t i; - string &err; - bool failed; - const JsonParse strategy; - - /* fail(msg, err_ret = Json()) - * - * Mark this parse as failed. - */ - Json fail(string &&msg) { - return fail(std::move(msg), Json()); - } - - template - T fail(string &&msg, const T err_ret) { - if (!failed) - err = std::move(msg); - failed = true; - return err_ret; - } - - /* consume_whitespace() - * - * Advance until the current character is non-whitespace. - */ - void consume_whitespace() { - while (str[i] == ' ' || str[i] == '\r' || str[i] == '\n' || str[i] == '\t') - i++; - } - - /* consume_comment() - * - * Advance comments (c-style inline and multiline). - */ - bool consume_comment() { - bool comment_found = false; - if (str[i] == '/') { - i++; - if (i == str.size()) - return fail("unexpected end of input after start of comment", false); - if (str[i] == '/') { // inline comment - i++; - // advance until next line, or end of input - while (i < str.size() && str[i] != '\n') { - i++; - } - comment_found = true; - } - else if (str[i] == '*') { // multiline comment - i++; - if (i > str.size()-2) - return fail("unexpected end of input inside multi-line comment", false); - // advance until closing tokens - while (!(str[i] == '*' && str[i+1] == '/')) { - i++; - if (i > str.size()-2) - return fail( - "unexpected end of input inside multi-line comment", false); - } - i += 2; - comment_found = true; - } - else - return fail("malformed comment", false); - } - return comment_found; - } - - /* consume_garbage() - * - * Advance until the current character is non-whitespace and non-comment. - */ - void consume_garbage() { - consume_whitespace(); - if(strategy == JsonParse::COMMENTS) { - bool comment_found = false; - do { - comment_found = consume_comment(); - if (failed) return; - consume_whitespace(); - } - while(comment_found); - } - } - - /* get_next_token() - * - * Return the next non-whitespace character. If the end of the input is reached, - * flag an error and return 0. - */ - char get_next_token() { - consume_garbage(); - if (failed) return static_cast(0); - if (i == str.size()) - return fail("unexpected end of input", static_cast(0)); - - return str[i++]; - } - - /* encode_utf8(pt, out) - * - * Encode pt as UTF-8 and add it to out. - */ - void encode_utf8(long pt, string & out) { - if (pt < 0) - return; - - if (pt < 0x80) { - out += static_cast(pt); - } else if (pt < 0x800) { - out += static_cast((pt >> 6) | 0xC0); - out += static_cast((pt & 0x3F) | 0x80); - } else if (pt < 0x10000) { - out += static_cast((pt >> 12) | 0xE0); - out += static_cast(((pt >> 6) & 0x3F) | 0x80); - out += static_cast((pt & 0x3F) | 0x80); - } else { - out += static_cast((pt >> 18) | 0xF0); - out += static_cast(((pt >> 12) & 0x3F) | 0x80); - out += static_cast(((pt >> 6) & 0x3F) | 0x80); - out += static_cast((pt & 0x3F) | 0x80); - } - } - - /* parse_string() - * - * Parse a string, starting at the current position. - */ - string parse_string() { - string out; - long last_escaped_codepoint = -1; - while (true) { - if (i == str.size()) - return fail("unexpected end of input in string", ""); - - char ch = str[i++]; - - if (ch == '"') { - encode_utf8(last_escaped_codepoint, out); - return out; - } - - if (in_range(ch, 0, 0x1f)) - return fail("unescaped " + esc(ch) + " in string", ""); - - // The usual case: non-escaped characters - if (ch != '\\') { - encode_utf8(last_escaped_codepoint, out); - last_escaped_codepoint = -1; - out += ch; - continue; - } - - // Handle escapes - if (i == str.size()) - return fail("unexpected end of input in string", ""); - - ch = str[i++]; - - if (ch == 'u') { - // Extract 4-byte escape sequence - string esc = str.substr(i, 4); - // Explicitly check length of the substring. The following loop - // relies on std::string returning the terminating NUL when - // accessing str[length]. Checking here reduces brittleness. - if (esc.length() < 4) { - return fail("bad \\u escape: " + esc, ""); - } - for (size_t j = 0; j < 4; j++) { - if (!in_range(esc[j], 'a', 'f') && !in_range(esc[j], 'A', 'F') - && !in_range(esc[j], '0', '9')) - return fail("bad \\u escape: " + esc, ""); - } - - long codepoint = strtol(esc.data(), nullptr, 16); - - // JSON specifies that characters outside the BMP shall be encoded as a pair - // of 4-hex-digit \u escapes encoding their surrogate pair components. Check - // whether we're in the middle of such a beast: the previous codepoint was an - // escaped lead (high) surrogate, and this is a trail (low) surrogate. - if (in_range(last_escaped_codepoint, 0xD800, 0xDBFF) - && in_range(codepoint, 0xDC00, 0xDFFF)) { - // Reassemble the two surrogate pairs into one astral-plane character, per - // the UTF-16 algorithm. - encode_utf8((((last_escaped_codepoint - 0xD800) << 10) - | (codepoint - 0xDC00)) + 0x10000, out); - last_escaped_codepoint = -1; - } else { - encode_utf8(last_escaped_codepoint, out); - last_escaped_codepoint = codepoint; - } - - i += 4; - continue; - } - - encode_utf8(last_escaped_codepoint, out); - last_escaped_codepoint = -1; - - if (ch == 'b') { - out += '\b'; - } else if (ch == 'f') { - out += '\f'; - } else if (ch == 'n') { - out += '\n'; - } else if (ch == 'r') { - out += '\r'; - } else if (ch == 't') { - out += '\t'; - } else if (ch == '"' || ch == '\\' || ch == '/') { - out += ch; - } else { - return fail("invalid escape character " + esc(ch), ""); - } - } - } - - /* parse_number() - * - * Parse a double. - */ - Json parse_number() { - size_t start_pos = i; - - if (str[i] == '-') - i++; - - // Integer part - if (str[i] == '0') { - i++; - if (in_range(str[i], '0', '9')) - return fail("leading 0s not permitted in numbers"); - } else if (in_range(str[i], '1', '9')) { - i++; - while (in_range(str[i], '0', '9')) - i++; - } else { - return fail("invalid " + esc(str[i]) + " in number"); - } - - if (str[i] != '.' && str[i] != 'e' && str[i] != 'E' - && (i - start_pos) <= static_cast(std::numeric_limits::digits10)) { - return std::atoi(str.c_str() + start_pos); - } - - // Decimal part - if (str[i] == '.') { - i++; - if (!in_range(str[i], '0', '9')) - return fail("at least one digit required in fractional part"); - - while (in_range(str[i], '0', '9')) - i++; - } - - // Exponent part - if (str[i] == 'e' || str[i] == 'E') { - i++; - - if (str[i] == '+' || str[i] == '-') - i++; - - if (!in_range(str[i], '0', '9')) - return fail("at least one digit required in exponent"); - - while (in_range(str[i], '0', '9')) - i++; - } - - return std::strtod(str.c_str() + start_pos, nullptr); - } - - /* expect(str, res) - * - * Expect that 'str' starts at the character that was just read. If it does, advance - * the input and return res. If not, flag an error. - */ - Json expect(const string &expected, Json res) { - assert(i != 0); - i--; - if (str.compare(i, expected.length(), expected) == 0) { - i += expected.length(); - return res; - } else { - return fail("parse error: expected " + expected + ", got " + str.substr(i, expected.length())); - } - } - - /* parse_json() - * - * Parse a JSON object. - */ - Json parse_json(int depth) { - if (depth > max_depth) { - return fail("exceeded maximum nesting depth"); - } - - char ch = get_next_token(); - if (failed) - return Json(); - - if (ch == '-' || (ch >= '0' && ch <= '9')) { - i--; - return parse_number(); - } - - if (ch == 't') - return expect("true", true); - - if (ch == 'f') - return expect("false", false); - - if (ch == 'n') - return expect("null", Json()); - - if (ch == '"') - return parse_string(); - - if (ch == '{') { - map data; - ch = get_next_token(); - if (ch == '}') - return data; - - while (1) { - if (ch != '"') - return fail("expected '\"' in object, got " + esc(ch)); - - string key = parse_string(); - if (failed) - return Json(); - - ch = get_next_token(); - if (ch != ':') - return fail("expected ':' in object, got " + esc(ch)); - - data[std::move(key)] = parse_json(depth + 1); - if (failed) - return Json(); - - ch = get_next_token(); - if (ch == '}') - break; - if (ch != ',') - return fail("expected ',' in object, got " + esc(ch)); - - ch = get_next_token(); - } - return data; - } - - if (ch == '[') { - vector data; - ch = get_next_token(); - if (ch == ']') - return data; - - while (1) { - i--; - data.push_back(parse_json(depth + 1)); - if (failed) - return Json(); - - ch = get_next_token(); - if (ch == ']') - break; - if (ch != ',') - return fail("expected ',' in list, got " + esc(ch)); - - ch = get_next_token(); - (void)ch; - } - return data; - } - - return fail("expected value, got " + esc(ch)); - } -}; -}//namespace { - -Json Json::parse(const string &in, string &err, JsonParse strategy) { - JsonParser parser { in, 0, err, false, strategy }; - Json result = parser.parse_json(0); - - // Check for any trailing garbage - parser.consume_garbage(); - if (parser.failed) - return Json(); - if (parser.i != in.size()) - return parser.fail("unexpected trailing " + esc(in[parser.i])); - - return result; -} - -// Documented in lottiejson11.hpp -vector Json::parse_multi(const string &in, - std::string::size_type &parser_stop_pos, - string &err, - JsonParse strategy) { - JsonParser parser { in, 0, err, false, strategy }; - parser_stop_pos = 0; - vector json_vec; - while (parser.i != in.size() && !parser.failed) { - json_vec.push_back(parser.parse_json(0)); - if (parser.failed) - break; - - // Check for another object - parser.consume_garbage(); - if (parser.failed) - break; - parser_stop_pos = parser.i; - } - return json_vec; -} - -/* * * * * * * * * * * * * * * * * * * * - * Shape-checking - */ - -bool Json::has_shape(const shape & types, string & err) const { - if (!is_object()) { - err = "expected JSON object, got " + dump(); - return false; - } - - const auto& obj_items = object_items(); - for (auto & item : types) { - const auto it = obj_items.find(item.first); - if (it == obj_items.cend() || it->second.type() != item.second) { - err = "bad type for " + item.first + " in " + dump(); - return false; - } - } - - return true; -} - -} // namespace lottiejson11 diff --git a/submodules/TelegramUI/Components/LottieMetal/BUILD b/submodules/TelegramUI/Components/LottieMetal/BUILD index dd63b1b0eb..6b3709b2f4 100644 --- a/submodules/TelegramUI/Components/LottieMetal/BUILD +++ b/submodules/TelegramUI/Components/LottieMetal/BUILD @@ -60,7 +60,7 @@ swift_library( "//submodules/AnimatedStickerNode", "//submodules/GZip", "//submodules/MetalEngine", - "//submodules/TelegramUI/Components/LottieCpp", + "//submodules/LottieCpp", "//submodules/Components/HierarchyTrackingLayer", ], visibility = [