From 1eac97621e308292e8f6c86024c2e9c890aea1c6 Mon Sep 17 00:00:00 2001 From: Mira Grudzinska <67589014+mgrudzinska@users.noreply.github.com> Date: Mon, 19 Jul 2021 10:28:14 +0200 Subject: [PATCH] common: introducing basic iterators functionality The introduced Iterator class enables to access the children nodes of a given Paint. --- inc/thorvg.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++-- src/lib/tvgPaint.cpp | 41 ++++++++++++++++++++++++++++++++++++++++ src/lib/tvgPaint.h | 24 ++++++++++++++++++++++++ src/lib/tvgPictureImpl.h | 10 ++++++++++ src/lib/tvgScene.cpp | 2 +- src/lib/tvgSceneImpl.h | 22 ++++++++++++++++++++++ src/lib/tvgShapeImpl.h | 10 ++++++++++ 7 files changed, 155 insertions(+), 3 deletions(-) diff --git a/inc/thorvg.h b/inc/thorvg.h index 5677427..3a79822 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -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. */ diff --git a/src/lib/tvgPaint.cpp b/src/lib/tvgPaint.cpp index 3884468..fc5c741 100644 --- a/src/lib/tvgPaint.cpp +++ b/src/lib/tvgPaint.cpp @@ -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; +} diff --git a/src/lib/tvgPaint.h b/src/lib/tvgPaint.h index 76f01b8..f0b5c6c 100644 --- a/src/lib/tvgPaint.h +++ b/src/lib/tvgPaint.h @@ -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& 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); + } + }; } diff --git a/src/lib/tvgPictureImpl.h b/src/lib/tvgPictureImpl.h index 82d1718..e2bf355 100644 --- a/src/lib/tvgPictureImpl.h +++ b/src/lib/tvgPictureImpl.h @@ -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_ diff --git a/src/lib/tvgScene.cpp b/src/lib/tvgScene.cpp index 4f3699f..9ec6f05 100644 --- a/src/lib/tvgScene.cpp +++ b/src/lib/tvgScene.cpp @@ -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(pImpl)); diff --git a/src/lib/tvgSceneImpl.h b/src/lib/tvgSceneImpl.h index 1ea4c99..d4ef719 100644 --- a/src/lib/tvgSceneImpl.h +++ b/src/lib/tvgSceneImpl.h @@ -32,6 +32,7 @@ struct Scene::Impl { Array 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_ diff --git a/src/lib/tvgShapeImpl.h b/src/lib/tvgShapeImpl.h index 69d95b7..f0ea0c9 100644 --- a/src/lib/tvgShapeImpl.h +++ b/src/lib/tvgShapeImpl.h @@ -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_ -- 2.7.4