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
a5377fd4f5
commit
940619b7cd
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
static constexpr float minVisibleAlpha = 0.5f / 255.0f;
|
||||||
|
|
||||||
struct TransformedPath {
|
struct TransformedPath {
|
||||||
lottie::BezierPath path;
|
lottie::BezierPath path;
|
||||||
lottie::CATransform3D transform;
|
lottie::CATransform3D transform;
|
||||||
@ -85,10 +87,6 @@ static std::vector<TransformedPath> collectPaths(std::shared_ptr<lottie::RenderT
|
|||||||
namespace lottie {
|
namespace lottie {
|
||||||
|
|
||||||
static std::optional<CGRect> getRenderContentItemGlobalRect(std::shared_ptr<RenderTreeNodeContentItem> const &contentItem, lottie::Vector2D const &globalSize, lottie::CATransform3D const &parentTransform, BezierPathsBoundingBoxContext &bezierPathsBoundingBoxContext) {
|
static std::optional<CGRect> getRenderContentItemGlobalRect(std::shared_ptr<RenderTreeNodeContentItem> const &contentItem, lottie::Vector2D const &globalSize, lottie::CATransform3D const &parentTransform, BezierPathsBoundingBoxContext &bezierPathsBoundingBoxContext) {
|
||||||
if (!contentItem->renderData.isValid) {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto currentTransform = parentTransform;
|
auto currentTransform = parentTransform;
|
||||||
CATransform3D localTransform = contentItem->transform;
|
CATransform3D localTransform = contentItem->transform;
|
||||||
currentTransform = localTransform * currentTransform;
|
currentTransform = localTransform * currentTransform;
|
||||||
@ -185,52 +183,8 @@ static std::optional<CGRect> getRenderNodeGlobalRect(std::shared_ptr<RenderTreeN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void processRenderContentItem(std::shared_ptr<RenderTreeNodeContentItem> const &contentItem, Vector2D const &globalSize, CATransform3D const &parentTransform, BezierPathsBoundingBoxContext &bezierPathsBoundingBoxContext) {
|
static void processRenderTree(std::shared_ptr<RenderTreeNode> const &node, Vector2D const &globalSize, bool isInvertedMask, BezierPathsBoundingBoxContext &bezierPathsBoundingBoxContext) {
|
||||||
auto currentTransform = parentTransform;
|
if (node->isHidden() || node->alpha() < minVisibleAlpha) {
|
||||||
CATransform3D localTransform = contentItem->transform;
|
|
||||||
currentTransform = localTransform * currentTransform;
|
|
||||||
|
|
||||||
if (!currentTransform.isInvertible()) {
|
|
||||||
contentItem->renderData.isValid = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int drawContentDescendants = 0;
|
|
||||||
for (const auto &shadingVariant : contentItem->shadings) {
|
|
||||||
if (shadingVariant->stroke) {
|
|
||||||
} else if (shadingVariant->fill) {
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
drawContentDescendants += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contentItem->isGroup) {
|
|
||||||
for (auto it = contentItem->subItems.rbegin(); it != contentItem->subItems.rend(); it++) {
|
|
||||||
const auto &subItem = *it;
|
|
||||||
processRenderContentItem(subItem, globalSize, currentTransform, bezierPathsBoundingBoxContext);
|
|
||||||
|
|
||||||
if (subItem->renderData.isValid) {
|
|
||||||
drawContentDescendants += subItem->renderData.drawContentDescendants;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (const auto &subItem : contentItem->subItems) {
|
|
||||||
subItem->renderData.isValid = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem->renderData.isValid = true;
|
|
||||||
|
|
||||||
contentItem->renderData.layer.masksToBounds = false;
|
|
||||||
|
|
||||||
contentItem->renderData.drawContentDescendants = drawContentDescendants;
|
|
||||||
contentItem->renderData.isInvertedMatte = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void processRenderTree(std::shared_ptr<RenderTreeNode> const &node, Vector2D const &globalSize, CATransform3D const &parentTransform, bool isInvertedMask, BezierPathsBoundingBoxContext &bezierPathsBoundingBoxContext) {
|
|
||||||
if (node->isHidden() || node->alpha() == 0.0f) {
|
|
||||||
node->renderData.isValid = false;
|
node->renderData.isValid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -242,44 +196,16 @@ static void processRenderTree(std::shared_ptr<RenderTreeNode> const &node, Vecto
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto currentTransform = parentTransform;
|
|
||||||
Vector2D localTranslation(node->position().x + -node->bounds().x, node->position().y + -node->bounds().y);
|
|
||||||
CATransform3D localTransform = node->transform();
|
|
||||||
localTransform = localTransform.translated(localTranslation);
|
|
||||||
currentTransform = localTransform * currentTransform;
|
|
||||||
|
|
||||||
if (!currentTransform.isInvertible()) {
|
|
||||||
node->renderData.isValid = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int drawContentDescendants = 0;
|
|
||||||
if (node->_contentItem) {
|
|
||||||
processRenderContentItem(node->_contentItem, globalSize, currentTransform, bezierPathsBoundingBoxContext);
|
|
||||||
if (node->_contentItem->renderData.isValid) {
|
|
||||||
drawContentDescendants += node->_contentItem->renderData.drawContentDescendants;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isInvertedMatte = isInvertedMask;
|
bool isInvertedMatte = isInvertedMask;
|
||||||
|
|
||||||
for (const auto &item : node->subnodes()) {
|
for (const auto &subnode : node->subnodes()) {
|
||||||
processRenderTree(item, globalSize, currentTransform, false, bezierPathsBoundingBoxContext);
|
processRenderTree(subnode, globalSize, false, bezierPathsBoundingBoxContext);
|
||||||
if (item->renderData.isValid) {
|
if (subnode->renderData.isValid) {
|
||||||
drawContentDescendants += item->renderData.drawContentDescendants;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool masksToBounds = node->masksToBounds();
|
|
||||||
if (masksToBounds) {
|
|
||||||
CGRect effectiveGlobalBounds = node->bounds().applyingTransform(currentTransform);
|
|
||||||
if (effectiveGlobalBounds.contains(CGRect(0.0, 0.0, globalSize.x, globalSize.y))) {
|
|
||||||
masksToBounds = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->mask()) {
|
if (node->mask()) {
|
||||||
processRenderTree(node->mask(), globalSize, currentTransform, node->invertMask(), bezierPathsBoundingBoxContext);
|
processRenderTree(node->mask(), globalSize, node->invertMask(), bezierPathsBoundingBoxContext);
|
||||||
if (!node->mask()->renderData.isValid) {
|
if (!node->mask()->renderData.isValid) {
|
||||||
node->renderData.isValid = false;
|
node->renderData.isValid = false;
|
||||||
return;
|
return;
|
||||||
@ -288,9 +214,6 @@ static void processRenderTree(std::shared_ptr<RenderTreeNode> const &node, Vecto
|
|||||||
|
|
||||||
node->renderData.isValid = true;
|
node->renderData.isValid = true;
|
||||||
|
|
||||||
node->renderData.layer.masksToBounds = masksToBounds;
|
|
||||||
|
|
||||||
node->renderData.drawContentDescendants = drawContentDescendants;
|
|
||||||
node->renderData.isInvertedMatte = isInvertedMatte;
|
node->renderData.isInvertedMatte = isInvertedMatte;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,10 +222,6 @@ static void processRenderTree(std::shared_ptr<RenderTreeNode> const &node, Vecto
|
|||||||
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> parentContext, std::shared_ptr<lottie::RenderTreeNodeContentItem> item, float parentAlpha, lottie::Vector2D const &globalSize, lottie::CATransform3D const &parentTransform, lottie::BezierPathsBoundingBoxContext &bezierPathsBoundingBoxContext) {
|
||||||
if (!item->renderData.isValid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto currentTransform = parentTransform;
|
auto currentTransform = parentTransform;
|
||||||
lottie::CATransform3D localTransform = item->transform;
|
lottie::CATransform3D localTransform = item->transform;
|
||||||
currentTransform = localTransform * currentTransform;
|
currentTransform = localTransform * currentTransform;
|
||||||
@ -320,7 +239,7 @@ static void drawLottieContentItem(std::shared_ptr<lottieRendering::Canvas> paren
|
|||||||
std::shared_ptr<lottieRendering::Canvas> tempContext;
|
std::shared_ptr<lottieRendering::Canvas> tempContext;
|
||||||
|
|
||||||
bool needsTempContext = false;
|
bool needsTempContext = false;
|
||||||
needsTempContext = layerAlpha != 1.0 && item->renderData.drawContentDescendants > 1;
|
needsTempContext = layerAlpha != 1.0 && item->drawContentCount > 1;
|
||||||
|
|
||||||
std::optional<lottie::CGRect> globalRect;
|
std::optional<lottie::CGRect> globalRect;
|
||||||
if (needsTempContext) {
|
if (needsTempContext) {
|
||||||
@ -552,7 +471,7 @@ static void renderLottieRenderNode(std::shared_ptr<lottie::RenderTreeNode> node,
|
|||||||
float normalizedOpacity = node->alpha();
|
float normalizedOpacity = node->alpha();
|
||||||
float layerAlpha = ((float)normalizedOpacity) * parentAlpha;
|
float layerAlpha = ((float)normalizedOpacity) * parentAlpha;
|
||||||
|
|
||||||
if (node->isHidden() || normalizedOpacity == 0.0f) {
|
if (node->isHidden() || normalizedOpacity < minVisibleAlpha) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -568,11 +487,19 @@ static void renderLottieRenderNode(std::shared_ptr<lottie::RenderTreeNode> node,
|
|||||||
std::shared_ptr<lottieRendering::Canvas> currentContext;
|
std::shared_ptr<lottieRendering::Canvas> currentContext;
|
||||||
std::shared_ptr<lottieRendering::Canvas> tempContext;
|
std::shared_ptr<lottieRendering::Canvas> tempContext;
|
||||||
|
|
||||||
|
bool masksToBounds = node->masksToBounds();
|
||||||
|
if (masksToBounds) {
|
||||||
|
lottie::CGRect effectiveGlobalBounds = node->bounds().applyingTransform(currentTransform);
|
||||||
|
if (effectiveGlobalBounds.contains(lottie::CGRect(0.0, 0.0, globalSize.x, globalSize.y))) {
|
||||||
|
masksToBounds = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool needsTempContext = false;
|
bool needsTempContext = false;
|
||||||
if (node->mask() && node->mask()->renderData.isValid) {
|
if (node->mask() && node->mask()->renderData.isValid) {
|
||||||
needsTempContext = true;
|
needsTempContext = true;
|
||||||
} else {
|
} else {
|
||||||
needsTempContext = layerAlpha != 1.0 || node->renderData.layer.masksToBounds;
|
needsTempContext = layerAlpha != 1.0 || masksToBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<lottie::CGRect> globalRect;
|
std::optional<lottie::CGRect> globalRect;
|
||||||
@ -583,13 +510,13 @@ static void renderLottieRenderNode(std::shared_ptr<lottie::RenderTreeNode> node,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((node->mask() && node->mask()->renderData.isValid) || node->renderData.layer.masksToBounds) {
|
if ((node->mask() && node->mask()->renderData.isValid) || masksToBounds) {
|
||||||
auto maskBackingStorage = parentContext->makeLayer((int)(globalRect->width), (int)(globalRect->height));
|
auto maskBackingStorage = parentContext->makeLayer((int)(globalRect->width), (int)(globalRect->height));
|
||||||
|
|
||||||
maskBackingStorage->concatenate(lottie::CATransform3D::identity().translated(lottie::Vector2D(-globalRect->x, -globalRect->y)));
|
maskBackingStorage->concatenate(lottie::CATransform3D::identity().translated(lottie::Vector2D(-globalRect->x, -globalRect->y)));
|
||||||
maskBackingStorage->concatenate(currentTransform);
|
maskBackingStorage->concatenate(currentTransform);
|
||||||
|
|
||||||
if (node->renderData.layer.masksToBounds) {
|
if (masksToBounds) {
|
||||||
maskBackingStorage->fill(lottie::CGRect(node->bounds().x, node->bounds().y, node->bounds().width, node->bounds().height), lottie::Color(1.0, 1.0, 1.0, 1.0));
|
maskBackingStorage->fill(lottie::CGRect(node->bounds().x, node->bounds().y, node->bounds().width, node->bounds().height), lottie::Color(1.0, 1.0, 1.0, 1.0));
|
||||||
}
|
}
|
||||||
if (node->mask() && node->mask()->renderData.isValid) {
|
if (node->mask() && node->mask()->renderData.isValid) {
|
||||||
@ -679,10 +606,6 @@ CGRect getPathNativeBoundingBox(CGPathRef _Nonnull path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (UIImage * _Nullable)renderForSize:(CGSize)size useReferenceRendering:(bool)useReferenceRendering {
|
- (UIImage * _Nullable)renderForSize:(CGSize)size useReferenceRendering:(bool)useReferenceRendering {
|
||||||
if (!useReferenceRendering) {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
LottieAnimation *animation = _animationContainer.animation;
|
LottieAnimation *animation = _animationContainer.animation;
|
||||||
std::shared_ptr<lottie::RenderTreeNode> renderNode = [_animationContainer internalGetRootRenderTreeNode];
|
std::shared_ptr<lottie::RenderTreeNode> renderNode = [_animationContainer internalGetRootRenderTreeNode];
|
||||||
if (!renderNode) {
|
if (!renderNode) {
|
||||||
@ -691,7 +614,11 @@ 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));
|
||||||
|
|
||||||
processRenderTree(renderNode, lottie::Vector2D((int)size.width, (int)size.height), rootTransform, false, *_bezierPathsBoundingBoxContext.get());
|
processRenderTree(renderNode, lottie::Vector2D((int)size.width, (int)size.height), false, *_bezierPathsBoundingBoxContext.get());
|
||||||
|
|
||||||
|
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);
|
||||||
|
@ -78,7 +78,7 @@ private final class ReferenceCompareTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var continueFromName: String?
|
var continueFromName: String?
|
||||||
//continueFromName = "1137162165791228042.json"
|
//continueFromName = "4986037051573928320.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 {
|
||||||
|
@ -15,29 +15,11 @@ namespace lottie {
|
|||||||
|
|
||||||
class ProcessedRenderTreeNodeData {
|
class ProcessedRenderTreeNodeData {
|
||||||
public:
|
public:
|
||||||
struct LayerParams {
|
ProcessedRenderTreeNodeData() {
|
||||||
bool masksToBounds;
|
|
||||||
|
|
||||||
LayerParams(
|
|
||||||
bool masksToBounds_
|
|
||||||
) :
|
|
||||||
masksToBounds(masksToBounds_) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ProcessedRenderTreeNodeData() :
|
|
||||||
isValid(false),
|
|
||||||
layer(
|
|
||||||
false
|
|
||||||
),
|
|
||||||
drawContentDescendants(false),
|
|
||||||
isInvertedMatte(false) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isValid = false;
|
bool isValid = false;
|
||||||
LayerParams layer;
|
bool isInvertedMatte = false;
|
||||||
int drawContentDescendants;
|
|
||||||
bool isInvertedMatte;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class RenderableItem {
|
class RenderableItem {
|
||||||
@ -388,6 +370,7 @@ public:
|
|||||||
std::shared_ptr<RenderTreeNodeContentPath> path;
|
std::shared_ptr<RenderTreeNodeContentPath> path;
|
||||||
std::vector<std::shared_ptr<RenderTreeNodeContentShadingVariant>> shadings;
|
std::vector<std::shared_ptr<RenderTreeNodeContentShadingVariant>> shadings;
|
||||||
std::vector<std::shared_ptr<RenderTreeNodeContentItem>> subItems;
|
std::vector<std::shared_ptr<RenderTreeNodeContentItem>> subItems;
|
||||||
|
int drawContentCount = 0;
|
||||||
|
|
||||||
ProcessedRenderTreeNodeData renderData;
|
ProcessedRenderTreeNodeData renderData;
|
||||||
};
|
};
|
||||||
@ -427,6 +410,9 @@ public:
|
|||||||
_subnodes(subnodes_),
|
_subnodes(subnodes_),
|
||||||
_mask(mask_),
|
_mask(mask_),
|
||||||
_invertMask(invertMask_) {
|
_invertMask(invertMask_) {
|
||||||
|
for (const auto &subnode : _subnodes) {
|
||||||
|
drawContentCount += subnode->drawContentCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~RenderTreeNode() {
|
~RenderTreeNode() {
|
||||||
@ -477,6 +463,7 @@ public:
|
|||||||
bool _masksToBounds = false;
|
bool _masksToBounds = false;
|
||||||
bool _isHidden = false;
|
bool _isHidden = false;
|
||||||
std::shared_ptr<RenderTreeNodeContentItem> _contentItem;
|
std::shared_ptr<RenderTreeNodeContentItem> _contentItem;
|
||||||
|
int drawContentCount = 0;
|
||||||
std::vector<std::shared_ptr<RenderTreeNode>> _subnodes;
|
std::vector<std::shared_ptr<RenderTreeNode>> _subnodes;
|
||||||
std::shared_ptr<RenderTreeNode> _mask;
|
std::shared_ptr<RenderTreeNode> _mask;
|
||||||
bool _invertMask = false;
|
bool _invertMask = false;
|
||||||
|
@ -102,42 +102,6 @@ public:
|
|||||||
|
|
||||||
virtual std::shared_ptr<RenderTreeNode> renderTreeNode(BezierPathsBoundingBoxContext &boundingBoxContext) override {
|
virtual std::shared_ptr<RenderTreeNode> renderTreeNode(BezierPathsBoundingBoxContext &boundingBoxContext) override {
|
||||||
if (!_renderTreeNode) {
|
if (!_renderTreeNode) {
|
||||||
_contentsTreeNode = std::make_shared<RenderTreeNode>(
|
|
||||||
CGRect(0.0, 0.0, 0.0, 0.0),
|
|
||||||
Vector2D(0.0, 0.0),
|
|
||||||
CATransform3D::identity(),
|
|
||||||
1.0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
std::vector<std::shared_ptr<RenderTreeNode>>(),
|
|
||||||
nullptr,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<RenderTreeNode>> subnodes;
|
|
||||||
subnodes.push_back(_contentsTreeNode);
|
|
||||||
|
|
||||||
std::shared_ptr<RenderTreeNode> 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<RenderTreeNode>(
|
|
||||||
CGRect(0.0, 0.0, 0.0, 0.0),
|
|
||||||
Vector2D(0.0, 0.0),
|
|
||||||
CATransform3D::identity(),
|
|
||||||
1.0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
subnodes,
|
|
||||||
maskNode,
|
|
||||||
invertMask
|
|
||||||
);
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<RenderTreeNode>> renderTreeSubnodes;
|
std::vector<std::shared_ptr<RenderTreeNode>> renderTreeSubnodes;
|
||||||
for (const auto &animationLayer : _animationLayers) {
|
for (const auto &animationLayer : _animationLayers) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@ -171,7 +135,41 @@ public:
|
|||||||
renderTreeValue.push_back(renderTreeContentItem);
|
renderTreeValue.push_back(renderTreeContentItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
_contentsTreeNode->_subnodes = renderTreeValue;
|
_contentsTreeNode = std::make_shared<RenderTreeNode>(
|
||||||
|
CGRect(0.0, 0.0, 0.0, 0.0),
|
||||||
|
Vector2D(0.0, 0.0),
|
||||||
|
CATransform3D::identity(),
|
||||||
|
1.0,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
renderTreeValue,
|
||||||
|
nullptr,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<RenderTreeNode>> subnodes;
|
||||||
|
subnodes.push_back(_contentsTreeNode);
|
||||||
|
|
||||||
|
std::shared_ptr<RenderTreeNode> 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<RenderTreeNode>(
|
||||||
|
CGRect(0.0, 0.0, 0.0, 0.0),
|
||||||
|
Vector2D(0.0, 0.0),
|
||||||
|
CATransform3D::identity(),
|
||||||
|
1.0,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
subnodes,
|
||||||
|
maskNode,
|
||||||
|
invertMask
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_contentsTreeNode->_bounds = _contentsLayer->bounds();
|
_contentsTreeNode->_bounds = _contentsLayer->bounds();
|
||||||
|
@ -994,6 +994,8 @@ public:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_contentItem->drawContentCount++;
|
||||||
|
|
||||||
auto itemShadingVariant = std::make_shared<RenderTreeNodeContentShadingVariant>();
|
auto itemShadingVariant = std::make_shared<RenderTreeNodeContentShadingVariant>();
|
||||||
if (shadingVariant.fill) {
|
if (shadingVariant.fill) {
|
||||||
itemShadingVariant->fill = shadingVariant.fill->fill();
|
itemShadingVariant->fill = shadingVariant.fill->fill();
|
||||||
@ -1011,6 +1013,7 @@ public:
|
|||||||
std::vector<std::shared_ptr<RenderTreeNode>> subItemNodes;
|
std::vector<std::shared_ptr<RenderTreeNode>> subItemNodes;
|
||||||
for (const auto &subItem : subItems) {
|
for (const auto &subItem : subItems) {
|
||||||
subItem->initializeRenderChildren();
|
subItem->initializeRenderChildren();
|
||||||
|
_contentItem->drawContentCount += subItem->_contentItem->drawContentCount;
|
||||||
_contentItem->subItems.push_back(subItem->_contentItem);
|
_contentItem->subItems.push_back(subItem->_contentItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1331,9 +1334,9 @@ std::shared_ptr<RenderTreeNode> ShapeCompositionLayer::renderTreeNode(BezierPath
|
|||||||
false
|
false
|
||||||
);
|
);
|
||||||
_contentRenderTreeNode->_contentItem = _contentTree->itemTree->_contentItem;
|
_contentRenderTreeNode->_contentItem = _contentTree->itemTree->_contentItem;
|
||||||
|
_contentRenderTreeNode->drawContentCount = _contentTree->itemTree->_contentItem->drawContentCount;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<RenderTreeNode>> subnodes;
|
std::vector<std::shared_ptr<RenderTreeNode>> subnodes;
|
||||||
//subnodes.push_back(_contentTree->itemTree->renderTree());
|
|
||||||
subnodes.push_back(_contentRenderTreeNode);
|
subnodes.push_back(_contentRenderTreeNode);
|
||||||
|
|
||||||
std::shared_ptr<RenderTreeNode> maskNode;
|
std::shared_ptr<RenderTreeNode> maskNode;
|
||||||
|
@ -58,8 +58,6 @@
|
|||||||
result.isValid = node->renderData.isValid;
|
result.isValid = node->renderData.isValid;
|
||||||
|
|
||||||
|
|
||||||
result.hasSimpleContents = node->renderData.drawContentDescendants <= 1;
|
|
||||||
result.drawContentDescendants = node->renderData.drawContentDescendants;
|
|
||||||
result.isInvertedMatte = node->renderData.isInvertedMatte;
|
result.isInvertedMatte = node->renderData.isInvertedMatte;
|
||||||
if (node->mask()) {
|
if (node->mask()) {
|
||||||
result.maskId = (int64_t)node->mask().get();
|
result.maskId = (int64_t)node->mask().get();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user