From 35be541018648e2be601c64453c9b6bbf2f64d6d Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Wed, 23 Jun 2021 17:04:23 +0900 Subject: [PATCH] CanvasRenderer: Add Drawable::SetClipPath() Api Clipping source drawable based on Path data. Change-Id: Idd0a20d4d5e0a2243bc1b7781b06f02296fc508d --- .../adaptor-framework/canvas-renderer-drawable.cpp | 5 +++ .../adaptor-framework/canvas-renderer-drawable.h | 7 ++++ .../canvas-renderer/common/drawable-impl.cpp | 27 ++++++++++++++ .../canvas-renderer/common/drawable-impl.h | 28 +++++++++++++++ .../generic/drawable-impl-generic.cpp | 15 ++++++++ .../generic/drawable-impl-generic.h | 15 ++++++++ .../tizen/canvas-renderer-impl-tizen.cpp | 29 +++++++++++++++ .../canvas-renderer/tizen/drawable-impl-tizen.cpp | 41 +++++++++++++++++++++- .../canvas-renderer/tizen/drawable-impl-tizen.h | 22 ++++++++++-- .../ubuntu/canvas-renderer-impl-ubuntu.cpp | 29 +++++++++++++++ .../ubuntu/drawable-impl-ubuntu.cpp | 41 +++++++++++++++++++++- .../canvas-renderer/ubuntu/drawable-impl-ubuntu.h | 23 ++++++++++-- 12 files changed, 274 insertions(+), 8 deletions(-) diff --git a/dali/devel-api/adaptor-framework/canvas-renderer-drawable.cpp b/dali/devel-api/adaptor-framework/canvas-renderer-drawable.cpp index 1529b42..d29c004 100644 --- a/dali/devel-api/adaptor-framework/canvas-renderer-drawable.cpp +++ b/dali/devel-api/adaptor-framework/canvas-renderer-drawable.cpp @@ -74,6 +74,11 @@ Rect CanvasRenderer::Drawable::GetBoundingBox() const return GetImplementation(*this).GetBoundingBox(); } +bool CanvasRenderer::Drawable::SetClipPath(Drawable& clip) +{ + return GetImplementation(*this).SetClipPath(clip); +} + CanvasRenderer::Drawable CanvasRenderer::Drawable::DownCast(BaseHandle handle) { return CanvasRenderer::Drawable(dynamic_cast(handle.GetObjectPtr())); diff --git a/dali/devel-api/adaptor-framework/canvas-renderer-drawable.h b/dali/devel-api/adaptor-framework/canvas-renderer-drawable.h index d9f0dd3..6251375 100644 --- a/dali/devel-api/adaptor-framework/canvas-renderer-drawable.h +++ b/dali/devel-api/adaptor-framework/canvas-renderer-drawable.h @@ -115,6 +115,13 @@ public: Rect GetBoundingBox() const; /** + * @brief The intersection with clip drawable is determined and only the resulting pixels from own drawable are rendered. + * @param[in] clip The clip drawable object. + * @return Returns True when it's successful. False otherwise. + */ + bool SetClipPath(Drawable& clip); + + /** * @brief Downcast a handle to Drawable handle. * * If handle points to an InputMethodContext the downcast produces valid diff --git a/dali/internal/canvas-renderer/common/drawable-impl.cpp b/dali/internal/canvas-renderer/common/drawable-impl.cpp index 3856e06..d8d5a57 100644 --- a/dali/internal/canvas-renderer/common/drawable-impl.cpp +++ b/dali/internal/canvas-renderer/common/drawable-impl.cpp @@ -106,6 +106,33 @@ Rect Drawable::GetBoundingBox() const return mImpl->GetBoundingBox(); } +bool Drawable::SetClipPath(Dali::CanvasRenderer::Drawable& clip) +{ + if(!mImpl) + { + return false; + } + return mImpl->SetClipPath(clip); +} + +Dali::CanvasRenderer::Drawable Drawable::GetCompositionDrawable() const +{ + if(!mImpl) + { + return Dali::CanvasRenderer::Drawable(); + } + return mImpl->GetCompositionDrawable(); +} + +Dali::Internal::Adaptor::Drawable::CompositionType Drawable::GetCompositionType() const +{ + if(!mImpl) + { + return Dali::Internal::Adaptor::Drawable::CompositionType::NONE; + } + return mImpl->GetCompositionType(); +} + void Drawable::SetAdded(bool added) { if(!mImpl) diff --git a/dali/internal/canvas-renderer/common/drawable-impl.h b/dali/internal/canvas-renderer/common/drawable-impl.h index d4439ed..d9fd55e 100644 --- a/dali/internal/canvas-renderer/common/drawable-impl.h +++ b/dali/internal/canvas-renderer/common/drawable-impl.h @@ -47,6 +47,17 @@ public: DRAWABLE_GROUP ///< Meaning of DrawableGorup class that inherits Drawable. }; + /** + * @brief Enumeration indicating type used in the composition of two objects - the target and the source. + */ + enum class CompositionType + { + NONE = 0, ///< Means that type is not defined. + CLIP_PATH, ///< The intersection of the source and the target is determined and only the resulting pixels from the source are rendered. + ALPHA_MASK, ///< The pixels of the source and the target are alpha blended. As a result, only the part of the source, which intersects with the target is visible. + ALPHA_MASK_INVERSE ///< The pixels of the source and the complement to the target's pixels are alpha blended. As a result, only the part of the source which is not covered by the target is visible. + }; + public: /** * @brief Constructor @@ -99,6 +110,23 @@ public: virtual Rect GetBoundingBox() const; /** + * @copydoc Dali::CanvasRenderer::Drawable::SetClipPath() + */ + virtual bool SetClipPath(Dali::CanvasRenderer::Drawable& clip); + + /** + * @brief Returns a composition drawble object. + * @return Returns a composition drawble object. + */ + virtual Dali::CanvasRenderer::Drawable GetCompositionDrawable() const; + + /** + * @brief Returns a composition type + * @return Returns a composition type + */ + virtual CompositionType GetCompositionType() const; + + /** * @brief Set whether this drawable object was added to other object(CanvasRenderer or DrawableGroup) or not. * @param[in] added Ture if added, false otherwise. */ diff --git a/dali/internal/canvas-renderer/generic/drawable-impl-generic.cpp b/dali/internal/canvas-renderer/generic/drawable-impl-generic.cpp index bbd4bab..d162f59 100644 --- a/dali/internal/canvas-renderer/generic/drawable-impl-generic.cpp +++ b/dali/internal/canvas-renderer/generic/drawable-impl-generic.cpp @@ -88,6 +88,21 @@ Rect DrawableGeneric::GetBoundingBox() const return Rect(0, 0, 0, 0); } +bool DrawableGeneric::SetClipPath(Dali::CanvasRenderer::Drawable& clip) +{ + return false; +} + +Dali::CanvasRenderer::Drawable DrawableGeneric::GetCompositionDrawable() const +{ + return Dali::CanvasRenderer::Drawable(); +} + +Drawable::CompositionType DrawableGeneric::GetCompositionType() const +{ + return Drawable::CompositionType::NONE; +} + void DrawableGeneric::SetAdded(bool added) { } diff --git a/dali/internal/canvas-renderer/generic/drawable-impl-generic.h b/dali/internal/canvas-renderer/generic/drawable-impl-generic.h index 41558a0..2b299dd 100644 --- a/dali/internal/canvas-renderer/generic/drawable-impl-generic.h +++ b/dali/internal/canvas-renderer/generic/drawable-impl-generic.h @@ -80,6 +80,21 @@ public: Rect GetBoundingBox() const override; /** + * @copydoc Dali::CanvasRenderer::Drawable::SetClipPath() + */ + bool SetClipPath(Dali::CanvasRenderer::Drawable& clip) override; + + /** + * @copydoc Internal::Adaptor::Drawable::GetCompositionDrawable() + */ + Dali::CanvasRenderer::Drawable GetCompositionDrawable() const override; + + /** + * @copydoc Internal::Adaptor::Drawable::GetCompositionType() + */ + CompositionType GetCompositionType() const override; + + /** * @copydoc Internal::Adaptor::Drawable::SetAdded() */ void SetAdded(bool added) override; diff --git a/dali/internal/canvas-renderer/tizen/canvas-renderer-impl-tizen.cpp b/dali/internal/canvas-renderer/tizen/canvas-renderer-impl-tizen.cpp index f86723d..422ef2d 100644 --- a/dali/internal/canvas-renderer/tizen/canvas-renderer-impl-tizen.cpp +++ b/dali/internal/canvas-renderer/tizen/canvas-renderer-impl-tizen.cpp @@ -264,6 +264,35 @@ void CanvasRendererTizen::PushDrawableToGroup(Dali::CanvasRenderer::Drawable& dr } } + Dali::CanvasRenderer::Drawable compositeDrawable = drawableImpl.GetCompositionDrawable(); + if(DALI_UNLIKELY(compositeDrawable)) + { + Internal::Adaptor::Drawable& compositeDrawableImpl = Dali::GetImplementation(compositeDrawable); + tvg::Paint* tvgCompositeObject = static_cast(compositeDrawableImpl.GetObject()); + if(tvgCompositeObject) + { + tvg::Paint* tvgDuplicatedCompositeObject = tvgCompositeObject->duplicate(); + Drawable::Types type = compositeDrawableImpl.GetType(); + + if(type == Drawable::Types::DRAWABLE_GROUP) + { + Dali::CanvasRenderer::DrawableGroup& compositeGroup = static_cast(compositeDrawable); + Internal::Adaptor::DrawableGroup& compositeDrawableGroupImpl = Dali::GetImplementation(compositeGroup); + DrawableGroup::DrawableVector compositeDrawables = compositeDrawableGroupImpl.GetDrawables(); + for(auto& it : compositeDrawables) + { + PushDrawableToGroup(it, static_cast(tvgDuplicatedCompositeObject)); + } + } + + if(tvgDuplicatedObject->composite(std::move(std::unique_ptr(tvgDuplicatedCompositeObject)), static_cast(drawableImpl.GetCompositionType())) != tvg::Result::Success) + { + DALI_LOG_ERROR("Tvg composite fail [%p]\n", this); + return; + } + } + } + if(parent->push(std::move(std::unique_ptr(tvgDuplicatedObject))) != tvg::Result::Success) { DALI_LOG_ERROR("Tvg push fail [%p]\n", this); diff --git a/dali/internal/canvas-renderer/tizen/drawable-impl-tizen.cpp b/dali/internal/canvas-renderer/tizen/drawable-impl-tizen.cpp index b8baa3c..9333c75 100644 --- a/dali/internal/canvas-renderer/tizen/drawable-impl-tizen.cpp +++ b/dali/internal/canvas-renderer/tizen/drawable-impl-tizen.cpp @@ -49,7 +49,9 @@ DrawableTizen* DrawableTizen::New() DrawableTizen::DrawableTizen() : mAdded(false), mChanged(false), - mType(Drawable::Types::NONE) + mType(Drawable::Types::NONE), + mCompositionType(Drawable::CompositionType::NONE), + mCompositionDrawable() #ifdef THORVG_SUPPORT , mTvgPaint(nullptr) @@ -210,6 +212,43 @@ Rect DrawableTizen::GetBoundingBox() const #endif } +bool DrawableTizen::SetClipPath(Dali::CanvasRenderer::Drawable& clip) +{ +#ifdef THORVG_SUPPORT + if(!mTvgPaint) + { + DALI_LOG_ERROR("Drawable is null\n"); + return false; + } + + Internal::Adaptor::Drawable& drawableImpl = Dali::GetImplementation(clip); + if(drawableImpl.IsAdded()) + { + DALI_LOG_ERROR("Already used [%p][%p]\n", this, &clip); + return false; + } + + drawableImpl.SetAdded(true); + mCompositionDrawable = clip; + mCompositionType = Drawable::CompositionType::CLIP_PATH; + Drawable::SetChanged(true); + + return true; +#else + return false; +#endif +} + +Dali::CanvasRenderer::Drawable DrawableTizen::GetCompositionDrawable() const +{ + return mCompositionDrawable; +} + +Drawable::CompositionType DrawableTizen::GetCompositionType() const +{ + return mCompositionType; +} + void DrawableTizen::SetAdded(bool added) { mAdded = !!added; diff --git a/dali/internal/canvas-renderer/tizen/drawable-impl-tizen.h b/dali/internal/canvas-renderer/tizen/drawable-impl-tizen.h index 8229250..f1cd7a7 100644 --- a/dali/internal/canvas-renderer/tizen/drawable-impl-tizen.h +++ b/dali/internal/canvas-renderer/tizen/drawable-impl-tizen.h @@ -82,6 +82,20 @@ public: * @copydoc Dali::CanvasRenderer::Drawable::GetBoundingBox() */ Rect GetBoundingBox() const override; + /** + * @copydoc Dali::CanvasRenderer::Drawable::SetClipPath() + */ + bool SetClipPath(Dali::CanvasRenderer::Drawable& clip) override; + + /** + * @copydoc Internal::Adaptor::Drawable::GetCompositionDrawable() + */ + Dali::CanvasRenderer::Drawable GetCompositionDrawable() const override; + + /** + * @copydoc Internal::Adaptor::Drawable::GetCompositionType() + */ + CompositionType GetCompositionType() const override; /** * @copydoc Internal::Adaptor::Drawable::SetAdded() @@ -140,9 +154,11 @@ protected: virtual ~DrawableTizen() override; private: - bool mAdded; - bool mChanged; - Drawable::Types mType; + bool mAdded; + bool mChanged; + Drawable::Types mType; + Drawable::CompositionType mCompositionType; + Dali::CanvasRenderer::Drawable mCompositionDrawable; #ifdef THORVG_SUPPORT tvg::Paint* mTvgPaint; diff --git a/dali/internal/canvas-renderer/ubuntu/canvas-renderer-impl-ubuntu.cpp b/dali/internal/canvas-renderer/ubuntu/canvas-renderer-impl-ubuntu.cpp index 8efe447..f1d553d 100644 --- a/dali/internal/canvas-renderer/ubuntu/canvas-renderer-impl-ubuntu.cpp +++ b/dali/internal/canvas-renderer/ubuntu/canvas-renderer-impl-ubuntu.cpp @@ -264,6 +264,35 @@ void CanvasRendererUbuntu::PushDrawableToGroup(Dali::CanvasRenderer::Drawable& d } } + Dali::CanvasRenderer::Drawable compositeDrawable = drawableImpl.GetCompositionDrawable(); + if(DALI_UNLIKELY(compositeDrawable)) + { + Internal::Adaptor::Drawable& compositeDrawableImpl = Dali::GetImplementation(compositeDrawable); + tvg::Paint* tvgCompositeObject = static_cast(compositeDrawableImpl.GetObject()); + if(tvgCompositeObject) + { + tvg::Paint* tvgDuplicatedCompositeObject = tvgCompositeObject->duplicate(); + Drawable::Types type = compositeDrawableImpl.GetType(); + + if(type == Drawable::Types::DRAWABLE_GROUP) + { + Dali::CanvasRenderer::DrawableGroup& compositeGroup = static_cast(compositeDrawable); + Internal::Adaptor::DrawableGroup& compositeDrawableGroupImpl = Dali::GetImplementation(compositeGroup); + DrawableGroup::DrawableVector compositeDrawables = compositeDrawableGroupImpl.GetDrawables(); + for(auto& it : compositeDrawables) + { + PushDrawableToGroup(it, static_cast(tvgDuplicatedCompositeObject)); + } + } + + if(tvgDuplicatedObject->composite(std::move(std::unique_ptr(tvgDuplicatedCompositeObject)), static_cast(drawableImpl.GetCompositionType())) != tvg::Result::Success) + { + DALI_LOG_ERROR("Tvg composite fail [%p]\n", this); + return; + } + } + } + if(group->push(std::move(std::unique_ptr(tvgDuplicatedObject))) != tvg::Result::Success) { DALI_LOG_ERROR("Tvg push fail [%p]\n", this); diff --git a/dali/internal/canvas-renderer/ubuntu/drawable-impl-ubuntu.cpp b/dali/internal/canvas-renderer/ubuntu/drawable-impl-ubuntu.cpp index 36a84aa..f4cb431 100644 --- a/dali/internal/canvas-renderer/ubuntu/drawable-impl-ubuntu.cpp +++ b/dali/internal/canvas-renderer/ubuntu/drawable-impl-ubuntu.cpp @@ -49,7 +49,9 @@ DrawableUbuntu* DrawableUbuntu::New() DrawableUbuntu::DrawableUbuntu() : mAdded(false), mChanged(false), - mType(Drawable::Types::NONE) + mType(Drawable::Types::NONE), + mCompositionType(Drawable::CompositionType::NONE), + mCompositionDrawable() #ifdef THORVG_SUPPORT , mTvgPaint(nullptr) @@ -210,6 +212,43 @@ Rect DrawableUbuntu::GetBoundingBox() const #endif } +bool DrawableUbuntu::SetClipPath(Dali::CanvasRenderer::Drawable& clip) +{ +#ifdef THORVG_SUPPORT + if(!mTvgPaint) + { + DALI_LOG_ERROR("Drawable is null\n"); + return false; + } + + Internal::Adaptor::Drawable& drawableImpl = Dali::GetImplementation(clip); + if(drawableImpl.IsAdded()) + { + DALI_LOG_ERROR("Already used [%p][%p]\n", this, &clip); + return false; + } + + drawableImpl.SetAdded(true); + mCompositionDrawable = clip; + mCompositionType = Drawable::CompositionType::CLIP_PATH; + Drawable::SetChanged(true); + + return true; +#else + return false; +#endif +} + +Dali::CanvasRenderer::Drawable DrawableUbuntu::GetCompositionDrawable() const +{ + return mCompositionDrawable; +} + +Drawable::CompositionType DrawableUbuntu::GetCompositionType() const +{ + return mCompositionType; +} + void DrawableUbuntu::SetAdded(bool added) { mAdded = !!added; diff --git a/dali/internal/canvas-renderer/ubuntu/drawable-impl-ubuntu.h b/dali/internal/canvas-renderer/ubuntu/drawable-impl-ubuntu.h index c91a5d6..45bdc3d 100644 --- a/dali/internal/canvas-renderer/ubuntu/drawable-impl-ubuntu.h +++ b/dali/internal/canvas-renderer/ubuntu/drawable-impl-ubuntu.h @@ -84,6 +84,21 @@ public: Rect GetBoundingBox() const override; /** + * @copydoc Dali::CanvasRenderer::Drawable::SetClipPath() + */ + bool SetClipPath(Dali::CanvasRenderer::Drawable& clip) override; + + /** + * @copydoc Internal::Adaptor::Drawable::GetCompositionDrawable() + */ + Dali::CanvasRenderer::Drawable GetCompositionDrawable() const override; + + /** + * @copydoc Internal::Adaptor::Drawable::GetCompositionType() + */ + CompositionType GetCompositionType() const override; + + /** * @copydoc Internal::Adaptor::Drawable::SetAdded() */ void SetAdded(bool added) override; @@ -140,9 +155,11 @@ protected: virtual ~DrawableUbuntu() override; private: - bool mAdded; - bool mChanged; - Drawable::Types mType; + bool mAdded; + bool mChanged; + Drawable::Types mType; + Drawable::CompositionType mCompositionType; + Dali::CanvasRenderer::Drawable mCompositionDrawable; #ifdef THORVG_SUPPORT tvg::Paint* mTvgPaint; -- 2.7.4