api: revise the clip() apis.

- Paint explicity allows a shape as a clipper
- Added clipper getter apis

API Updates
 + Shape* Paint::clip()
 * Result Paint::clip(Paint* clipper) -> Result Paint::clip(Shape* clipper)

CAPI Updates
 + Tvg_Paint* tvg_paint_get_clip(const Tvg_Paint* paint)
 * Tvg_Result tvg_paint_clip(Tvg_Paint* paint, Tvg_Paint* clipper)
   -> Tvg_Result tvg_paint_set_clip(Tvg_Paint* paint, Tvg_Paint* clipper);

Please note that clipper type can be changed again to tvg::Path
in the upcoming update.
This commit is contained in:
Hermet Park 2025-05-29 13:10:22 +09:00
parent e2909dd6a4
commit 2eb2b83bb0
6 changed files with 55 additions and 16 deletions

View file

@ -65,6 +65,7 @@ namespace tvg
class RenderMethod; class RenderMethod;
class Animation; class Animation;
class Shape;
/** /**
* @defgroup ThorVG ThorVG * @defgroup ThorVG ThorVG
@ -396,13 +397,13 @@ public:
* *
* @param[in] clipper The shape object as the clipper. * @param[in] clipper The shape object as the clipper.
* *
* @retval Result::NonSupport If the @p clipper type is not Shape. * @retval Result::InsufficientCondition if the @p clipper has already belonged to another paint.
* @retval Result::InsufficientCondition if the target has already belonged to another paint. *
* @see Paint::clip()
* *
* @note @p clipper only supports the Shape type.
* @since 1.0 * @since 1.0
*/ */
Result clip(Paint* clipper) noexcept; Result clip(Shape* clipper) noexcept;
/** /**
* @brief Sets the blending method for the paint object. * @brief Sets the blending method for the paint object.
@ -478,6 +479,19 @@ public:
*/ */
MaskMethod mask(const Paint** target) const noexcept; MaskMethod mask(const Paint** target) const noexcept;
/**
* @brief Get the clipper shape of the paint object.
*
* This function returns the clipper that has been previously set to this paint object.
*
* @return The shape object used as the clipper, or @c nullptr if no clipper is set.
*
* @see Paint::clip(Shape* clipper)
*
* @since 1.0
*/
Shape* clip() const noexcept;
/** /**
* @brief Increment the reference count for the Paint instance. * @brief Increment the reference count for the Paint instance.
* *

View file

@ -972,7 +972,7 @@ TVG_API Tvg_Result tvg_paint_set_mask_method(Tvg_Paint* paint, Tvg_Paint* target
TVG_API Tvg_Result tvg_paint_get_mask_method(const Tvg_Paint* paint, const Tvg_Paint** target, Tvg_Mask_Method* method); TVG_API Tvg_Result tvg_paint_get_mask_method(const Tvg_Paint* paint, const Tvg_Paint** target, Tvg_Mask_Method* method);
/*! /**
* @brief Clip the drawing region of the paint object. * @brief Clip the drawing region of the paint object.
* *
* This function restricts the drawing area of the paint object to the specified shape's paths. * This function restricts the drawing area of the paint object to the specified shape's paths.
@ -985,10 +985,24 @@ TVG_API Tvg_Result tvg_paint_get_mask_method(const Tvg_Paint* paint, const Tvg_P
* @retval TVG_RESULT_INSUFFICIENT_CONDITION if the target has already belonged to another paint. * @retval TVG_RESULT_INSUFFICIENT_CONDITION if the target has already belonged to another paint.
* @retval TVG_RESULT_NOT_SUPPORTED If the @p clipper type is not Shape. * @retval TVG_RESULT_NOT_SUPPORTED If the @p clipper type is not Shape.
* *
* @see tvg_paint_get_clip()
* @since 1.0 * @since 1.0
*/ */
TVG_API Tvg_Result tvg_paint_clip(Tvg_Paint* paint, Tvg_Paint* clipper); TVG_API Tvg_Result tvg_paint_set_clip(Tvg_Paint* paint, Tvg_Paint* clipper);
/**
* @brief Get the clipper shape of the paint object.
*
* This function returns the clipper that has been previously set to this paint object.
*
* @return The shape object used as the clipper, or @c nullptr if no clipper is set.
*
* @see tvg_paint_set_clip()
*
* @since 1.0
*/
TVG_API Tvg_Paint* tvg_paint_get_clip(const Tvg_Paint* paint);
/** /**
* @brief Retrieves the parent paint object. * @brief Retrieves the parent paint object.

View file

@ -304,10 +304,17 @@ TVG_API Tvg_Result tvg_paint_get_type(const Tvg_Paint* paint, Tvg_Type* type)
} }
TVG_API Tvg_Result tvg_paint_clip(Tvg_Paint* paint, Tvg_Paint* clipper) TVG_API Tvg_Result tvg_paint_set_clip(Tvg_Paint* paint, Tvg_Paint* clipper)
{ {
if (!paint) return TVG_RESULT_INVALID_ARGUMENT; if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
return (Tvg_Result) reinterpret_cast<Paint*>(paint)->clip((Paint*)(clipper)); return (Tvg_Result) reinterpret_cast<Paint*>(paint)->clip((Shape*)(clipper));
}
TVG_API Tvg_Paint* tvg_paint_get_clip(const Tvg_Paint* paint)
{
if (!paint) return nullptr;
return (Tvg_Paint*) reinterpret_cast<const Paint*>(paint)->clip();
} }

View file

@ -168,7 +168,7 @@ Paint* Paint::Impl::duplicate(Paint* ret)
ret->pImpl->opacity = opacity; ret->pImpl->opacity = opacity;
if (maskData) ret->mask(maskData->target->duplicate(), maskData->method); if (maskData) ret->mask(maskData->target->duplicate(), maskData->method);
if (clipper) ret->clip(clipper->duplicate()); if (clipper) ret->clip(static_cast<Shape*>(clipper->duplicate()));
return ret; return ret;
} }
@ -376,16 +376,18 @@ Paint* Paint::duplicate() const noexcept
} }
Result Paint::clip(Paint* clipper) noexcept Result Paint::clip(Shape* clipper) noexcept
{ {
if (clipper && clipper->type() != Type::Shape) {
TVGERR("RENDERER", "Clipping only supports the Shape!");
return Result::NonSupport;
}
return pImpl->clip(clipper); return pImpl->clip(clipper);
} }
Shape* Paint::clip() const noexcept
{
return pImpl->clipper;
}
Result Paint::mask(Paint* target, MaskMethod method) noexcept Result Paint::mask(Paint* target, MaskMethod method) noexcept
{ {
return pImpl->mask(target, method); return pImpl->mask(target, method);

View file

@ -54,7 +54,7 @@ namespace tvg
Paint* paint = nullptr; Paint* paint = nullptr;
Paint* parent = nullptr; Paint* parent = nullptr;
Mask* maskData = nullptr; Mask* maskData = nullptr;
Paint* clipper = nullptr; Shape* clipper = nullptr;
RenderMethod* renderer = nullptr; RenderMethod* renderer = nullptr;
RenderData rd = nullptr; RenderData rd = nullptr;
@ -163,7 +163,7 @@ namespace tvg
return tm; return tm;
} }
Result clip(Paint* clp) Result clip(Shape* clp)
{ {
if (clp && PAINT(clp)->parent) return Result::InsufficientCondition; if (clp && PAINT(clp)->parent) return Result::InsufficientCondition;
if (clipper) PAINT(clipper)->unref(clipper != clp); if (clipper) PAINT(clipper)->unref(clipper != clp);

View file

@ -223,7 +223,9 @@ TEST_CASE("Composition", "[tvgPaint]")
//Clipping //Clipping
auto comp = Shape::gen(); auto comp = Shape::gen();
REQUIRE(shape->clip() == nullptr);
REQUIRE(shape->clip(comp) == Result::Success); REQUIRE(shape->clip(comp) == Result::Success);
REQUIRE(shape->clip() == comp);
//AlphaMask //AlphaMask
comp = Shape::gen(); comp = Shape::gen();