common picture: introduce picture feature which is for vector file extensions. 69/239869/5
authorHermet Park <chuneon.park@samsung.com>
Thu, 30 Jul 2020 07:50:29 +0000 (16:50 +0900)
committerHermet Park <chuneon.park@samsung.com>
Thu, 30 Jul 2020 08:13:00 +0000 (17:13 +0900)
Now Scene is only specialized for composition of Paint objects.

Change-Id: I16426913f029c89e9f9ac4d5e0afed11d1a228d0

inc/thorvg.h
src/lib/meson.build
src/lib/tvgCommon.h
src/lib/tvgPicture.cpp [new file with mode: 0644]
src/lib/tvgPictureImpl.h [new file with mode: 0644]
src/lib/tvgScene.cpp
src/lib/tvgSceneImpl.h
src/lib/tvgShape.cpp
src/lib/tvgShapeImpl.h
test/testSvg.cpp

index 36fed95..7c725bc 100644 (file)
@@ -268,6 +268,28 @@ public:
 
 
 /**
+ * @class Picture
+ *
+ * @ingroup ThorVG
+ *
+ * @brief description...
+ *
+ */
+class TVG_EXPORT Picture final : public Paint
+{
+public:
+    ~Picture();
+
+    Result load(const std::string& path) noexcept;
+    Result size(float* w, float* h) const noexcept;
+
+    static std::unique_ptr<Picture> gen() noexcept;
+
+    _TVG_DECLARE_PRIVATE(Picture);
+};
+
+
+/**
  * @class Scene
  *
  * @ingroup ThorVG
@@ -282,11 +304,11 @@ public:
 
     Result push(std::unique_ptr<Paint> paint) noexcept;
     Result reserve(uint32_t size) noexcept;
-    Result load(const std::string& path) noexcept;
 
     static std::unique_ptr<Scene> gen() noexcept;
 
     _TVG_DECLARE_PRIVATE(Scene);
+    _TVG_DECLARE_ACCESSOR(Picture);
 };
 
 
index 64cedbd..631016d 100644 (file)
@@ -16,6 +16,7 @@ source_file = [
    'tvgBezier.h',
    'tvgLoader.h',
    'tvgLoaderMgr.h',
+   'tvgPictureImpl.h',
    'tvgRender.h',
    'tvgSceneImpl.h',
    'tvgShapePath.h',
@@ -28,6 +29,7 @@ source_file = [
    'tvgLinearGradient.cpp',
    'tvgLoaderMgr.cpp',
    'tvgPaint.cpp',
+   'tvgPicture.cpp',
    'tvgRadialGradient.cpp',
    'tvgRender.cpp',
    'tvgScene.cpp',
index 4cec18f..dddac62 100644 (file)
@@ -31,8 +31,6 @@ using namespace std;
 using namespace tvg;
 
 #define IMPL pImpl.get()
-#define SCENE_IMPL scene->pImpl.get()
-#define SHAPE_IMPL shape->pImpl.get()
 
 #define FILL_ID_LINEAR 0
 #define FILL_ID_RADIAL 1
@@ -42,8 +40,5 @@ using namespace tvg;
 #include "tvgLoaderMgr.h"
 #include "tvgRender.h"
 #include "tvgPaint.h"
-#include "tvgShapePath.h"
-#include "tvgShapeImpl.h"
-#include "tvgSceneImpl.h"
 
 #endif //_TVG_COMMON_H_
diff --git a/src/lib/tvgPicture.cpp b/src/lib/tvgPicture.cpp
new file mode 100644 (file)
index 0000000..6d6ae47
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *               http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+#ifndef _TVG_PICTURE_CPP_
+#define _TVG_PICTURE_CPP_
+
+#include "tvgPictureImpl.h"
+
+/************************************************************************/
+/* External Class Implementation                                        */
+/************************************************************************/
+
+Picture::Picture() : pImpl(make_unique<Impl>())
+{
+    Paint::IMPL->method(new PaintMethod<Picture::Impl>(IMPL));
+}
+
+
+Picture::~Picture()
+{
+}
+
+
+unique_ptr<Picture> Picture::gen() noexcept
+{
+    return unique_ptr<Picture>(new Picture);
+}
+
+
+Result Picture::load(const std::string& path) noexcept
+{
+    if (path.empty()) return Result::InvalidArguments;
+
+    return IMPL->load(path);
+}
+
+
+Result Picture::size(float* w, float* h) const noexcept
+{
+    if (IMPL->size(w, h)) return Result::Success;
+    return Result::InsufficientCondition;
+}
+
+#endif /* _TVG_PICTURE_CPP_ */
\ No newline at end of file
diff --git a/src/lib/tvgPictureImpl.h b/src/lib/tvgPictureImpl.h
new file mode 100644 (file)
index 0000000..b72c556
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *               http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+#ifndef _TVG_PICTURE_IMPL_H_
+#define _TVG_PICTURE_IMPL_H_
+
+#include "tvgCommon.h"
+#include "tvgSceneImpl.h"
+
+/************************************************************************/
+/* Internal Class Implementation                                        */
+/************************************************************************/
+
+struct Picture::Impl
+{
+    unique_ptr<Loader> loader = nullptr;
+    Scene* scene = nullptr;
+    RenderTransform *rTransform = nullptr;
+    uint32_t flag = RenderUpdateFlag::None;
+
+    ~Impl()
+    {
+        if (rTransform) delete(rTransform);
+    }
+
+    bool dispose(RenderMethod& renderer)
+    {
+        if (!scene) return false;
+
+        scene->IMPL->dispose(renderer);
+        delete(scene);
+
+        return true;
+    }
+
+    bool update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t pFlag)
+    {
+        if (loader) {
+            auto scene = loader->data();
+            if (scene) {
+                this->scene = scene.release();
+                if (!this->scene) return false;
+                loader->close();
+            }
+        }
+
+        if (!scene) return false;
+
+        if (flag & RenderUpdateFlag::Transform) {
+            if (!rTransform) return false;
+            if (!rTransform->update()) {
+                delete(rTransform);
+                rTransform = nullptr;
+            }
+        }
+
+        auto ret = true;
+
+        if (rTransform && pTransform) {
+            RenderTransform outTransform(pTransform, rTransform);
+            ret = scene->IMPL->update(renderer, &outTransform, flag);
+        } else {
+            auto outTransform = pTransform ? pTransform : rTransform;
+            ret = scene->IMPL->update(renderer, outTransform, flag);
+        }
+
+        flag = RenderUpdateFlag::None;
+
+        return ret;
+    }
+
+    bool render(RenderMethod &renderer)
+    {
+        if (!scene) return false;
+        return scene->IMPL->render(renderer);
+    }
+
+
+    bool size(float* w, float* h)
+    {
+        if (loader) {
+            if (w) *w = loader->vw;
+            if (h) *h = loader->vh;
+            return true;
+        }
+
+        return false;
+    }
+
+    bool bounds(float* x, float* y, float* w, float* h)
+    {
+        if (!scene) return false;
+        return scene->IMPL->bounds(x, y, w, h);
+    }
+
+    bool scale(float factor)
+    {
+        if (rTransform) {
+            if (fabsf(factor - rTransform->scale) <= FLT_EPSILON) return true;
+        } else {
+            if (fabsf(factor) <= FLT_EPSILON) return true;
+            rTransform = new RenderTransform();
+            if (!rTransform) return false;
+        }
+        rTransform->scale = factor;
+        flag |= RenderUpdateFlag::Transform;
+
+        return true;
+    }
+
+    bool rotate(float degree)
+    {
+        if (rTransform) {
+            if (fabsf(degree - rTransform->degree) <= FLT_EPSILON) return true;
+        } else {
+            if (fabsf(degree) <= FLT_EPSILON) return true;
+            rTransform = new RenderTransform();
+            if (!rTransform) return false;
+        }
+        rTransform->degree = degree;
+        flag |= RenderUpdateFlag::Transform;
+
+        return true;
+    }
+
+    bool translate(float x, float y)
+    {
+        if (rTransform) {
+            if (fabsf(x - rTransform->x) <= FLT_EPSILON && fabsf(y - rTransform->y) <= FLT_EPSILON) return true;
+        } else {
+            if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON) return true;
+            rTransform = new RenderTransform();
+            if (!rTransform) return false;
+        }
+        rTransform->x = x;
+        rTransform->y = y;
+        flag |= RenderUpdateFlag::Transform;
+
+        return true;
+    }
+
+
+    bool transform(const Matrix& m)
+    {
+        if (!rTransform) {
+            rTransform = new RenderTransform();
+            if (!rTransform) return false;
+        }
+        rTransform->override(m);
+        flag |= RenderUpdateFlag::Transform;
+
+        return true;
+    }
+
+
+    Result load(const string& path)
+    {
+        if (loader) loader->close();
+        loader = LoaderMgr::loader(path.c_str());
+        if (!loader || !loader->open(path.c_str())) return Result::NonSupport;
+        if (!loader->read()) return Result::Unknown;
+        return Result::Success;
+    }
+};
+
+#endif //_TVG_PICTURE_IMPL_H_
\ No newline at end of file
index d34d57a..ff3aca8 100644 (file)
@@ -17,7 +17,7 @@
 #ifndef _TVG_SCENE_CPP_
 #define _TVG_SCENE_CPP_
 
