mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-09 14:13:43 +00:00
svg: fixed broken clip regression bugs
introduced by 8492a63
https://github.com/thorvg/thorvg/issues/3083
https://github.com/thorvg/thorvg/issues/3082
This commit is contained in:
parent
5ea1db128e
commit
7e810ce54d
1 changed files with 34 additions and 24 deletions
|
@ -184,8 +184,8 @@ static bool _appendClipChild(SvgLoaderData& loaderData, SvgNode* node, Shape* sh
|
||||||
{
|
{
|
||||||
//The SVG standard allows only for 'use' nodes that point directly to a basic shape.
|
//The SVG standard allows only for 'use' nodes that point directly to a basic shape.
|
||||||
if (node->type == SvgNodeType::Use) {
|
if (node->type == SvgNodeType::Use) {
|
||||||
|
if (node->child.count != 1) return false;
|
||||||
auto child = *(node->child.data);
|
auto child = *(node->child.data);
|
||||||
|
|
||||||
Matrix finalTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
|
Matrix finalTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
|
||||||
if (node->transform) finalTransform = *node->transform;
|
if (node->transform) finalTransform = *node->transform;
|
||||||
if (node->node.use.x != 0.0f || node->node.use.y != 0.0f) {
|
if (node->node.use.x != 0.0f || node->node.use.y != 0.0f) {
|
||||||
|
@ -217,11 +217,32 @@ static Matrix _compositionTransform(Paint* paint, const SvgNode* node, const Svg
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _applyClip(SvgLoaderData& loaderData, Paint* paint, const SvgNode* node, const SvgNode* clipNode, const Box& vBox, const string& svgPath)
|
||||||
|
{
|
||||||
|
node->style->clipPath.applying = true;
|
||||||
|
|
||||||
|
auto clipper = Shape::gen();
|
||||||
|
auto child = clipNode->child.data;
|
||||||
|
auto valid = false; //Composite only when valid shapes exist
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < clipNode->child.count; ++i, ++child) {
|
||||||
|
if (_appendClipChild(loaderData, *child, clipper, vBox, svgPath)) valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
Matrix finalTransform = _compositionTransform(paint, node, clipNode, SvgNodeType::ClipPath);
|
||||||
|
clipper->transform(finalTransform);
|
||||||
|
paint->clip(clipper);
|
||||||
|
} else {
|
||||||
|
delete(clipper);
|
||||||
|
}
|
||||||
|
|
||||||
|
node->style->clipPath.applying = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static Paint* _applyComposition(SvgLoaderData& loaderData, Paint* paint, const SvgNode* node, const Box& vBox, const string& svgPath)
|
static Paint* _applyComposition(SvgLoaderData& loaderData, Paint* paint, const SvgNode* node, const Box& vBox, const string& svgPath)
|
||||||
{
|
{
|
||||||
/* Do not drop in Circular Dependency for ClipPath.
|
|
||||||
Composition can be applied recursively if its children nodes have composition target to this one. */
|
|
||||||
if (node->style->clipPath.applying || node->style->mask.applying) {
|
if (node->style->clipPath.applying || node->style->mask.applying) {
|
||||||
TVGLOG("SVG", "Multiple composition tried! Check out circular dependency?");
|
TVGLOG("SVG", "Multiple composition tried! Check out circular dependency?");
|
||||||
return paint;
|
return paint;
|
||||||
|
@ -237,25 +258,7 @@ static Paint* _applyComposition(SvgLoaderData& loaderData, Paint* paint, const S
|
||||||
auto scene = Scene::gen();
|
auto scene = Scene::gen();
|
||||||
scene->push(paint);
|
scene->push(paint);
|
||||||
|
|
||||||
if (validClip) {
|
if (validClip) _applyClip(loaderData, scene, node, clipNode, vBox, svgPath);
|
||||||
node->style->clipPath.applying = true;
|
|
||||||
|
|
||||||
auto clipper = Shape::gen();
|
|
||||||
auto child = clipNode->child.data;
|
|
||||||
auto valid = false; //Composite only when valid shapes exist
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < clipNode->child.count; ++i, ++child) {
|
|
||||||
if (_appendClipChild(loaderData, *child, clipper, vBox, svgPath)) valid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valid) {
|
|
||||||
Matrix finalTransform = _compositionTransform(paint, node, clipNode, SvgNodeType::ClipPath);
|
|
||||||
clipper->transform(finalTransform);
|
|
||||||
scene->clip(clipper);
|
|
||||||
}
|
|
||||||
|
|
||||||
node->style->clipPath.applying = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mask */
|
/* Mask */
|
||||||
if (validMask) {
|
if (validMask) {
|
||||||
|
@ -412,14 +415,14 @@ static Paint* _shapeBuildHelper(SvgLoaderData& loaderData, SvgNode* node, const
|
||||||
|
|
||||||
static bool _appendClipShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath, const Matrix* transform)
|
static bool _appendClipShape(SvgLoaderData& loaderData, SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath, const Matrix* transform)
|
||||||
{
|
{
|
||||||
|
auto currentPtsCnt = shape->pathCoords(nullptr);
|
||||||
|
|
||||||
if (!_recognizeShape(node, shape)) return false;
|
if (!_recognizeShape(node, shape)) return false;
|
||||||
|
|
||||||
//The 'transform' matrix has higher priority than the node->transform, since it already contains it
|
//The 'transform' matrix has higher priority than the node->transform, since it already contains it
|
||||||
auto m = transform ? transform : (node->transform ? node->transform : nullptr);
|
auto m = transform ? transform : (node->transform ? node->transform : nullptr);
|
||||||
|
|
||||||
uint32_t currentPtsCnt = 0;
|
|
||||||
if (m) {
|
if (m) {
|
||||||
currentPtsCnt = shape->pathCoords(nullptr);
|
|
||||||
const Point *pts = nullptr;
|
const Point *pts = nullptr;
|
||||||
auto ptsCnt = shape->pathCoords(&pts);
|
auto ptsCnt = shape->pathCoords(&pts);
|
||||||
auto p = const_cast<Point*>(pts) + currentPtsCnt;
|
auto p = const_cast<Point*>(pts) + currentPtsCnt;
|
||||||
|
@ -429,6 +432,13 @@ static bool _appendClipShape(SvgLoaderData& loaderData, SvgNode* node, Shape* sh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Apply Clip Chaining
|
||||||
|
auto clipNode = node->style->clipPath.node;
|
||||||
|
if (clipNode && clipNode->child.count > 0) {
|
||||||
|
if (node->style->clipPath.applying) TVGLOG("SVG", "Multiple composition tried! Check out circular dependency?");
|
||||||
|
else _applyClip(loaderData, shape, node, clipNode, vBox, svgPath);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue