From 65c4e274373247dfde8fcfadf8ba423ebb37ef9d Mon Sep 17 00:00:00 2001 From: Mira Grudzinska Date: Thu, 17 Apr 2025 07:42:26 +0200 Subject: [PATCH] svg_loader: fix clipping in use/symbol nodes Clipping for the node when a was used, was being overridden when 'overflowVisible' was 'true' (the default value), which caused the 'clip-path' applied to the node to have no visible effect. The clipping for the node (without node) was transformed in an incorrect order, resulting in a visually incorrect results. @Issue: https://github.com/thorvg/thorvg/issues/3392 --- src/loaders/svg/tvgSvgSceneBuilder.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/loaders/svg/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp index 7d2b3f19..616d2a5f 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -807,12 +807,22 @@ static Scene* _useBuildHelper(SvgLoaderData& loaderData, const SvgNode* node, co } viewBoxClip->transform(mClipTransform); - scene->clip(viewBoxClip); + auto clippingLayer = Scene::gen(); + clippingLayer->clip(viewBoxClip); + clippingLayer->push(scene); + return clippingLayer; } - } else { - scene->transform(mUseTransform); + return scene; } + if (auto clipper = PAINT(scene)->clipper) { + auto& clipTransform = clipper->transform(); + Matrix inv; + if (node->transform && inverse(node->transform, &inv)) clipTransform = inv * clipTransform; + clipTransform = mUseTransform * clipTransform ; + } + + scene->transform(mUseTransform); return scene; } @@ -888,7 +898,9 @@ static Scene* _sceneBuildHelper(SvgLoaderData& loaderData, const SvgNode* node, auto scene = Scene::gen(); // For a Symbol node, the viewBox transformation has to be applied first - see _useBuildHelper() - if (!mask && node->transform && node->type != SvgNodeType::Symbol) scene->transform(*node->transform); + if (!mask && node->transform && node->type != SvgNodeType::Symbol && node->type != SvgNodeType::Use) { + scene->transform(*node->transform); + } if (!node->style->display || node->style->opacity == 0) return scene;