svg_loader: support other units for mask and clip 09/313709/2
authorjoogab.yun <joogab.yun@samsung.com>
Mon, 1 Jul 2024 05:21:57 +0000 (14:21 +0900)
committerjoogab.yun <joogab.yun@samsung.com>
Mon, 1 Jul 2024 09:44:51 +0000 (18:44 +0900)
Added support for the objectBoundingBox value of
the clipPathUnits and for the userSpaceOnUse value
of the maskContentUnits.

Change-Id: I81d8d7701185881e68b4424b58ca6ee301e25dc4

src/loaders/svg/tvgSvgSceneBuilder.cpp

index c6ad906d010f76575e73030d52760d7d54072156..af003173ea70da37dc629d9106b453698f7cf25e 100644 (file)
@@ -53,6 +53,7 @@
 #include <cstring>
 #include <string>
 #include "tvgSvgLoaderCommon.h"
+#include "tvgPaint.h"
 #include "tvgSvgSceneBuilder.h"
 #include "tvgSvgPath.h"
 #include "tvgSvgUtil.h"
@@ -240,6 +241,25 @@ static bool _appendChildShape(SvgNode* node, Shape* shape, const Box& vBox, cons
     return valid;
 }
 
+static Matrix _compositionTransform(Paint* paint, const SvgNode* node, const SvgNode* compNode, SvgNodeType type)
+{
+    Matrix m = {1, 0, 0, 0, 1, 0, 0, 0, 1};
+    //The initial mask transformation ignored according to the SVG standard.
+    if (node->transform && type != SvgNodeType::Mask) {
+        m = *node->transform;
+    }
+    if (compNode->transform) {
+        m = mathMultiply(&m, compNode->transform);
+    }
+    if (!compNode->node.clip.userSpace) {
+        float x, y, w, h;
+        paint->bounds(&x, &y, &w, &h, false);
+        Matrix mBBox = {w, 0, x, 0, h, y, 0, 0, 1};
+        m = mathMultiply(&m, &mBBox);
+    }
+    return m;
+}
+
 
 static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox, const string& svgPath)
 {
@@ -263,7 +283,11 @@ static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox
                 if (_appendChildShape(*child, comp.get(), vBox, svgPath)) valid = true;
             }
 
-            if (valid) paint->composite(move(comp), CompositeMethod::ClipPath);
+            if (valid) {
+                Matrix finalTransform = _compositionTransform(paint, node, compNode, SvgNodeType::ClipPath);
+                comp->transform(finalTransform);
+                paint->composite(std::move(comp), CompositeMethod::ClipPath);
+            }
 
             node->style->clipPath.applying = false;
         }
@@ -280,9 +304,9 @@ static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox
             node->style->mask.applying = true;
 
             bool isMaskWhite = true;
-            auto comp = _sceneBuildHelper(compNode, vBox, svgPath, true, 0, &isMaskWhite);
-            if (comp) {
-                if (node->transform) comp->transform(*node->transform);
+            if (auto comp = _sceneBuildHelper(compNode, vBox, svgPath, true, 0, &isMaskWhite)) {
+                Matrix finalTransform = _compositionTransform(paint, node, compNode, SvgNodeType::Mask);
+                comp->transform(finalTransform);
 
                 if (compNode->node.mask.type == SvgMaskType::Luminance && !isMaskWhite) {
                     paint->composite(move(comp), CompositeMethod::LumaMask);