svg loader: converting the image path to the absolute one
authorMira Grudzinska <m.grudzinska@samsung.com>
Tue, 21 Sep 2021 01:11:47 +0000 (03:11 +0200)
committerHermet Park <chuneon.park@samsung.com>
Tue, 26 Oct 2021 04:11:42 +0000 (13:11 +0900)
The href image tag should point to an absolute image path.

src/examples/images/image-embeded.svg
src/examples/images/logo.png [new file with mode: 0644]
src/loaders/svg/tvgSvgLoader.cpp
src/loaders/svg/tvgSvgLoader.h
src/loaders/svg/tvgSvgSceneBuilder.cpp
src/loaders/svg/tvgSvgSceneBuilder.h

index 8f0712a..3104bec 100644 (file)
@@ -7,6 +7,6 @@
        <image href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='50' r='48' fill='none' stroke='%23000'/%3E%3Cpath d='M50,2a48,48 0 1 1 0,96a24 24 0 1 1 0-48a24 24 0 1 0 0-48'/%3E%3Ccircle cx='50' cy='26' r='6'/%3E%3Ccircle cx='50' cy='74' r='6' fill='%23FFF'/%3E%3C/svg%3E%0A" height="100" width="100" x="0" y="0" />
        <image href="data:image/svg+xml;utf8,%3Csvg+xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27+viewBox%3D%270+0+100+100%27%3E%3Ccircle+cx%3D%2750%27+cy%3D%2750%27+r%3D%2748%27+fill%3D%27none%27+stroke%3D%27%23000%27%2F%3E%3Cpath+d%3D%27M50%2C2a48%2C48+0+1+1+0%2C96a24+24+0+1+1+0-48a24+24+0+1+0+0-48%27%2F%3E%3Ccircle+cx%3D%2750%27+cy%3D%2726%27+r%3D%276%27%2F%3E%3Ccircle+cx%3D%2750%27+cy%3D%2774%27+r%3D%276%27+fill%3D%27%23FFF%27%2F%3E%3C%2Fsvg%3E%0D%0A" height="100" width="100" x="100" y="0" />
        <image href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCAxMDAgMTAwJz48Y2lyY2xlIGN4PSc1MCcgY3k9JzUwJyByPSc0OCcgZmlsbD0nbm9uZScgc3Ryb2tlPScjMDAwJy8+PHBhdGggZD0nTTUwLDJhNDgsNDggMCAxIDEgMCw5NmEyNCAyNCAwIDEgMSAwLTQ4YTI0IDI0IDAgMSAwIDAtNDgnLz48Y2lyY2xlIGN4PSc1MCcgY3k9JzI2JyByPSc2Jy8+PGNpcmNsZSBjeD0nNTAnIGN5PSc3NCcgcj0nNicgZmlsbD0nI0ZGRicvPjwvc3ZnPg0K" height="100" width="100" x="0" y="100" />
-       <image href="src/examples/images/yinyang.svg" height="100" width="100" x="100" y="100" />
-       <image href="src/examples/images/logo.png" height="80" width="80" x="60" y="60" clip-path="url(#circleView)" />
-</svg>
\ No newline at end of file
+       <image href="yinyang.svg" height="100" width="100" x="100" y="100" />
+       <image href="logo.png" height="80" width="80" x="60" y="60" clip-path="url(#circleView)" />
+</svg>
diff --git a/src/examples/images/logo.png b/src/examples/images/logo.png
new file mode 100644 (file)
index 0000000..b08abf8
Binary files /dev/null and b/src/examples/images/logo.png differ
index 88b2496..c1b3b33 100644 (file)
@@ -2788,7 +2788,7 @@ void SvgLoader::run(unsigned tid)
 
         if (loaderData.cloneNodes.count > 0) _clonePostponedNodes(&loaderData.cloneNodes);
     }
-    root = svgSceneBuild(loaderData.doc, vx, vy, vw, vh, w, h, preserveAspect);
+    root = svgSceneBuild(loaderData.doc, vx, vy, vw, vh, w, h, preserveAspect, svgPath);
 }
 
 
@@ -2857,6 +2857,7 @@ bool SvgLoader::open(const string& path)
 
     if (!f.is_open()) return false;
 