-#include "tvgCommon.h"
+#include "tvgSceneImpl.h"
 
 /************************************************************************/
 /* External Class Implementation                                        */
@@ -57,12 +57,4 @@ Result Scene::reserve(uint32_t size) noexcept
     return Result::Success;
 }
 
-
-Result Scene::load(const std::string& path) noexcept
-{
-    if (path.empty()) return Result::InvalidArguments;
-
-     return IMPL->load(path);
-}
-
 #endif /* _TVG_SCENE_CPP_ */
\ No newline at end of file
index 0ba1f1f..84bdd7e 100644 (file)
@@ -28,12 +28,9 @@ struct Scene::Impl
     vector<Paint*> paints;
     RenderTransform *rTransform = nullptr;
     uint32_t flag = RenderUpdateFlag::None;
-    unique_ptr<Loader> loader = nullptr;
 
     ~Impl()
     {
-        //Are you sure clear() prior to this?
-        assert(paints.empty());
         if (rTransform) delete(rTransform);
     }
 
@@ -58,16 +55,6 @@ struct Scene::Impl
 
     bool update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t pFlag)
     {
-        if (loader) {
-            auto scene = loader->data();
-            if (scene) {
-                auto p = scene.release();
-                if (!p) return false;
-                paints.push_back(p);
-                loader->close();
-            }
-        }
-
         if (flag & RenderUpdateFlag::Transform) {
             if (!rTransform) return false;
             if (!rTransform->update()) {
@@ -101,37 +88,31 @@ struct Scene::Impl
 
     bool bounds(float* px, float* py, float* pw, float* ph)
     {
-        if (loader) {
-            if (px) *px = loader->vx;
-            if (py) *py = loader->vy;
-            if (pw) *pw = loader->vw;
-            if (ph) *ph = loader->vh;
-        } else {
-            auto x = FLT_MAX;
-            auto y = FLT_MAX;
-            auto w = 0.0f;
-            auto h = 0.0f;
-
-            for(auto paint: paints) {
-                auto x2 = FLT_MAX;
-                auto y2 = FLT_MAX;
-                auto w2 = 0.0f;
-                auto h2 = 0.0f;
-
-                if (paint->IMPL->method()->bounds(&x2, &y2, &w2, &h2)) return false;
-
-                //Merge regions
-                if (x2 < x) x = x2;
-                if (x + w < x2 + w2) w = (x2 + w2) - x;
-                if (y2 < y) y = x2;
-                if (y + h < y2 + h2) h = (y2 + h2) - y;
-            }
+        auto x = FLT_MAX;
+        auto y = FLT_MAX;
+        auto w = 0.0f;
+        auto h = 0.0f;
 
-            if (px) *px = x;
-            if (py) *py = y;
-            if (pw) *pw = w;
-            if (ph) *ph = h;
+        for(auto paint: paints) {
+            auto x2 = FLT_MAX;
+            auto y2 = FLT_MAX;
+            auto w2 = 0.0f;
+            auto h2 = 0.0f;
+
+            if (paint->IMPL->method()->bounds(&x2, &y2, &w2, &h2)) return false;
+
+            //Merge regions
+            if (x2 < x) x = x2;
+            if (x + w < x2 + w2) w = (x2 + w2) - x;
+            if (y2 < y) y = x2;
+            if (y + h < y2 + h2) h = (y2 + h2) - y;
         }
+
+        if (px) *px = x;
+        if (py) *py = y;
+        if (pw) *pw = w;
+        if (ph) *ph = h;
+
         return true;
     }
 
@@ -193,16 +174,6 @@ struct Scene::Impl
 
         return true;
     }
-
-
-    Result load(const string& path)
-    {
-        if (loader) loader->close();
-        loader = LoaderMgr::loader(path.c_str());
-        if (!loader || !loader->open(path.c_str())) return Result::NonSupport;
-        if (!loader->read()) return Result::Unknown;
-        return Result::Success;
-    }
 };
 
 #endif //_TVG_SCENE_IMPL_H_
\ No newline at end of file
index 7d26614..59718d8 100644 (file)
@@ -17,7 +17,6 @@
 #ifndef _TVG_SHAPE_CPP_
 #define _TVG_SHAPE_CPP_
 
-#include "tvgCommon.h"
 #include "tvgShapeImpl.h"
 
 /************************************************************************/
index a7755da..2a7005e 100644 (file)
@@ -18,6 +18,7 @@
 #define _TVG_SHAPE_IMPL_H_
 
 #include "tvgCommon.h"
+#include "tvgShapePath.h"
 
 /************************************************************************/
 /* Internal Class Implementation                                        */
index b8eb2ba..5f05370 100644 (file)
@@ -14,15 +14,15 @@ void svgDirCallback(const char* name, const char* path, void* data)
 {
     tvg::Canvas* canvas = static_cast<tvg::Canvas*>(data);
 
-    auto scene = tvg::Scene::gen();
+    auto picture = tvg::Picture::gen();
 
     char buf[PATH_MAX];
     sprintf(buf,"%s/%s", path, name);
 
-    if (scene->load(buf) != tvg::Result::Success) return;
+    if (picture->load(buf) != tvg::Result::Success) return;
 
-    scene->translate(((WIDTH - (x * 2)) / NUM_PER_LINE) * (count % NUM_PER_LINE) + x, ((HEIGHT - (y * 2))/ NUM_PER_LINE) * (int)((float)count / (float)NUM_PER_LINE) + y);
-    canvas->push(move(scene));
+    picture->translate(((WIDTH - (x * 2)) / NUM_PER_LINE) * (count % NUM_PER_LINE) + x, ((HEIGHT - (y * 2))/ NUM_PER_LINE) * (int)((float)count / (float)NUM_PER_LINE) + y);
+    canvas->push(move(picture));
 
     count++;