common: introducing basic iterators functionality
authorMira Grudzinska <67589014+mgrudzinska@users.noreply.github.com>
Mon, 19 Jul 2021 08:28:14 +0000 (10:28 +0200)
committerJunsuChoi <jsuya.choi@samsung.com>
Thu, 22 Jul 2021 08:24:22 +0000 (17:24 +0900)
The introduced Iterator class enables to access the children nodes
of a given Paint.

inc/thorvg.h
src/lib/tvgPaint.cpp
src/lib/tvgPaint.h
src/lib/tvgPictureImpl.h
src/lib/tvgScene.cpp
src/lib/tvgSceneImpl.h
src/lib/tvgShapeImpl.h

index 5677427..3a79822 100644 (file)
@@ -300,6 +300,51 @@ public:
     uint8_t opacity() const noexcept;
 
     /**
+     * @brief Const forward iterator-like class enabling the iteration over the children nodes of the given paint.
+     *
+     * For the Scene-type Paint the children nodes represent the paints pushed into the Scene - the order of the children nodes is the same as the order as they were pushed. For the Picture-type Paint the child node is the read image in one of the supported formats. The Shape-type Paint doesn't have any child nodes.
+     *
+     * @BETA_API
+     */
+    class Iterator
+    {
+        const Paint* parent;
+        const Paint* child;
+
+        public:
+            Iterator (Paint* p = nullptr, Paint* c = nullptr);
+            const Paint& operator*() const;
+            Iterator& operator++();
+            Iterator operator++(int);
+            friend bool operator!=(const Iterator& it1, const Iterator& it2)
+            {
+                return it1.child != it2.child;
+            };
+            friend bool operator==(const Iterator& it1, const Iterator& it2)
+            {
+                return it1.child == it2.child;
+            };
+    };
+
+    /**
+     * @brief Gets the iterator to the first child node.
+     *
+     * @return The iterator pointing to the first element of the children nodes of the given paint object.
+     *
+     * @BETA_API
+     */
+    Iterator begin() const noexcept;
+
+    /**
+     * @brief Gets the iterator to the past-the end child node.
+     *
+     * @return The iterator referring to the past-the-end element of the children nodes of the given paint object.
+     *
+     * @BETA_API
+     */
+    Iterator end() const noexcept;
+
+    /**
      * @brief Gets the composition target object and the composition method.
      *
      * @param[out] target The paint of the target object.
@@ -685,7 +730,7 @@ public:
      * The rectangle with rounded corners can be achieved by setting non-zero values to @p rx and @p ry arguments.
      * The @p rx and @p ry values specify the radii of the ellipse defining the rounding of the corners.
      *
-     * The position of the rectangle is specified by the coordinates of its upper left corner -  @p x and @p y arguments.
+     * The position of the rectangle is specified by the coordinates of its upper left corner - @p x and @p y arguments.
      *
      * The rectangle is treated as a new sub-path - it is not connected with the previous sub-path.
      *
@@ -973,7 +1018,7 @@ public:
  * @class Picture
  *
  * @brief A class representing an image read in one of the supported formats: raw, svg, png and etc.
- * Besides the methods inherited from the Paint, it provides  methods to load & draw images on the canvas.
+ * Besides the methods inherited from the Paint, it provides methods to load & draw images on the canvas.
  *
  * @note Supported formats are depended on the available TVG loaders.
  */
index 3884468..fc5c741 100644 (file)
@@ -331,3 +331,44 @@ uint8_t Paint::opacity() const noexcept
 {
     return pImpl->opacity;
 }