+    svgPath = path;
     getline(f, filePath, '\0');
     f.close();
 
index 01e90d4..468f058 100644 (file)
@@ -29,6 +29,7 @@ class SvgLoader : public LoadModule, public Task
 {
 public:
     string filePath;
+    string svgPath = "";
     const char* content = nullptr;
     uint32_t size = 0;
 
index 0026af4..fe7a2db 100644 (file)
@@ -469,7 +469,7 @@ static bool _isValidImageMimeTypeAndEncoding(const char** href, const char** mim
 }
 
 
-static unique_ptr<Picture> _imageBuildHelper(SvgNode* node, float vx, float vy, float vw, float vh)
+static unique_ptr<Picture> _imageBuildHelper(SvgNode* node, float vx, float vy, float vw, float vh, const string& svgPath)
 {
     if (!node->node.image.href) return nullptr;
     auto picture = Picture::gen();
@@ -496,7 +496,12 @@ static unique_ptr<Picture> _imageBuildHelper(SvgNode* node, float vx, float vy,
             TVGLOG("SVG", "Embedded svg file is disabled.");
             return nullptr;
         }
-        if (picture->load(href) != Result::Success) return nullptr;
+        string imagePath = href;
+        if (strncmp(href, "/", 1)) {
+            auto last = svgPath.find_last_of("/");
+            imagePath = svgPath.substr(0, (last == string::npos ? 0 : last + 1 )) + imagePath;
+        }
+        if (picture->load(imagePath) != Result::Success) return nullptr;
     }
 
     float w, h;
@@ -512,7 +517,7 @@ static unique_ptr<Picture> _imageBuildHelper(SvgNode* node, float vx, float vy,
 }
 
 
-static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, float vx, float vy, float vw, float vh)
+static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, float vx, float vy, float vw, float vh, const string& svgPath)
 {
     if (_isGroupType(node->type)) {
         auto scene = Scene::gen();
@@ -522,9 +527,9 @@ static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, float vx, float
             auto child = node->child.data;
             for (uint32_t i = 0; i < node->child.count; ++i, ++child) {
                 if (_isGroupType((*child)->type)) {
-                    scene->push(_sceneBuildHelper(*child, vx, vy, vw, vh));
+                    scene->push(_sceneBuildHelper(*child, vx, vy, vw, vh, svgPath));
                 } else if ((*child)->type == SvgNodeType::Image) {
-                    auto image = _imageBuildHelper(*child, vx, vy, vw, vh);
+                    auto image = _imageBuildHelper(*child, vx, vy, vw, vh, svgPath);
                     if (image) scene->push(move(image));
                 } else {
                     auto shape = _shapeBuildHelper(*child, vx, vy, vw, vh);
@@ -544,11 +549,11 @@ static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, float vx, float
 /* External Class Implementation                                        */
 /************************************************************************/
 
-unique_ptr<Scene> svgSceneBuild(SvgNode* node, float vx, float vy, float vw, float vh, float w, float h, bool preserveAspect)
+unique_ptr<Scene> svgSceneBuild(SvgNode* node, float vx, float vy, float vw, float vh, float w, float h, bool preserveAspect, const string& svgPath)
 {
     if (!node || (node->type != SvgNodeType::Doc)) return nullptr;
 
-    auto docNode = _sceneBuildHelper(node, vx, vy, vw, vh);
+    auto docNode = _sceneBuildHelper(node, vx, vy, vw, vh, svgPath);
 
     if (fabsf(w - vw) > FLT_EPSILON || fabsf(h - vh) > FLT_EPSILON) {
         auto sx = w / vw;
index a09e340..4232aca 100644 (file)
@@ -25,6 +25,6 @@
 
 #include "tvgCommon.h"
 
-unique_ptr<Scene> svgSceneBuild(SvgNode* node, float vx, float vy, float vw, float vh, float w, float h, bool preserveAspect);
+unique_ptr<Scene> svgSceneBuild(SvgNode* node, float vx, float vy, float vw, float vh, float w, float h, bool preserveAspect, const string& svgPath);
 
 #endif //_TVG_SVG_SCENE_BUILDER_H_