loader SvgSceneBuilder: Add root node to clipping viewBox.
authorJunsuChoi <jsuya.choi@samsung.com>
Mon, 15 Mar 2021 05:56:36 +0000 (14:56 +0900)
committerJunsuChoi <jsuya.choi@samsung.com>
Tue, 16 Mar 2021 01:05:46 +0000 (10:05 +0900)
If the boundary of scene created through the scenebuilder is larger than the viewbox,
scene(SVG's root) should be clipped to the size of the viewbox.
So, if scene need a clip, add a parent root and add clippath composition to that root.

src/loaders/svg/tvgSvgSceneBuilder.cpp

index 38b3b6e..0bbc023 100644 (file)
@@ -386,6 +386,32 @@ unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, float vx, float vy, flo
     return nullptr;
 }
 
+unique_ptr<Scene> _buildRoot(const SvgNode* node, float vx, float vy, float vw, float vh)
+{
+    unique_ptr<Scene> root;
+    auto docNode = move(_sceneBuildHelper(node, vx, vy, vw, vh));
+    float x, y, w, h;
+
+    if (docNode->bounds(&x, &y, &w, &h) != Result::Success) return nullptr;
+
+    if (x < vx || y < vy || w > vh || h > vh) {
+        auto viewBoxClip = Shape::gen();
+        viewBoxClip->appendRect(vx, vy ,vw, vh, 0, 0);
+        viewBoxClip->fill(0, 0, 0, 255);
+
+        auto compositeLayer = Scene::gen();
+        compositeLayer->composite(move(viewBoxClip), tvg::CompositeMethod::ClipPath);
+        compositeLayer->push(move(docNode));
+
+        root = Scene::gen();
+        root->push(move(compositeLayer));
+    }
+    else
+    {
+        root = move(docNode);
+    }
+    return root;
+}
 
 SvgSceneBuilder::SvgSceneBuilder()
 {
@@ -401,5 +427,5 @@ unique_ptr<Scene> SvgSceneBuilder::build(SvgNode* node)
 {
     if (!node || (node->type != SvgNodeType::Doc)) return nullptr;
 
-    return _sceneBuildHelper(node, node->node.doc.vx, node->node.doc.vy, node->node.doc.vw, node->node.doc.vh);
+    return _buildRoot(node, node->node.doc.vx, node->node.doc.vy, node->node.doc.vw, node->node.doc.vh);
 }