+
+
+Paint::Iterator Paint::begin() const noexcept
+{
+    return pImpl->begin();
+}
+
+
+Paint::Iterator Paint::end() const noexcept
+{
+    return Paint::Iterator();
+}
+
+
+Paint::Iterator::Iterator(Paint* p, Paint* c) : parent{p}, child{c}
+{
+}
+
+
+const Paint& Paint::Iterator::operator*() const
+{
+    return *child;
+}
+
+
+Paint::Iterator& Paint::Iterator::operator++() //prefix
+{
+    const Paint* nextChild = nullptr;
+    if (parent) nextChild = parent->pImpl->next(child);
+    child = nextChild;
+
+    return *this;
+}
+
+
+Paint::Iterator Paint::Iterator::operator++(int) //postfix
+{
+    Iterator tmp = *this;
+    ++*this;
+    return tmp;
+}
index 76f01b8..f0b5c6c 100644 (file)
@@ -37,6 +37,8 @@ namespace tvg
         virtual bool bounds(float* x, float* y, float* w, float* h) const = 0;
         virtual RenderRegion bounds(RenderMethod& renderer) const = 0;
         virtual Paint* duplicate() = 0;
+        virtual Paint::Iterator begin() = 0;
+        virtual const Paint* next(const Paint* p) = 0;
     };
 
     struct Paint::Impl
@@ -111,6 +113,17 @@ namespace tvg
         void* update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, uint32_t pFlag);
         bool render(RenderMethod& renderer);
         Paint* duplicate();
+
+        Paint::Iterator begin()
+        {
+            return smethod->begin();
+        }
+
+        const Paint* next(const Paint* p)
+        {
+            return smethod->next(p);
+        }
+
     };
 
 
@@ -151,6 +164,17 @@ namespace tvg
         {
             return inst->duplicate();
         }
+
+        Paint::Iterator begin() override
+        {
+            return inst->begin();
+        }
+
+        const Paint* next(const Paint* p) override
+        {
+            return inst->next(p);
+        }
+
     };
 }
 
index 82d1718..e2bf355 100644 (file)
@@ -218,6 +218,16 @@ struct Picture::Impl
 
         return ret.release();
     }
+
+    Paint::Iterator begin()
+    {
+        return Paint::Iterator(picture, paint);
+    }
+
+    const Paint* next(const Paint* p)
+    {
+        return nullptr;
+    }
 };
 
 #endif //_TVG_PICTURE_IMPL_H_
index 4f3699f..9ec6f05 100644 (file)
@@ -25,7 +25,7 @@
 /* External Class Implementation                                        */
 /************************************************************************/
 
-Scene::Scene() : pImpl(new Impl())
+Scene::Scene() : pImpl(new Impl(this))
 {
     _id = PAINT_ID_SCENE;
     Paint::pImpl->method(new PaintMethod<Scene::Impl>(pImpl));
index 1ea4c99..d4ef719 100644 (file)
@@ -32,6 +32,7 @@
 struct Scene::Impl
 {
     Array<Paint*> paints;
+    Scene* scene = nullptr;
     uint8_t opacity;            //for composition
     RenderMethod* renderer = nullptr;    //keep it for explicit clear
 
@@ -42,6 +43,10 @@ struct Scene::Impl
         }
     }
 
+    Impl(Scene* s) : scene(s)
+    {
+    }
+
     bool dispose(RenderMethod& renderer)
     {
         for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) {
@@ -181,6 +186,23 @@ struct Scene::Impl
         paints.clear();
         renderer = nullptr;
     }
+
+    Paint::Iterator begin()
+    {
+        if (paints.count > 0) return Paint::Iterator(scene, *(paints.data));
+        return Paint::Iterator();
+    }
+
+    const Paint* next(const Paint* p)
+    {
+        for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) {
+            auto tmp = paint;
+            if (*paint == p && ++tmp < (paints.data + paints.count)) {
+                return *tmp;
+            }
+        }
+        return nullptr;
+    }
 };
 
 #endif //_TVG_SCENE_IMPL_H_
index 69d95b7..f0ea0c9 100644 (file)
@@ -390,6 +390,16 @@ struct Shape::Impl
 
         return ret.release();
     }
+
+    Paint::Iterator begin()
+    {
+        return Paint::Iterator();
+    }
+
+    const Paint* next(const Paint* p)
+    {
+        return nullptr;
+    }
 };
 
 #endif //_TVG_SHAPE_IMPL_H_