mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Lottie
This commit is contained in:
parent
41c88223b4
commit
814852d902
@ -6,6 +6,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace lottieRendering {
|
namespace lottieRendering {
|
||||||
|
|
||||||
@ -41,6 +42,20 @@ enum class BlendMode {
|
|||||||
DestinationOut
|
DestinationOut
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class PathCommandType {
|
||||||
|
MoveTo,
|
||||||
|
LineTo,
|
||||||
|
CurveTo,
|
||||||
|
Close
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PathCommandType type;
|
||||||
|
CGPoint points[4];
|
||||||
|
} PathCommand;
|
||||||
|
|
||||||
|
typedef std::function<void(std::function<void(PathCommand const &)>)> CanvasPathEnumerator;
|
||||||
|
|
||||||
class Canvas {
|
class Canvas {
|
||||||
public:
|
public:
|
||||||
virtual ~Canvas() = default;
|
virtual ~Canvas() = default;
|
||||||
@ -53,13 +68,13 @@ public:
|
|||||||
virtual void saveState() = 0;
|
virtual void saveState() = 0;
|
||||||
virtual void restoreState() = 0;
|
virtual void restoreState() = 0;
|
||||||
|
|
||||||
virtual void fillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::FillRule fillRule, lottie::Color const &color) = 0;
|
virtual void fillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, lottie::Color const &color) = 0;
|
||||||
virtual void linearGradientFillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) = 0;
|
virtual void linearGradientFillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) = 0;
|
||||||
virtual void radialGradientFillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) = 0;
|
virtual void radialGradientFillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) = 0;
|
||||||
|
|
||||||
virtual void strokePath(std::shared_ptr<lottie::CGPath> const &path, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, lottie::Color const &color) = 0;
|
virtual void strokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, lottie::Color const &color) = 0;
|
||||||
virtual void linearGradientStrokePath(std::shared_ptr<lottie::CGPath> const &path, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) = 0;
|
virtual void linearGradientStrokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) = 0;
|
||||||
virtual void radialGradientStrokePath(std::shared_ptr<lottie::CGPath> const &path, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) = 0;
|
virtual void radialGradientStrokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) = 0;
|
||||||
|
|
||||||
virtual void fill(lottie::CGRect const &rect, lottie::Color const &fillColor) = 0;
|
virtual void fill(lottie::CGRect const &rect, lottie::Color const &fillColor) = 0;
|
||||||
virtual void setBlendMode(BlendMode blendMode) = 0;
|
virtual void setBlendMode(BlendMode blendMode) = 0;
|
||||||
@ -67,7 +82,6 @@ public:
|
|||||||
virtual void setAlpha(float alpha) = 0;
|
virtual void setAlpha(float alpha) = 0;
|
||||||
|
|
||||||
virtual void concatenate(lottie::CATransform3D const &transform) = 0;
|
virtual void concatenate(lottie::CATransform3D const &transform) = 0;
|
||||||
virtual lottie::CATransform3D currentTransform() = 0;
|
|
||||||
|
|
||||||
virtual void draw(std::shared_ptr<Canvas> const &other, lottie::CGRect const &rect) = 0;
|
virtual void draw(std::shared_ptr<Canvas> const &other, lottie::CGRect const &rect) = 0;
|
||||||
};
|
};
|
||||||
|
@ -29,19 +29,18 @@ public:
|
|||||||
virtual void saveState() override;
|
virtual void saveState() override;
|
||||||
virtual void restoreState() override;
|
virtual void restoreState() override;
|
||||||
|
|
||||||
virtual void fillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::FillRule fillRule, lottie::Color const &color) override;
|
virtual void fillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, lottie::Color const &color) override;
|
||||||
virtual void linearGradientFillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) override;
|
virtual void linearGradientFillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) override;
|
||||||
virtual void radialGradientFillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) override;
|
virtual void radialGradientFillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) override;
|
||||||
|
|
||||||
virtual void strokePath(std::shared_ptr<lottie::CGPath> const &path, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, lottie::Color const &color) override;
|
virtual void strokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, lottie::Color const &color) override;
|
||||||
virtual void linearGradientStrokePath(std::shared_ptr<lottie::CGPath> const &path, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) override;
|
virtual void linearGradientStrokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) override;
|
||||||
virtual void radialGradientStrokePath(std::shared_ptr<lottie::CGPath> const &path, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) override;
|
virtual void radialGradientStrokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) override;
|
||||||
|
|
||||||
virtual void fill(lottie::CGRect const &rect, lottie::Color const &fillColor) override;
|
virtual void fill(lottie::CGRect const &rect, lottie::Color const &fillColor) override;
|
||||||
virtual void setBlendMode(BlendMode blendMode) override;
|
virtual void setBlendMode(BlendMode blendMode) override;
|
||||||
virtual void setAlpha(float alpha) override;
|
virtual void setAlpha(float alpha) override;
|
||||||
virtual void concatenate(lottie::CATransform3D const &transform) override;
|
virtual void concatenate(lottie::CATransform3D const &transform) override;
|
||||||
virtual lottie::CATransform3D currentTransform() override;
|
|
||||||
|
|
||||||
virtual std::shared_ptr<Image> makeImage() const;
|
virtual std::shared_ptr<Image> makeImage() const;
|
||||||
virtual void draw(std::shared_ptr<Canvas> const &other, lottie::CGRect const &rect) override;
|
virtual void draw(std::shared_ptr<Canvas> const &other, lottie::CGRect const &rect) override;
|
||||||
|
@ -11,6 +11,52 @@ int alignUp(int size, int align) {
|
|||||||
return (size + alignmentMask) & ~alignmentMask;
|
return (size + alignmentMask) & ~alignmentMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool addEnumeratedPath(CGContextRef context, CanvasPathEnumerator const &enumeratePath) {
|
||||||
|
bool isEmpty = true;
|
||||||
|
|
||||||
|
enumeratePath([&](PathCommand const &command) {
|
||||||
|
switch (command.type) {
|
||||||
|
case PathCommandType::MoveTo: {
|
||||||
|
if (isEmpty) {
|
||||||
|
isEmpty = false;
|
||||||
|
CGContextBeginPath(context);
|
||||||
|
}
|
||||||
|
CGContextMoveToPoint(context, command.points[0].x, command.points[0].y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PathCommandType::LineTo: {
|
||||||
|
if (isEmpty) {
|
||||||
|
isEmpty = false;
|
||||||
|
CGContextBeginPath(context);
|
||||||
|
}
|
||||||
|
CGContextAddLineToPoint(context, command.points[0].x, command.points[0].y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PathCommandType::CurveTo: {
|
||||||
|
if (isEmpty) {
|
||||||
|
isEmpty = false;
|
||||||
|
CGContextBeginPath(context);
|
||||||
|
}
|
||||||
|
CGContextAddCurveToPoint(context, command.points[0].x, command.points[0].y, command.points[1].x, command.points[1].y, command.points[2].x, command.points[2].y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PathCommandType::Close: {
|
||||||
|
if (isEmpty) {
|
||||||
|
isEmpty = false;
|
||||||
|
CGContextBeginPath(context);
|
||||||
|
}
|
||||||
|
CGContextClosePath(context);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return !isEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageImpl::ImageImpl(::CGImageRef image) {
|
ImageImpl::ImageImpl(::CGImageRef image) {
|
||||||
@ -87,11 +133,10 @@ void CanvasImpl::restoreState() {
|
|||||||
CGContextRestoreGState(_context);
|
CGContextRestoreGState(_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasImpl::fillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::FillRule fillRule, lottie::Color const &color) {
|
void CanvasImpl::fillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, lottie::Color const &color) {
|
||||||
CGContextBeginPath(_context);
|
if (!addEnumeratedPath(_context, enumeratePath)) {
|
||||||
lottie::CGPathCocoaImpl::withNativePath(path, [context = _context](CGPathRef nativePath) {
|
return;
|
||||||
CGContextAddPath(context, nativePath);
|
}
|
||||||
});
|
|
||||||
|
|
||||||
CGFloat components[4] = { color.r, color.g, color.b, color.a };
|
CGFloat components[4] = { color.r, color.g, color.b, color.a };
|
||||||
CGColorRef nativeColor = CGColorCreate(CGBitmapContextGetColorSpace(_topContext), components);
|
CGColorRef nativeColor = CGColorCreate(CGBitmapContextGetColorSpace(_topContext), components);
|
||||||
@ -110,12 +155,13 @@ void CanvasImpl::fillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::F
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasImpl::linearGradientFillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) {
|
void CanvasImpl::linearGradientFillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) {
|
||||||
CGContextSaveGState(_context);
|
CGContextSaveGState(_context);
|
||||||
CGContextBeginPath(_context);
|
|
||||||
lottie::CGPathCocoaImpl::withNativePath(path, [context = _context](CGPathRef nativePath) {
|
if (!addEnumeratedPath(_context, enumeratePath)) {
|
||||||
CGContextAddPath(context, nativePath);
|
CGContextRestoreGState(_context);
|
||||||
});
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (fillRule) {
|
switch (fillRule) {
|
||||||
case lottie::FillRule::EvenOdd: {
|
case lottie::FillRule::EvenOdd: {
|
||||||
@ -155,12 +201,13 @@ void CanvasImpl::linearGradientFillPath(std::shared_ptr<lottie::CGPath> const &p
|
|||||||
CGContextRestoreGState(_context);
|
CGContextRestoreGState(_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasImpl::radialGradientFillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) {
|
void CanvasImpl::radialGradientFillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) {
|
||||||
CGContextSaveGState(_context);
|
CGContextSaveGState(_context);
|
||||||
CGContextBeginPath(_context);
|
|
||||||
lottie::CGPathCocoaImpl::withNativePath(path, [context = _context](CGPathRef nativePath) {
|
if (!addEnumeratedPath(_context, enumeratePath)) {
|
||||||
CGContextAddPath(context, nativePath);
|
CGContextRestoreGState(_context);
|
||||||
});
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (fillRule) {
|
switch (fillRule) {
|
||||||
case lottie::FillRule::EvenOdd: {
|
case lottie::FillRule::EvenOdd: {
|
||||||
@ -200,11 +247,10 @@ void CanvasImpl::radialGradientFillPath(std::shared_ptr<lottie::CGPath> const &p
|
|||||||
CGContextRestoreGState(_context);
|
CGContextRestoreGState(_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasImpl::strokePath(std::shared_ptr<lottie::CGPath> const &path, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, lottie::Color const &color) {
|
void CanvasImpl::strokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, lottie::Color const &color) {
|
||||||
CGContextBeginPath(_context);
|
if (!addEnumeratedPath(_context, enumeratePath)) {
|
||||||
lottie::CGPathCocoaImpl::withNativePath(path, [context = _context](CGPathRef nativePath) {
|
return;
|
||||||
CGContextAddPath(context, nativePath);
|
}
|
||||||
});
|
|
||||||
|
|
||||||
CGFloat components[4] = { color.r, color.g, color.b, color.a };
|
CGFloat components[4] = { color.r, color.g, color.b, color.a };
|
||||||
CGColorRef nativeColor = CGColorCreate(CGBitmapContextGetColorSpace(_topContext), components);
|
CGColorRef nativeColor = CGColorCreate(CGBitmapContextGetColorSpace(_topContext), components);
|
||||||
@ -261,12 +307,12 @@ void CanvasImpl::strokePath(std::shared_ptr<lottie::CGPath> const &path, float l
|
|||||||
CGContextStrokePath(_context);
|
CGContextStrokePath(_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasImpl::linearGradientStrokePath(std::shared_ptr<lottie::CGPath> const &path, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) {
|
void CanvasImpl::linearGradientStrokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) {
|
||||||
CGContextSaveGState(_context);
|
CGContextSaveGState(_context);
|
||||||
CGContextBeginPath(_context);
|
if (!addEnumeratedPath(_context, enumeratePath)) {
|
||||||
lottie::CGPathCocoaImpl::withNativePath(path, [context = _context](CGPathRef nativePath) {
|
CGContextRestoreGState(_context);
|
||||||
CGContextAddPath(context, nativePath);
|
return;
|
||||||
});
|
}
|
||||||
|
|
||||||
CGContextSetLineWidth(_context, lineWidth);
|
CGContextSetLineWidth(_context, lineWidth);
|
||||||
|
|
||||||
@ -346,12 +392,12 @@ void CanvasImpl::linearGradientStrokePath(std::shared_ptr<lottie::CGPath> const
|
|||||||
CGContextRestoreGState(_context);
|
CGContextRestoreGState(_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasImpl::radialGradientStrokePath(std::shared_ptr<lottie::CGPath> const &path, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) {
|
void CanvasImpl::radialGradientStrokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) {
|
||||||
CGContextSaveGState(_context);
|
CGContextSaveGState(_context);
|
||||||
CGContextBeginPath(_context);
|
if (!addEnumeratedPath(_context, enumeratePath)) {
|
||||||
lottie::CGPathCocoaImpl::withNativePath(path, [context = _context](CGPathRef nativePath) {
|
CGContextRestoreGState(_context);
|
||||||
CGContextAddPath(context, nativePath);
|
return;
|
||||||
});
|
}
|
||||||
|
|
||||||
CGContextSetLineWidth(_context, lineWidth);
|
CGContextSetLineWidth(_context, lineWidth);
|
||||||
|
|
||||||
@ -467,10 +513,6 @@ void CanvasImpl::concatenate(lottie::CATransform3D const &transform) {
|
|||||||
CGContextConcatCTM(_context, CATransform3DGetAffineTransform(nativeTransform(transform)));
|
CGContextConcatCTM(_context, CATransform3DGetAffineTransform(nativeTransform(transform)));
|
||||||
}
|
}
|
||||||
|
|
||||||
lottie::CATransform3D CanvasImpl::currentTransform() {
|
|
||||||
return lottie::fromNativeTransform(CATransform3DMakeAffineTransform(CGContextGetCTM(_context)));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<Image> CanvasImpl::makeImage() const {
|
std::shared_ptr<Image> CanvasImpl::makeImage() const {
|
||||||
::CGImageRef nativeImage = CGBitmapContextCreateImage(_context);
|
::CGImageRef nativeImage = CGBitmapContextCreateImage(_context);
|
||||||
if (nativeImage) {
|
if (nativeImage) {
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
#ifndef NullCanvasImpl_h
|
||||||
|
#define NullCanvasImpl_h
|
||||||
|
|
||||||
|
#include "Canvas.h"
|
||||||
|
|
||||||
|
namespace lottieRendering {
|
||||||
|
|
||||||
|
class NullCanvasImpl: public Canvas {
|
||||||
|
public:
|
||||||
|
NullCanvasImpl(int width, int height);
|
||||||
|
virtual ~NullCanvasImpl();
|
||||||
|
|
||||||
|
virtual int width() const override;
|
||||||
|
virtual int height() const override;
|
||||||
|
|
||||||
|
virtual std::shared_ptr<Canvas> makeLayer(int width, int height) override;
|
||||||
|
|
||||||
|
virtual void saveState() override;
|
||||||
|
virtual void restoreState() override;
|
||||||
|
|
||||||
|
virtual void fillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, lottie::Color const &color) override;
|
||||||
|
virtual void linearGradientFillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, lottieRendering::Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) override;
|
||||||
|
virtual void radialGradientFillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, lottieRendering::Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) override;
|
||||||
|
virtual void strokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, lottie::Color const &color) override;
|
||||||
|
virtual void linearGradientStrokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) override;
|
||||||
|
virtual void radialGradientStrokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) override;
|
||||||
|
virtual void fill(lottie::CGRect const &rect, lottie::Color const &fillColor) override;
|
||||||
|
|
||||||
|
virtual void setBlendMode(BlendMode blendMode) override;
|
||||||
|
|
||||||
|
virtual void setAlpha(float alpha) override;
|
||||||
|
|
||||||
|
virtual void concatenate(lottie::CATransform3D const &transform) override;
|
||||||
|
|
||||||
|
virtual void draw(std::shared_ptr<Canvas> const &other, lottie::CGRect const &rect) override;
|
||||||
|
|
||||||
|
void flush();
|
||||||
|
|
||||||
|
private:
|
||||||
|
float _width = 0.0f;
|
||||||
|
float _height = 0.0f;
|
||||||
|
lottie::CATransform3D _transform;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,81 @@
|
|||||||
|
#include "NullCanvasImpl.h"
|
||||||
|
|
||||||
|
namespace lottieRendering {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void addEnumeratedPath(CanvasPathEnumerator const &enumeratePath) {
|
||||||
|
enumeratePath([&](PathCommand const &command) {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NullCanvasImpl::NullCanvasImpl(int width, int height) :
|
||||||
|
_width(width), _height(height), _transform(lottie::CATransform3D::identity()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
NullCanvasImpl::~NullCanvasImpl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
int NullCanvasImpl::width() const {
|
||||||
|
return _width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NullCanvasImpl::height() const {
|
||||||
|
return _height;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Canvas> NullCanvasImpl::makeLayer(int width, int height) {
|
||||||
|
return std::make_shared<NullCanvasImpl>(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullCanvasImpl::saveState() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullCanvasImpl::restoreState() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullCanvasImpl::fillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, lottie::Color const &color) {
|
||||||
|
addEnumeratedPath(enumeratePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullCanvasImpl::linearGradientFillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) {
|
||||||
|
addEnumeratedPath(enumeratePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullCanvasImpl::radialGradientFillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) {
|
||||||
|
addEnumeratedPath(enumeratePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullCanvasImpl::strokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, lottie::Color const &color) {
|
||||||
|
addEnumeratedPath(enumeratePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullCanvasImpl::linearGradientStrokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) {
|
||||||
|
addEnumeratedPath(enumeratePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullCanvasImpl::radialGradientStrokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) {
|
||||||
|
addEnumeratedPath(enumeratePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullCanvasImpl::fill(lottie::CGRect const &rect, lottie::Color const &fillColor) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullCanvasImpl::setBlendMode(BlendMode blendMode) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullCanvasImpl::setAlpha(float alpha) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullCanvasImpl::concatenate(lottie::CATransform3D const &transform) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullCanvasImpl::draw(std::shared_ptr<Canvas> const &other, lottie::CGRect const &rect) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void NullCanvasImpl::flush() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
#import "Canvas.h"
|
#import "Canvas.h"
|
||||||
#import "CoreGraphicsCanvasImpl.h"
|
#import "CoreGraphicsCanvasImpl.h"
|
||||||
#import "ThorVGCanvasImpl.h"
|
#import "ThorVGCanvasImpl.h"
|
||||||
|
#import "NullCanvasImpl.h"
|
||||||
|
|
||||||
#include <LottieCpp/RenderTreeNode.h>
|
#include <LottieCpp/RenderTreeNode.h>
|
||||||
|
|
||||||
@ -10,6 +11,8 @@ namespace {
|
|||||||
|
|
||||||
static constexpr float minVisibleAlpha = 0.5f / 255.0f;
|
static constexpr float minVisibleAlpha = 0.5f / 255.0f;
|
||||||
|
|
||||||
|
static constexpr float minGlobalRectCalculationSize = 200.0f;
|
||||||
|
|
||||||
struct TransformedPath {
|
struct TransformedPath {
|
||||||
lottie::BezierPath path;
|
lottie::BezierPath path;
|
||||||
lottie::CATransform3D transform;
|
lottie::CATransform3D transform;
|
||||||
@ -53,9 +56,7 @@ static lottie::CGRect collectPathBoundingBoxes(std::shared_ptr<lottie::RenderTre
|
|||||||
return boundingBox;
|
return boundingBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<TransformedPath> collectPaths(std::shared_ptr<lottie::RenderTreeNodeContentItem> item, size_t subItemLimit, lottie::CATransform3D const &parentTransform, bool skipApplyTransform) {
|
static void enumeratePaths(std::shared_ptr<lottie::RenderTreeNodeContentItem> item, size_t subItemLimit, lottie::CATransform3D const &parentTransform, bool skipApplyTransform, std::function<void(lottie::BezierPath const &path, lottie::CATransform3D const &transform)> const &onPath) {
|
||||||
std::vector<TransformedPath> mappedPaths;
|
|
||||||
|
|
||||||
//TODO:remove skipApplyTransform
|
//TODO:remove skipApplyTransform
|
||||||
lottie::CATransform3D effectiveTransform = parentTransform;
|
lottie::CATransform3D effectiveTransform = parentTransform;
|
||||||
if (!skipApplyTransform && item->isGroup) {
|
if (!skipApplyTransform && item->isGroup) {
|
||||||
@ -65,21 +66,14 @@ static std::vector<TransformedPath> collectPaths(std::shared_ptr<lottie::RenderT
|
|||||||
size_t maxSubitem = std::min(item->subItems.size(), subItemLimit);
|
size_t maxSubitem = std::min(item->subItems.size(), subItemLimit);
|
||||||
|
|
||||||
if (item->path) {
|
if (item->path) {
|
||||||
mappedPaths.emplace_back(item->path->path, effectiveTransform);
|
onPath(item->path->path, effectiveTransform);
|
||||||
}
|
}
|
||||||
assert(!item->trimParams);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < maxSubitem; i++) {
|
for (size_t i = 0; i < maxSubitem; i++) {
|
||||||
auto &subItem = item->subItems[i];
|
auto &subItem = item->subItems[i];
|
||||||
|
|
||||||
auto subItemPaths = collectPaths(subItem, INT32_MAX, effectiveTransform, false);
|
enumeratePaths(subItem, INT32_MAX, effectiveTransform, false, onPath);
|
||||||
|
|
||||||
for (auto &path : subItemPaths) {
|
|
||||||
mappedPaths.emplace_back(path.path, path.transform);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mappedPaths;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -187,7 +181,7 @@ static std::optional<CGRect> getRenderNodeGlobalRect(std::shared_ptr<RenderTreeN
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static void drawLottieContentItem(std::shared_ptr<lottieRendering::Canvas> parentContext, std::shared_ptr<lottie::RenderTreeNodeContentItem> item, float parentAlpha, lottie::Vector2D const &globalSize, lottie::CATransform3D const &parentTransform, lottie::BezierPathsBoundingBoxContext &bezierPathsBoundingBoxContext) {
|
static void drawLottieContentItem(std::shared_ptr<lottieRendering::Canvas> const &parentContext, std::shared_ptr<lottie::RenderTreeNodeContentItem> item, float parentAlpha, lottie::Vector2D const &globalSize, lottie::CATransform3D const &parentTransform, lottie::BezierPathsBoundingBoxContext &bezierPathsBoundingBoxContext) {
|
||||||
auto currentTransform = parentTransform;
|
auto currentTransform = parentTransform;
|
||||||
lottie::CATransform3D localTransform = item->transform;
|
lottie::CATransform3D localTransform = item->transform;
|
||||||
currentTransform = localTransform * currentTransform;
|
currentTransform = localTransform * currentTransform;
|
||||||
@ -201,7 +195,7 @@ static void drawLottieContentItem(std::shared_ptr<lottieRendering::Canvas> paren
|
|||||||
|
|
||||||
parentContext->saveState();
|
parentContext->saveState();
|
||||||
|
|
||||||
std::shared_ptr<lottieRendering::Canvas> currentContext;
|
std::shared_ptr<lottieRendering::Canvas> const *currentContext;
|
||||||
std::shared_ptr<lottieRendering::Canvas> tempContext;
|
std::shared_ptr<lottieRendering::Canvas> tempContext;
|
||||||
|
|
||||||
bool needsTempContext = false;
|
bool needsTempContext = false;
|
||||||
@ -209,7 +203,11 @@ static void drawLottieContentItem(std::shared_ptr<lottieRendering::Canvas> paren
|
|||||||
|
|
||||||
std::optional<lottie::CGRect> globalRect;
|
std::optional<lottie::CGRect> globalRect;
|
||||||
if (needsTempContext) {
|
if (needsTempContext) {
|
||||||
globalRect = lottie::getRenderContentItemGlobalRect(item, globalSize, parentTransform, bezierPathsBoundingBoxContext);
|
if (globalSize.x <= minGlobalRectCalculationSize && globalSize.y <= minGlobalRectCalculationSize) {
|
||||||
|
globalRect = lottie::CGRect(0.0, 0.0, globalSize.x, globalSize.y);
|
||||||
|
} else {
|
||||||
|
globalRect = lottie::getRenderContentItemGlobalRect(item, globalSize, parentTransform, bezierPathsBoundingBoxContext);
|
||||||
|
}
|
||||||
if (!globalRect || globalRect->width <= 0.0f || globalRect->height <= 0.0f) {
|
if (!globalRect || globalRect->width <= 0.0f || globalRect->height <= 0.0f) {
|
||||||
parentContext->restoreState();
|
parentContext->restoreState();
|
||||||
return;
|
return;
|
||||||
@ -218,13 +216,13 @@ static void drawLottieContentItem(std::shared_ptr<lottieRendering::Canvas> paren
|
|||||||
auto tempContextValue = parentContext->makeLayer((int)(globalRect->width), (int)(globalRect->height));
|
auto tempContextValue = parentContext->makeLayer((int)(globalRect->width), (int)(globalRect->height));
|
||||||
tempContext = tempContextValue;
|
tempContext = tempContextValue;
|
||||||
|
|
||||||
currentContext = tempContextValue;
|
currentContext = &tempContext;
|
||||||
currentContext->concatenate(lottie::CATransform3D::identity().translated(lottie::Vector2D(-globalRect->x, -globalRect->y)));
|
(*currentContext)->concatenate(lottie::CATransform3D::identity().translated(lottie::Vector2D(-globalRect->x, -globalRect->y)));
|
||||||
|
|
||||||
currentContext->saveState();
|
(*currentContext)->saveState();
|
||||||
currentContext->concatenate(currentTransform);
|
(*currentContext)->concatenate(currentTransform);
|
||||||
} else {
|
} else {
|
||||||
currentContext = parentContext;
|
currentContext = &parentContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
parentContext->concatenate(item->transform);
|
parentContext->concatenate(item->transform);
|
||||||
@ -237,75 +235,105 @@ static void drawLottieContentItem(std::shared_ptr<lottieRendering::Canvas> paren
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &shading : item->shadings) {
|
for (const auto &shading : item->shadings) {
|
||||||
std::vector<lottie::BezierPath> itemPaths;
|
lottieRendering::CanvasPathEnumerator iteratePaths;
|
||||||
if (shading->explicitPath) {
|
if (shading->explicitPath) {
|
||||||
itemPaths = shading->explicitPath.value();
|
auto itemPaths = shading->explicitPath.value();
|
||||||
} else {
|
iteratePaths = [itemPaths = itemPaths](std::function<void(lottieRendering::PathCommand const &)> iterate) -> void {
|
||||||
auto rawPaths = collectPaths(item, shading->subItemLimit, lottie::CATransform3D::identity(), true);
|
lottieRendering::PathCommand pathCommand;
|
||||||
for (const auto &rawPath : rawPaths) {
|
for (const auto &path : itemPaths) {
|
||||||
itemPaths.push_back(rawPath.path.copyUsingTransform(rawPath.transform));
|
std::optional<lottie::PathElement> previousElement;
|
||||||
}
|
for (const auto &element : path.elements()) {
|
||||||
}
|
if (previousElement.has_value()) {
|
||||||
|
if (previousElement->vertex.outTangentRelative().isZero() && element.vertex.inTangentRelative().isZero()) {
|
||||||
if (itemPaths.empty()) {
|
pathCommand.type = lottieRendering::PathCommandType::LineTo;
|
||||||
continue;
|
pathCommand.points[0] = CGPointMake(element.vertex.point.x, element.vertex.point.y);
|
||||||
}
|
iterate(pathCommand);
|
||||||
|
} else {
|
||||||
std::shared_ptr<lottie::CGPath> path = lottie::CGPath::makePath();
|
pathCommand.type = lottieRendering::PathCommandType::CurveTo;
|
||||||
|
pathCommand.points[2] = CGPointMake(element.vertex.point.x, element.vertex.point.y);
|
||||||
const auto iterate = [&](LottiePathItem const *pathItem) {
|
pathCommand.points[1] = CGPointMake(element.vertex.inTangent.x, element.vertex.inTangent.y);
|
||||||
switch (pathItem->type) {
|
pathCommand.points[0] = CGPointMake(previousElement->vertex.outTangent.x, previousElement->vertex.outTangent.y);
|
||||||
case LottiePathItemTypeMoveTo: {
|
iterate(pathCommand);
|
||||||
path->moveTo(lottie::Vector2D(pathItem->points[0].x, pathItem->points[0].y));
|
}
|
||||||
break;
|
} else {
|
||||||
}
|
pathCommand.type = lottieRendering::PathCommandType::MoveTo;
|
||||||
case LottiePathItemTypeLineTo: {
|
pathCommand.points[0] = CGPointMake(element.vertex.point.x, element.vertex.point.y);
|
||||||
path->addLineTo(lottie::Vector2D(pathItem->points[0].x, pathItem->points[0].y));
|
iterate(pathCommand);
|
||||||
break;
|
}
|
||||||
}
|
previousElement = element;
|
||||||
case LottiePathItemTypeCurveTo: {
|
}
|
||||||
path->addCurveTo(lottie::Vector2D(pathItem->points[2].x, pathItem->points[2].y), lottie::Vector2D(pathItem->points[0].x, pathItem->points[0].y), lottie::Vector2D(pathItem->points[1].x, pathItem->points[1].y));
|
if (path.closed().value_or(true)) {
|
||||||
break;
|
pathCommand.type = lottieRendering::PathCommandType::Close;
|
||||||
}
|
iterate(pathCommand);
|
||||||
case LottiePathItemTypeClose: {
|
|
||||||
path->closeSubpath();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
LottiePathItem pathItem;
|
|
||||||
for (const auto &path : itemPaths) {
|
|
||||||
std::optional<lottie::PathElement> previousElement;
|
|
||||||
for (const auto &element : path.elements()) {
|
|
||||||
if (previousElement.has_value()) {
|
|
||||||
if (previousElement->vertex.outTangentRelative().isZero() && element.vertex.inTangentRelative().isZero()) {
|
|
||||||
pathItem.type = LottiePathItemTypeLineTo;
|
|
||||||
pathItem.points[0] = CGPointMake(element.vertex.point.x, element.vertex.point.y);
|
|
||||||
iterate(&pathItem);
|
|
||||||
} else {
|
|
||||||
pathItem.type = LottiePathItemTypeCurveTo;
|
|
||||||
pathItem.points[2] = CGPointMake(element.vertex.point.x, element.vertex.point.y);
|
|
||||||
pathItem.points[1] = CGPointMake(element.vertex.inTangent.x, element.vertex.inTangent.y);
|
|
||||||
pathItem.points[0] = CGPointMake(previousElement->vertex.outTangent.x, previousElement->vertex.outTangent.y);
|
|
||||||
iterate(&pathItem);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
pathItem.type = LottiePathItemTypeMoveTo;
|
|
||||||
pathItem.points[0] = CGPointMake(element.vertex.point.x, element.vertex.point.y);
|
|
||||||
iterate(&pathItem);
|
|
||||||
}
|
}
|
||||||
previousElement = element;
|
};
|
||||||
}
|
} else {
|
||||||
if (path.closed().value_or(true)) {
|
iteratePaths = [&](std::function<void(lottieRendering::PathCommand const &)> iterate) {
|
||||||
pathItem.type = LottiePathItemTypeClose;
|
enumeratePaths(item, shading->subItemLimit, lottie::CATransform3D::identity(), true, [&](lottie::BezierPath const &sourcePath, lottie::CATransform3D const &transform) {
|
||||||
iterate(&pathItem);
|
auto path = sourcePath.copyUsingTransform(transform);
|
||||||
}
|
|
||||||
|
lottieRendering::PathCommand pathCommand;
|
||||||
|
std::optional<lottie::PathElement> previousElement;
|
||||||
|
for (const auto &element : path.elements()) {
|
||||||
|
if (previousElement.has_value()) {
|
||||||
|
if (previousElement->vertex.outTangentRelative().isZero() && element.vertex.inTangentRelative().isZero()) {
|
||||||
|
pathCommand.type = lottieRendering::PathCommandType::LineTo;
|
||||||
|
pathCommand.points[0] = CGPointMake(element.vertex.point.x, element.vertex.point.y);
|
||||||
|
iterate(pathCommand);
|
||||||
|
} else {
|
||||||
|
pathCommand.type = lottieRendering::PathCommandType::CurveTo;
|
||||||
|
pathCommand.points[2] = CGPointMake(element.vertex.point.x, element.vertex.point.y);
|
||||||
|
pathCommand.points[1] = CGPointMake(element.vertex.inTangent.x, element.vertex.inTangent.y);
|
||||||
|
pathCommand.points[0] = CGPointMake(previousElement->vertex.outTangent.x, previousElement->vertex.outTangent.y);
|
||||||
|
iterate(pathCommand);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pathCommand.type = lottieRendering::PathCommandType::MoveTo;
|
||||||
|
pathCommand.points[0] = CGPointMake(element.vertex.point.x, element.vertex.point.y);
|
||||||
|
iterate(pathCommand);
|
||||||
|
}
|
||||||
|
previousElement = element;
|
||||||
|
}
|
||||||
|
if (path.closed().value_or(true)) {
|
||||||
|
pathCommand.type = lottieRendering::PathCommandType::Close;
|
||||||
|
iterate(pathCommand);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*auto iteratePaths = [&](std::function<void(lottieRendering::PathCommand const &)> iterate) -> void {
|
||||||
|
lottieRendering::PathCommand pathCommand;
|
||||||
|
for (const auto &path : itemPaths) {
|
||||||
|
std::optional<lottie::PathElement> previousElement;
|
||||||
|
for (const auto &element : path.elements()) {
|
||||||
|
if (previousElement.has_value()) {
|
||||||
|
if (previousElement->vertex.outTangentRelative().isZero() && element.vertex.inTangentRelative().isZero()) {
|
||||||
|
pathCommand.type = lottieRendering::PathCommandType::LineTo;
|
||||||
|
pathCommand.points[0] = CGPointMake(element.vertex.point.x, element.vertex.point.y);
|
||||||
|
iterate(pathCommand);
|
||||||
|
} else {
|
||||||
|
pathCommand.type = lottieRendering::PathCommandType::CurveTo;
|
||||||
|
pathCommand.points[2] = CGPointMake(element.vertex.point.x, element.vertex.point.y);
|
||||||
|
pathCommand.points[1] = CGPointMake(element.vertex.inTangent.x, element.vertex.inTangent.y);
|
||||||
|
pathCommand.points[0] = CGPointMake(previousElement->vertex.outTangent.x, previousElement->vertex.outTangent.y);
|
||||||
|
iterate(pathCommand);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pathCommand.type = lottieRendering::PathCommandType::MoveTo;
|
||||||
|
pathCommand.points[0] = CGPointMake(element.vertex.point.x, element.vertex.point.y);
|
||||||
|
iterate(pathCommand);
|
||||||
|
}
|
||||||
|
previousElement = element;
|
||||||
|
}
|
||||||
|
if (path.closed().value_or(true)) {
|
||||||
|
pathCommand.type = lottieRendering::PathCommandType::Close;
|
||||||
|
iterate(pathCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};*/
|
||||||
|
|
||||||
if (shading->stroke) {
|
if (shading->stroke) {
|
||||||
if (shading->stroke->shading->type() == lottie::RenderTreeNodeContentItem::ShadingType::Solid) {
|
if (shading->stroke->shading->type() == lottie::RenderTreeNodeContentItem::ShadingType::Solid) {
|
||||||
lottie::RenderTreeNodeContentItem::SolidShading *solidShading = (lottie::RenderTreeNodeContentItem::SolidShading *)shading->stroke->shading.get();
|
lottie::RenderTreeNodeContentItem::SolidShading *solidShading = (lottie::RenderTreeNodeContentItem::SolidShading *)shading->stroke->shading.get();
|
||||||
@ -354,7 +382,7 @@ static void drawLottieContentItem(std::shared_ptr<lottieRendering::Canvas> paren
|
|||||||
dashPattern = shading->stroke->dashPattern;
|
dashPattern = shading->stroke->dashPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentContext->strokePath(path, shading->stroke->lineWidth, lineJoin, lineCap, shading->stroke->dashPhase, dashPattern, lottie::Color(solidShading->color.r, solidShading->color.g, solidShading->color.b, solidShading->color.a * solidShading->opacity * renderAlpha));
|
(*currentContext)->strokePath(iteratePaths, shading->stroke->lineWidth, lineJoin, lineCap, shading->stroke->dashPhase, dashPattern, lottie::Color(solidShading->color.r, solidShading->color.g, solidShading->color.b, solidShading->color.a * solidShading->opacity * renderAlpha));
|
||||||
} else if (shading->stroke->shading->type() == lottie::RenderTreeNodeContentItem::ShadingType::Gradient) {
|
} else if (shading->stroke->shading->type() == lottie::RenderTreeNodeContentItem::ShadingType::Gradient) {
|
||||||
//TODO:gradient stroke
|
//TODO:gradient stroke
|
||||||
}
|
}
|
||||||
@ -378,7 +406,7 @@ static void drawLottieContentItem(std::shared_ptr<lottieRendering::Canvas> paren
|
|||||||
if (shading->fill->shading->type() == lottie::RenderTreeNodeContentItem::ShadingType::Solid) {
|
if (shading->fill->shading->type() == lottie::RenderTreeNodeContentItem::ShadingType::Solid) {
|
||||||
lottie::RenderTreeNodeContentItem::SolidShading *solidShading = (lottie::RenderTreeNodeContentItem::SolidShading *)shading->fill->shading.get();
|
lottie::RenderTreeNodeContentItem::SolidShading *solidShading = (lottie::RenderTreeNodeContentItem::SolidShading *)shading->fill->shading.get();
|
||||||
if (solidShading->opacity != 0.0) {
|
if (solidShading->opacity != 0.0) {
|
||||||
currentContext->fillPath(path, rule, lottie::Color(solidShading->color.r, solidShading->color.g, solidShading->color.b, solidShading->color.a * solidShading->opacity * renderAlpha));
|
(*currentContext)->fillPath(iteratePaths, rule, lottie::Color(solidShading->color.r, solidShading->color.g, solidShading->color.b, solidShading->color.a * solidShading->opacity * renderAlpha));
|
||||||
}
|
}
|
||||||
} else if (shading->fill->shading->type() == lottie::RenderTreeNodeContentItem::ShadingType::Gradient) {
|
} else if (shading->fill->shading->type() == lottie::RenderTreeNodeContentItem::ShadingType::Gradient) {
|
||||||
lottie::RenderTreeNodeContentItem::GradientShading *gradientShading = (lottie::RenderTreeNodeContentItem::GradientShading *)shading->fill->shading.get();
|
lottie::RenderTreeNodeContentItem::GradientShading *gradientShading = (lottie::RenderTreeNodeContentItem::GradientShading *)shading->fill->shading.get();
|
||||||
@ -397,11 +425,11 @@ static void drawLottieContentItem(std::shared_ptr<lottieRendering::Canvas> paren
|
|||||||
|
|
||||||
switch (gradientShading->gradientType) {
|
switch (gradientShading->gradientType) {
|
||||||
case lottie::GradientType::Linear: {
|
case lottie::GradientType::Linear: {
|
||||||
currentContext->linearGradientFillPath(path, rule, gradient, start, end);
|
(*currentContext)->linearGradientFillPath(iteratePaths, rule, gradient, start, end);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case lottie::GradientType::Radial: {
|
case lottie::GradientType::Radial: {
|
||||||
currentContext->radialGradientFillPath(path, rule, gradient, start, 0.0, start, start.distanceTo(end));
|
(*currentContext)->radialGradientFillPath(iteratePaths, rule, gradient, start, 0.0, start, start.distanceTo(end));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -415,7 +443,7 @@ static void drawLottieContentItem(std::shared_ptr<lottieRendering::Canvas> paren
|
|||||||
|
|
||||||
for (auto it = item->subItems.rbegin(); it != item->subItems.rend(); it++) {
|
for (auto it = item->subItems.rbegin(); it != item->subItems.rend(); it++) {
|
||||||
const auto &subItem = *it;
|
const auto &subItem = *it;
|
||||||
drawLottieContentItem(currentContext, subItem, renderAlpha, globalSize, currentTransform, bezierPathsBoundingBoxContext);
|
drawLottieContentItem(*currentContext, subItem, renderAlpha, globalSize, currentTransform, bezierPathsBoundingBoxContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tempContext) {
|
if (tempContext) {
|
||||||
@ -430,7 +458,7 @@ static void drawLottieContentItem(std::shared_ptr<lottieRendering::Canvas> paren
|
|||||||
parentContext->restoreState();
|
parentContext->restoreState();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void renderLottieRenderNode(std::shared_ptr<lottie::RenderTreeNode> node, std::shared_ptr<lottieRendering::Canvas> parentContext, lottie::Vector2D const &globalSize, lottie::CATransform3D const &parentTransform, float parentAlpha, bool isInvertedMatte, lottie::BezierPathsBoundingBoxContext &bezierPathsBoundingBoxContext) {
|
static void renderLottieRenderNode(std::shared_ptr<lottie::RenderTreeNode> node, std::shared_ptr<lottieRendering::Canvas> const &parentContext, lottie::Vector2D const &globalSize, lottie::CATransform3D const &parentTransform, float parentAlpha, bool isInvertedMatte, lottie::BezierPathsBoundingBoxContext &bezierPathsBoundingBoxContext) {
|
||||||
float normalizedOpacity = node->alpha();
|
float normalizedOpacity = node->alpha();
|
||||||
float layerAlpha = ((float)normalizedOpacity) * parentAlpha;
|
float layerAlpha = ((float)normalizedOpacity) * parentAlpha;
|
||||||
|
|
||||||
@ -470,7 +498,11 @@ static void renderLottieRenderNode(std::shared_ptr<lottie::RenderTreeNode> node,
|
|||||||
|
|
||||||
std::optional<lottie::CGRect> globalRect;
|
std::optional<lottie::CGRect> globalRect;
|
||||||
if (needsTempContext) {
|
if (needsTempContext) {
|
||||||
globalRect = lottie::getRenderNodeGlobalRect(node, globalSize, parentTransform, false, bezierPathsBoundingBoxContext);
|
if (globalSize.x <= minGlobalRectCalculationSize && globalSize.y <= minGlobalRectCalculationSize) {
|
||||||
|
globalRect = lottie::CGRect(0.0, 0.0, globalSize.x, globalSize.y);
|
||||||
|
} else {
|
||||||
|
globalRect = lottie::getRenderNodeGlobalRect(node, globalSize, parentTransform, false, bezierPathsBoundingBoxContext);
|
||||||
|
}
|
||||||
if (!globalRect || globalRect->width <= 0.0f || globalRect->height <= 0.0f) {
|
if (!globalRect || globalRect->width <= 0.0f || globalRect->height <= 0.0f) {
|
||||||
parentContext->restoreState();
|
parentContext->restoreState();
|
||||||
return;
|
return;
|
||||||
@ -578,10 +610,6 @@ CGRect getPathNativeBoundingBox(CGPathRef _Nonnull path) {
|
|||||||
|
|
||||||
lottie::CATransform3D rootTransform = lottie::CATransform3D::identity().scaled(lottie::Vector2D(size.width / (float)animation.size.width, size.height / (float)animation.size.height));
|
lottie::CATransform3D rootTransform = lottie::CATransform3D::identity().scaled(lottie::Vector2D(size.width / (float)animation.size.width, size.height / (float)animation.size.height));
|
||||||
|
|
||||||
if (!useReferenceRendering) {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useReferenceRendering) {
|
if (useReferenceRendering) {
|
||||||
auto context = std::make_shared<lottieRendering::CanvasImpl>((int)size.width, (int)size.height);
|
auto context = std::make_shared<lottieRendering::CanvasImpl>((int)size.width, (int)size.height);
|
||||||
|
|
||||||
@ -594,12 +622,13 @@ CGRect getPathNativeBoundingBox(CGPathRef _Nonnull path) {
|
|||||||
|
|
||||||
return [[UIImage alloc] initWithCGImage:std::static_pointer_cast<lottieRendering::ImageImpl>(image)->nativeImage()];
|
return [[UIImage alloc] initWithCGImage:std::static_pointer_cast<lottieRendering::ImageImpl>(image)->nativeImage()];
|
||||||
} else {
|
} else {
|
||||||
/*auto context = std::make_shared<lottieRendering::ThorVGCanvasImpl>((int)size.width, (int)size.height);
|
//auto context = std::make_shared<lottieRendering::ThorVGCanvasImpl>((int)size.width, (int)size.height);
|
||||||
|
auto context = std::make_shared<lottieRendering::NullCanvasImpl>((int)size.width, (int)size.height);
|
||||||
|
|
||||||
CGPoint scale = CGPointMake(size.width / (CGFloat)animation.size.width, size.height / (CGFloat)animation.size.height);
|
CGPoint scale = CGPointMake(size.width / (CGFloat)animation.size.width, size.height / (CGFloat)animation.size.height);
|
||||||
context->concatenate(lottie::CATransform3D::makeScale(scale.x, scale.y, 1.0));
|
context->concatenate(lottie::CATransform3D::makeScale(scale.x, scale.y, 1.0));
|
||||||
|
|
||||||
renderLottieRenderNode(renderNode, context, lottie::Vector2D(context->width(), context->height()), 1.0);*/
|
renderLottieRenderNode(renderNode, context, lottie::Vector2D(context->width(), context->height()), rootTransform, 1.0, false, *_bezierPathsBoundingBoxContext.get());
|
||||||
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,12 @@ public:
|
|||||||
virtual void saveState() override;
|
virtual void saveState() override;
|
||||||
virtual void restoreState() override;
|
virtual void restoreState() override;
|
||||||
|
|
||||||
virtual void fillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::FillRule fillRule, lottie::Color const &color) override;
|
virtual void fillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, lottie::Color const &color) override;
|
||||||
virtual void linearGradientFillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::FillRule fillRule, lottieRendering::Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) override;
|
virtual void linearGradientFillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, lottieRendering::Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) override;
|
||||||
virtual void radialGradientFillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::FillRule fillRule, lottieRendering::Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) override;
|
virtual void radialGradientFillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, lottieRendering::Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) override;
|
||||||
virtual void strokePath(std::shared_ptr<lottie::CGPath> const &path, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, lottie::Color const &color) override;
|
virtual void strokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, lottie::Color const &color) override;
|
||||||
virtual void linearGradientStrokePath(std::shared_ptr<lottie::CGPath> const &path, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) override;
|
virtual void linearGradientStrokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) override;
|
||||||
virtual void radialGradientStrokePath(std::shared_ptr<lottie::CGPath> const &path, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) override;
|
virtual void radialGradientStrokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) override;
|
||||||
virtual void fill(lottie::CGRect const &rect, lottie::Color const &fillColor) override;
|
virtual void fill(lottie::CGRect const &rect, lottie::Color const &fillColor) override;
|
||||||
|
|
||||||
virtual void setBlendMode(BlendMode blendMode) override;
|
virtual void setBlendMode(BlendMode blendMode) override;
|
||||||
@ -33,7 +33,6 @@ public:
|
|||||||
virtual void setAlpha(float alpha) override;
|
virtual void setAlpha(float alpha) override;
|
||||||
|
|
||||||
virtual void concatenate(lottie::CATransform3D const &transform) override;
|
virtual void concatenate(lottie::CATransform3D const &transform) override;
|
||||||
virtual lottie::CATransform3D currentTransform() override;
|
|
||||||
|
|
||||||
virtual void draw(std::shared_ptr<Canvas> const &other, lottie::CGRect const &rect) override;
|
virtual void draw(std::shared_ptr<Canvas> const &other, lottie::CGRect const &rect) override;
|
||||||
|
|
||||||
|
@ -4,22 +4,22 @@ namespace lottieRendering {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void tvgPath(std::shared_ptr<lottie::CGPath> const &path, tvg::Shape *shape) {
|
void tvgPath(CanvasPathEnumerator const &enumeratePath, tvg::Shape *shape) {
|
||||||
path->enumerate([shape](lottie::CGPathItem const &item) {
|
enumeratePath([&](PathCommand const &command) {
|
||||||
switch (item.type) {
|
switch (command.type) {
|
||||||
case lottie::CGPathItem::Type::MoveTo: {
|
case PathCommandType::MoveTo: {
|
||||||
shape->moveTo(item.points[0].x, item.points[0].y);
|
shape->moveTo(command.points[0].x, command.points[0].y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case lottie::CGPathItem::Type::LineTo: {
|
case PathCommandType::LineTo: {
|
||||||
shape->lineTo(item.points[0].x, item.points[0].y);
|
shape->lineTo(command.points[0].x, command.points[0].y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case lottie::CGPathItem::Type::CurveTo: {
|
case PathCommandType::CurveTo: {
|
||||||
shape->cubicTo(item.points[0].x, item.points[0].y, item.points[1].x, item.points[1].y, item.points[2].x, item.points[2].y);
|
shape->cubicTo(command.points[0].x, command.points[0].y, command.points[1].x, command.points[1].y, command.points[2].x, command.points[2].y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case lottie::CGPathItem::Type::Close: {
|
case PathCommandType::Close: {
|
||||||
shape->close();
|
shape->close();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -89,9 +89,9 @@ void ThorVGCanvasImpl::restoreState() {
|
|||||||
_stateStack.pop_back();
|
_stateStack.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThorVGCanvasImpl::fillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::FillRule fillRule, lottie::Color const &color) {
|
void ThorVGCanvasImpl::fillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, lottie::Color const &color) {
|
||||||
auto shape = tvg::Shape::gen();
|
auto shape = tvg::Shape::gen();
|
||||||
tvgPath(path, shape.get());
|
tvgPath(enumeratePath, shape.get());
|
||||||
|
|
||||||
shape->transform(tvgTransform(_transform));
|
shape->transform(tvgTransform(_transform));
|
||||||
|
|
||||||
@ -101,9 +101,9 @@ void ThorVGCanvasImpl::fillPath(std::shared_ptr<lottie::CGPath> const &path, lot
|
|||||||
_canvas->push(std::move(shape));
|
_canvas->push(std::move(shape));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThorVGCanvasImpl::linearGradientFillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) {
|
void ThorVGCanvasImpl::linearGradientFillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) {
|
||||||
auto shape = tvg::Shape::gen();
|
auto shape = tvg::Shape::gen();
|
||||||
tvgPath(path, shape.get());
|
tvgPath(enumeratePath, shape.get());
|
||||||
|
|
||||||
shape->transform(tvgTransform(_transform));
|
shape->transform(tvgTransform(_transform));
|
||||||
|
|
||||||
@ -129,9 +129,9 @@ void ThorVGCanvasImpl::linearGradientFillPath(std::shared_ptr<lottie::CGPath> co
|
|||||||
_canvas->push(std::move(shape));
|
_canvas->push(std::move(shape));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThorVGCanvasImpl::radialGradientFillPath(std::shared_ptr<lottie::CGPath> const &path, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) {
|
void ThorVGCanvasImpl::radialGradientFillPath(CanvasPathEnumerator const &enumeratePath, lottie::FillRule fillRule, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) {
|
||||||
auto shape = tvg::Shape::gen();
|
auto shape = tvg::Shape::gen();
|
||||||
tvgPath(path, shape.get());
|
tvgPath(enumeratePath, shape.get());
|
||||||
|
|
||||||
shape->transform(tvgTransform(_transform));
|
shape->transform(tvgTransform(_transform));
|
||||||
|
|
||||||
@ -157,9 +157,9 @@ void ThorVGCanvasImpl::radialGradientFillPath(std::shared_ptr<lottie::CGPath> co
|
|||||||
_canvas->push(std::move(shape));
|
_canvas->push(std::move(shape));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThorVGCanvasImpl::strokePath(std::shared_ptr<lottie::CGPath> const &path, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, lottie::Color const &color) {
|
void ThorVGCanvasImpl::strokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, lottie::Color const &color) {
|
||||||
auto shape = tvg::Shape::gen();
|
auto shape = tvg::Shape::gen();
|
||||||
tvgPath(path, shape.get());
|
tvgPath(enumeratePath, shape.get());
|
||||||
|
|
||||||
shape->transform(tvgTransform(_transform));
|
shape->transform(tvgTransform(_transform));
|
||||||
|
|
||||||
@ -217,12 +217,10 @@ void ThorVGCanvasImpl::strokePath(std::shared_ptr<lottie::CGPath> const &path, f
|
|||||||
_canvas->push(std::move(shape));
|
_canvas->push(std::move(shape));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThorVGCanvasImpl::linearGradientStrokePath(std::shared_ptr<lottie::CGPath> const &path, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) {
|
void ThorVGCanvasImpl::linearGradientStrokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &start, lottie::Vector2D const &end) {
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThorVGCanvasImpl::radialGradientStrokePath(std::shared_ptr<lottie::CGPath> const &path, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) {
|
void ThorVGCanvasImpl::radialGradientStrokePath(CanvasPathEnumerator const &enumeratePath, float lineWidth, lottie::LineJoin lineJoin, lottie::LineCap lineCap, float dashPhase, std::vector<float> const &dashPattern, Gradient const &gradient, lottie::Vector2D const &startCenter, float startRadius, lottie::Vector2D const &endCenter, float endRadius) {
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThorVGCanvasImpl::fill(lottie::CGRect const &rect, lottie::Color const &fillColor) {
|
void ThorVGCanvasImpl::fill(lottie::CGRect const &rect, lottie::Color const &fillColor) {
|
||||||
@ -271,10 +269,6 @@ void ThorVGCanvasImpl::concatenate(lottie::CATransform3D const &transform) {
|
|||||||
));*/
|
));*/
|
||||||
}
|
}
|
||||||
|
|
||||||
lottie::CATransform3D ThorVGCanvasImpl::currentTransform() {
|
|
||||||
return _transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThorVGCanvasImpl::draw(std::shared_ptr<Canvas> const &other, lottie::CGRect const &rect) {
|
void ThorVGCanvasImpl::draw(std::shared_ptr<Canvas> const &other, lottie::CGRect const &rect) {
|
||||||
/*ThorVGCanvasImpl *impl = (ThorVGCanvasImpl *)other.get();
|
/*ThorVGCanvasImpl *impl = (ThorVGCanvasImpl *)other.get();
|
||||||
auto image = impl->surface()->makeImageSnapshot();
|
auto image = impl->surface()->makeImageSnapshot();
|
||||||
|
@ -78,7 +78,7 @@ private final class ReferenceCompareTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var continueFromName: String?
|
var continueFromName: String?
|
||||||
//continueFromName = "4986037051573928320.json"
|
//continueFromName = "35707580709863498.json"
|
||||||
|
|
||||||
let _ = await processAnimationFolderAsync(basePath: bundlePath, path: "", stopOnFailure: true, process: { path, name, alwaysDraw in
|
let _ = await processAnimationFolderAsync(basePath: bundlePath, path: "", stopOnFailure: true, process: { path, name, alwaysDraw in
|
||||||
if let continueFromNameValue = continueFromName {
|
if let continueFromNameValue = continueFromName {
|
||||||
@ -119,7 +119,7 @@ public final class ViewController: UIViewController {
|
|||||||
|
|
||||||
self.view.layer.addSublayer(MetalEngine.shared.rootLayer)
|
self.view.layer.addSublayer(MetalEngine.shared.rootLayer)
|
||||||
|
|
||||||
if "".isEmpty {
|
if !"".isEmpty {
|
||||||
if #available(iOS 13.0, *) {
|
if #available(iOS 13.0, *) {
|
||||||
self.test = ReferenceCompareTest(view: self.view)
|
self.test = ReferenceCompareTest(view: self.view)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user