mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-04 21:41:45 +00:00
lottie/render: Move drawable class to vector.
Change-Id: I4cb296e7a1d86b5215ab191b4306514d3fcdeacf
This commit is contained in:
parent
8b77e6ce93
commit
1c62266e43
@ -5,158 +5,6 @@
|
||||
#include"vdasher.h"
|
||||
#include <cmath>
|
||||
|
||||
VDrawable::VDrawable():mFlag(DirtyState::All),
|
||||
mType(Type::Fill),
|
||||
mFillRule(FillRule::Winding)
|
||||
{
|
||||
mStroke.dashArraySize = 0;
|
||||
mStroke.cap = CapStyle::Round;
|
||||
mStroke.join= JoinStyle::Round;
|
||||
mStroke.meterLimit = 10;
|
||||
mStroke.enable = false;
|
||||
}
|
||||
|
||||
void VDrawable::preprocess()
|
||||
{
|
||||
if (mFlag & (DirtyState::Path)) {
|
||||
if (mStroke.enable) {
|
||||
VPath newPath = mPath;
|
||||
if (mStroke.dashArraySize) {
|
||||
VDasher dasher(mStroke.dashArray, mStroke.dashArraySize);
|
||||
newPath = dasher.dashed(mPath);
|
||||
}
|
||||
mRleTask = VRaster::instance().generateStrokeInfo(mPath, mStroke.cap, mStroke.join,
|
||||
mStroke.width, mStroke.meterLimit);
|
||||
} else {
|
||||
mRleTask = VRaster::instance().generateFillInfo(mPath, mFillRule);
|
||||
}
|
||||
mFlag &= ~DirtyFlag(DirtyState::Path);
|
||||
}
|
||||
}
|
||||
|
||||
VRle VDrawable::rle()
|
||||
{
|
||||
if (mRleTask.valid()) {
|
||||
mRle = std::move(mRleTask.get());
|
||||
}
|
||||
return mRle;
|
||||
}
|
||||
|
||||
void VDrawable::setStrokeInfo(CapStyle cap, JoinStyle join, float meterLimit, float strokeWidth)
|
||||
{
|
||||
mStroke.enable = true;
|
||||
mStroke.cap = cap;
|
||||
mStroke.join = join;
|
||||
mStroke.meterLimit = meterLimit;
|
||||
mStroke.width = strokeWidth;
|
||||
mFlag |= DirtyState::Path;
|
||||
}
|
||||
void VDrawable::setDashInfo(float *array, int size)
|
||||
{
|
||||
mStroke.dashArray = array;
|
||||
mStroke.dashArraySize = size;
|
||||
mFlag |= DirtyState::Path;
|
||||
}
|
||||
|
||||
void VDrawable::sync()
|
||||
{
|
||||
mCNode.mFlag = ChangeFlagNone;
|
||||
if (mFlag & DirtyState::None) return;
|
||||
|
||||
if (mFlag & DirtyState::Path) {
|
||||
const std::vector<VPath::Element> &elm = mPath.elements();
|
||||
const std::vector<VPointF> &pts = mPath.points();
|
||||
const float *ptPtr = reinterpret_cast<const float *>(pts.data());
|
||||
const char *elmPtr = reinterpret_cast<const char *>(elm.data());
|
||||
mCNode.mPath.elmPtr = elmPtr;
|
||||
mCNode.mPath.elmCount = elm.size();
|
||||
mCNode.mPath.ptPtr = ptPtr;
|
||||
mCNode.mPath.ptCount = 2 * pts.size();
|
||||
mCNode.mFlag |= ChangeFlagPath;
|
||||
}
|
||||
|
||||
if (mStroke.enable) {
|
||||
mCNode.mStroke.width = mStroke.width;
|
||||
mCNode.mStroke.meterLimit = mStroke.meterLimit;
|
||||
mCNode.mStroke.enable = 1;
|
||||
|
||||
switch (mFillRule) {
|
||||
case FillRule::EvenOdd:
|
||||
mCNode.mFillRule = LOTNode::EvenOdd;
|
||||
break;
|
||||
default:
|
||||
mCNode.mFillRule = LOTNode::Winding;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (mStroke.cap) {
|
||||
case CapStyle::Flat:
|
||||
mCNode.mStroke.cap = LOTNode::FlatCap;
|
||||
break;
|
||||
case CapStyle::Square:
|
||||
mCNode.mStroke.cap = LOTNode::SquareCap;
|
||||
break;
|
||||
case CapStyle::Round:
|
||||
mCNode.mStroke.cap = LOTNode::RoundCap;
|
||||
break;
|
||||
default:
|
||||
mCNode.mStroke.cap = LOTNode::FlatCap;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (mStroke.join) {
|
||||
case JoinStyle::Miter:
|
||||
mCNode.mStroke.join = LOTNode::MiterJoin;
|
||||
break;
|
||||
case JoinStyle::Bevel:
|
||||
mCNode.mStroke.join = LOTNode::BevelJoin;
|
||||
break;
|
||||
case JoinStyle::Round:
|
||||
mCNode.mStroke.join = LOTNode::RoundJoin;
|
||||
break;
|
||||
default:
|
||||
mCNode.mStroke.join = LOTNode::MiterJoin;
|
||||
break;
|
||||
}
|
||||
|
||||
mCNode.mStroke.dashArray = mStroke.dashArray;
|
||||
mCNode.mStroke.dashArraySize = mStroke.dashArraySize;
|
||||
|
||||
} else {
|
||||
mCNode.mStroke.enable = 0;
|
||||
}
|
||||
|
||||
switch (mBrush.type()) {
|
||||
case VBrush::Type::Solid:
|
||||
mCNode.mType = LOTNode::BrushSolid;
|
||||
mCNode.mColor.r = mBrush.mColor.r;
|
||||
mCNode.mColor.g = mBrush.mColor.g;
|
||||
mCNode.mColor.b = mBrush.mColor.b;
|
||||
mCNode.mColor.a = mBrush.mColor.a;
|
||||
break;
|
||||
case VBrush::Type::LinearGradient:
|
||||
mCNode.mType = LOTNode::BrushGradient;
|
||||
mCNode.mGradient.type = LOTNode::Gradient::Linear;
|
||||
mCNode.mGradient.start.x = mBrush.mGradient->linear.x1;
|
||||
mCNode.mGradient.start.y = mBrush.mGradient->linear.y1;
|
||||
mCNode.mGradient.end.x = mBrush.mGradient->linear.x2;
|
||||
mCNode.mGradient.end.y = mBrush.mGradient->linear.y2;
|
||||
break;
|
||||
case VBrush::Type::RadialGradient:
|
||||
mCNode.mType = LOTNode::BrushGradient;
|
||||
mCNode.mGradient.type = LOTNode::Gradient::Radial;
|
||||
mCNode.mGradient.center.x = mBrush.mGradient->radial.cx;
|
||||
mCNode.mGradient.center.y = mBrush.mGradient->radial.cy;
|
||||
mCNode.mGradient.focal.x = mBrush.mGradient->radial.fx;
|
||||
mCNode.mGradient.focal.y = mBrush.mGradient->radial.fy;
|
||||
mCNode.mGradient.cradius = mBrush.mGradient->radial.cradius;
|
||||
mCNode.mGradient.fradius = mBrush.mGradient->radial.fradius;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lottie Layer Rules
|
||||
* 1. time stretch is pre calculated and applied to all the properties of the lottilayer model and all its children
|
||||
* 2. The frame property could be reversed using,time-reverse layer property in AE. which means (start frame > endFrame)
|
||||
@ -276,8 +124,9 @@ void LOTCompItem::buildRenderList()
|
||||
|
||||
mRenderList.clear();
|
||||
for(auto i : mDrawableList) {
|
||||
i->sync();
|
||||
mRenderList.push_back(&i->mCNode);
|
||||
LOTDrawable *lotDrawable = static_cast<LOTDrawable *>(i);
|
||||
lotDrawable->sync();
|
||||
mRenderList.push_back(&lotDrawable->mCNode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -563,7 +412,7 @@ LOTSolidLayerItem::LOTSolidLayerItem(LOTLayerData *layerData):LOTLayerItem(layer
|
||||
void LOTSolidLayerItem::updateContent()
|
||||
{
|
||||
if (!mRenderNode) {
|
||||
mRenderNode = std::make_unique<VDrawable>();
|
||||
mRenderNode = std::make_unique<LOTDrawable>();
|
||||
mRenderNode->mType = VDrawable::Type::Fill;
|
||||
mRenderNode->mFlag |= VDrawable::DirtyState::All;
|
||||
}
|
||||
@ -764,7 +613,7 @@ void LOTPathDataItem::addPaintOperation(std::vector<LOTPaintDataItem *> &list, i
|
||||
{
|
||||
for(auto paintItem : list) {
|
||||
bool sameGroup = (externalCount-- > 0) ? false : true;
|
||||
mNodeList.push_back(std::make_unique<VDrawable>());
|
||||
mNodeList.push_back(std::make_unique<LOTDrawable>());
|
||||
mRenderList.push_back(LOTRenderNode(this, paintItem, mNodeList.back().get(), sameGroup));
|
||||
}
|
||||
}
|
||||
@ -1107,3 +956,103 @@ void LOTRepeaterItem::renderList(std::vector<VDrawable *> &list)
|
||||
|
||||
}
|
||||
|
||||
void LOTDrawable::sync()
|
||||
{
|
||||
mCNode.mFlag = ChangeFlagNone;
|
||||
if (mFlag & DirtyState::None) return;
|
||||
|
||||
if (mFlag & DirtyState::Path) {
|
||||
const std::vector<VPath::Element> &elm = mPath.elements();
|
||||
const std::vector<VPointF> &pts = mPath.points();
|
||||
const float *ptPtr = reinterpret_cast<const float *>(pts.data());
|
||||
const char *elmPtr = reinterpret_cast<const char *>(elm.data());
|
||||
mCNode.mPath.elmPtr = elmPtr;
|
||||
mCNode.mPath.elmCount = elm.size();
|
||||
mCNode.mPath.ptPtr = ptPtr;
|
||||
mCNode.mPath.ptCount = 2 * pts.size();
|
||||
mCNode.mFlag |= ChangeFlagPath;
|
||||
}
|
||||
|
||||
if (mStroke.enable) {
|
||||
mCNode.mStroke.width = mStroke.width;
|
||||
mCNode.mStroke.meterLimit = mStroke.meterLimit;
|
||||
mCNode.mStroke.enable = 1;
|
||||
|
||||
switch (mFillRule) {
|
||||
case FillRule::EvenOdd:
|
||||
mCNode.mFillRule = LOTNode::EvenOdd;
|
||||
break;
|
||||
default:
|
||||
mCNode.mFillRule = LOTNode::Winding;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (mStroke.cap) {
|
||||
case CapStyle::Flat:
|
||||
mCNode.mStroke.cap = LOTNode::FlatCap;
|
||||
break;
|
||||
case CapStyle::Square:
|
||||
mCNode.mStroke.cap = LOTNode::SquareCap;
|
||||
break;
|
||||
case CapStyle::Round:
|
||||
mCNode.mStroke.cap = LOTNode::RoundCap;
|
||||
break;
|
||||
default:
|
||||
mCNode.mStroke.cap = LOTNode::FlatCap;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (mStroke.join) {
|
||||
case JoinStyle::Miter:
|
||||
mCNode.mStroke.join = LOTNode::MiterJoin;
|
||||
break;
|
||||
case JoinStyle::Bevel:
|
||||
mCNode.mStroke.join = LOTNode::BevelJoin;
|
||||
break;
|
||||
case JoinStyle::Round:
|
||||
mCNode.mStroke.join = LOTNode::RoundJoin;
|
||||
break;
|
||||
default:
|
||||
mCNode.mStroke.join = LOTNode::MiterJoin;
|
||||
break;
|
||||
}
|
||||
|
||||
mCNode.mStroke.dashArray = mStroke.dashArray;
|
||||
mCNode.mStroke.dashArraySize = mStroke.dashArraySize;
|
||||
|
||||
} else {
|
||||
mCNode.mStroke.enable = 0;
|
||||
}
|
||||
|
||||
switch (mBrush.type()) {
|
||||
case VBrush::Type::Solid:
|
||||
mCNode.mType = LOTNode::BrushSolid;
|
||||
mCNode.mColor.r = mBrush.mColor.r;
|
||||
mCNode.mColor.g = mBrush.mColor.g;
|
||||
mCNode.mColor.b = mBrush.mColor.b;
|
||||
mCNode.mColor.a = mBrush.mColor.a;
|
||||
break;
|
||||
case VBrush::Type::LinearGradient:
|
||||
mCNode.mType = LOTNode::BrushGradient;
|
||||
mCNode.mGradient.type = LOTNode::Gradient::Linear;
|
||||
mCNode.mGradient.start.x = mBrush.mGradient->linear.x1;
|
||||
mCNode.mGradient.start.y = mBrush.mGradient->linear.y1;
|
||||
mCNode.mGradient.end.x = mBrush.mGradient->linear.x2;
|
||||
mCNode.mGradient.end.y = mBrush.mGradient->linear.y2;
|
||||
break;
|
||||
case VBrush::Type::RadialGradient:
|
||||
mCNode.mType = LOTNode::BrushGradient;
|
||||
mCNode.mGradient.type = LOTNode::Gradient::Radial;
|
||||
mCNode.mGradient.center.x = mBrush.mGradient->radial.cx;
|
||||
mCNode.mGradient.center.y = mBrush.mGradient->radial.cy;
|
||||
mCNode.mGradient.focal.x = mBrush.mGradient->radial.fx;
|
||||
mCNode.mGradient.focal.y = mBrush.mGradient->radial.fy;
|
||||
mCNode.mGradient.cradius = mBrush.mGradient->radial.cradius;
|
||||
mCNode.mGradient.fradius = mBrush.mGradient->radial.fradius;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -10,8 +10,8 @@
|
||||
#include"vpoint.h"
|
||||
#include"vpathmesure.h"
|
||||
#include"lottieplayer.h"
|
||||
#include"vbrush.h"
|
||||
#include"vpainter.h"
|
||||
#include"vdrawable.h"
|
||||
|
||||
V_USE_NAMESPACE
|
||||
|
||||
@ -156,47 +156,11 @@ public:
|
||||
VRle mRle;
|
||||
};
|
||||
|
||||
class VDrawable
|
||||
class LOTDrawable : public VDrawable
|
||||
{
|
||||
public:
|
||||
enum class DirtyState {
|
||||
None = 0x00000000,
|
||||
Path = 0x00000001,
|
||||
Stroke = 0x00000010,
|
||||
Brush = 0x00000100,
|
||||
All = (None | Path | Stroke | Brush)
|
||||
};
|
||||
enum class Type {
|
||||
Fill,
|
||||
Stroke,
|
||||
};
|
||||
typedef vFlag<DirtyState> DirtyFlag;
|
||||
VDrawable();
|
||||
void sync();
|
||||
void setPath(const VPath &path);
|
||||
void setFillRule(FillRule rule){mFillRule = rule;}
|
||||
void setBrush(const VBrush &brush){mBrush = brush;}
|
||||
void setStrokeInfo(CapStyle cap, JoinStyle join, float meterLimit, float strokeWidth);
|
||||
void setDashInfo(float *array, int size);
|
||||
void preprocess();
|
||||
VRle rle();
|
||||
public:
|
||||
DirtyFlag mFlag;
|
||||
VDrawable::Type mType;
|
||||
VBrush mBrush;
|
||||
VPath mPath;
|
||||
FillRule mFillRule;
|
||||
std::future<VRle> mRleTask;
|
||||
VRle mRle;
|
||||
struct {
|
||||
bool enable;
|
||||
float width;
|
||||
CapStyle cap;
|
||||
JoinStyle join;
|
||||
float meterLimit;
|
||||
float *dashArray;
|
||||
int dashArraySize;
|
||||
}mStroke;
|
||||
LOTNode mCNode;
|
||||
};
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ target_sources(lottie-player
|
||||
"${CMAKE_CURRENT_LIST_DIR}/vinterpolator.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/vbezier.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/vraster.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/vdrawable.cpp"
|
||||
)
|
||||
|
||||
target_include_directories(lottie-player
|
||||
|
||||
@ -10,6 +10,8 @@ source_file += files('vpainter.cpp')
|
||||
source_file += files('vcompositionfunctions.cpp')
|
||||
source_file += files('vdrawhelper.cpp')
|
||||
source_file += files('vdrawhelper_sse2.cpp')
|
||||
source_file += files('vdrawable.cpp')
|
||||
|
||||
|
||||
source_file += files('vregion.cpp')
|
||||
source_file += files('vrle.cpp')
|
||||
|
||||
46
src/vector/vdrawable.cpp
Normal file
46
src/vector/vdrawable.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include "vdrawable.h"
|
||||
#include"vdasher.h"
|
||||
#include"vraster.h"
|
||||
|
||||
void VDrawable::preprocess()
|
||||
{
|
||||
if (mFlag & (DirtyState::Path)) {
|
||||
if (mStroke.enable) {
|
||||
VPath newPath = mPath;
|
||||
if (mStroke.dashArraySize) {
|
||||
VDasher dasher(mStroke.dashArray, mStroke.dashArraySize);
|
||||
newPath = dasher.dashed(mPath);
|
||||
}
|
||||
mRleTask = VRaster::instance().generateStrokeInfo(mPath, mStroke.cap, mStroke.join,
|
||||
mStroke.width, mStroke.meterLimit);
|
||||
} else {
|
||||
mRleTask = VRaster::instance().generateFillInfo(mPath, mFillRule);
|
||||
}
|
||||
mFlag &= ~DirtyFlag(DirtyState::Path);
|
||||
}
|
||||
}
|
||||
|
||||
VRle VDrawable::rle()
|
||||
{
|
||||
if (mRleTask.valid()) {
|
||||
mRle = std::move(mRleTask.get());
|
||||
}
|
||||
return mRle;
|
||||
}
|
||||
|
||||
void VDrawable::setStrokeInfo(CapStyle cap, JoinStyle join, float meterLimit, float strokeWidth)
|
||||
{
|
||||
mStroke.enable = true;
|
||||
mStroke.cap = cap;
|
||||
mStroke.join = join;
|
||||
mStroke.meterLimit = meterLimit;
|
||||
mStroke.width = strokeWidth;
|
||||
mFlag |= DirtyState::Path;
|
||||
}
|
||||
|
||||
void VDrawable::setDashInfo(float *array, int size)
|
||||
{
|
||||
mStroke.dashArray = array;
|
||||
mStroke.dashArraySize = size;
|
||||
mFlag |= DirtyState::Path;
|
||||
}
|
||||
50
src/vector/vdrawable.h
Normal file
50
src/vector/vdrawable.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef VDRAWABLE_H
|
||||
#define VDRAWABLE_H
|
||||
#include "vbrush.h"
|
||||
#include "vpath.h"
|
||||
#include "vrle.h"
|
||||
#include<future>
|
||||
|
||||
class VDrawable
|
||||
{
|
||||
public:
|
||||
enum class DirtyState {
|
||||
None = 0x00000000,
|
||||
Path = 0x00000001,
|
||||
Stroke = 0x00000010,
|
||||
Brush = 0x00000100,
|
||||
All = (None | Path | Stroke | Brush)
|
||||
};
|
||||
enum class Type {
|
||||
Fill,
|
||||
Stroke,
|
||||
};
|
||||
typedef vFlag<DirtyState> DirtyFlag;
|
||||
VDrawable() = default;
|
||||
void setPath(const VPath &path);
|
||||
void setFillRule(FillRule rule){mFillRule = rule;}
|
||||
void setBrush(const VBrush &brush){mBrush = brush;}
|
||||
void setStrokeInfo(CapStyle cap, JoinStyle join, float meterLimit, float strokeWidth);
|
||||
void setDashInfo(float *array, int size);
|
||||
void preprocess();
|
||||
VRle rle();
|
||||
public:
|
||||
DirtyFlag mFlag {DirtyState::All};
|
||||
VDrawable::Type mType {Type::Fill};
|
||||
VBrush mBrush;
|
||||
VPath mPath;
|
||||
FillRule mFillRule{FillRule::Winding};
|
||||
std::future<VRle> mRleTask;
|
||||
VRle mRle;
|
||||
struct {
|
||||
bool enable {false};
|
||||
float width {0.0};
|
||||
CapStyle cap {CapStyle::Flat};
|
||||
JoinStyle join {JoinStyle::Bevel};
|
||||
float meterLimit {10};
|
||||
float *dashArray {nullptr};
|
||||
int dashArraySize {0};
|
||||
}mStroke;
|
||||
};
|
||||
|
||||
#endif // VDRAWABLE_H
|
||||
Loading…
x
Reference in New Issue
Block a user