diff --git a/examples/Blending.cpp b/examples/Blending.cpp index 9629f8fa..95b678fa 100644 --- a/examples/Blending.cpp +++ b/examples/Blending.cpp @@ -94,7 +94,7 @@ struct UserExample : tvgexam::Example //RadialGradient auto fill2 = tvg::RadialGradient::gen(); - fill2->radial(300, 800, 150); + fill2->radial(300, 800, 150, 300, 800, 0); fill2->colorStops(colorStops, 2); shape6->fill(std::move(fill2)); diff --git a/examples/Capi.cpp b/examples/Capi.cpp index 650d6f04..c860a6ad 100644 --- a/examples/Capi.cpp +++ b/examples/Capi.cpp @@ -103,7 +103,7 @@ void contents() //Prepare a radial gradient for the fill Tvg_Gradient* grad2 = tvg_radial_gradient_new(); - tvg_radial_gradient_set(grad2, 600.0f, 180.0f, 50.0f); + tvg_radial_gradient_set(grad2, 600.0f, 180.0f, 50.0f, 640.0f, 180.0f, 0.0f); Tvg_Color_Stop color_stops2[3] = { {0.0f, 255, 0, 255, 255}, @@ -121,11 +121,11 @@ void contents() const Tvg_Color_Stop* color_stops2_get; tvg_gradient_get_color_stops(grad2, &color_stops2_get, &cnt); - float cx, cy, radius; - tvg_radial_gradient_get(grad2, &cx, &cy, &radius); + float cx, cy, r, fx, fy, fr; + tvg_radial_gradient_get(grad2, &cx, &cy, &r, &fx, &fy, &fr); Tvg_Gradient* grad2_stroke = tvg_radial_gradient_new(); - tvg_radial_gradient_set(grad2_stroke, cx, cy, radius); + tvg_radial_gradient_set(grad2_stroke, cx, cy, r, fx, fy, fr); tvg_gradient_set_color_stops(grad2_stroke, color_stops2_get, cnt); tvg_gradient_set_spread(grad2_stroke, TVG_STROKE_FILL_REPEAT); @@ -261,7 +261,7 @@ void contents() } else { //Radial gradient Tvg_Gradient* grad = tvg_radial_gradient_new(); - tvg_radial_gradient_set(grad, 200.0f, 200.0f, 20.0f); + tvg_radial_gradient_set(grad, 200.0f, 200.0f, 20.0f, 200.0f, 200.0f, 0.0f); Tvg_Color_Stop color_stops[2] = { {0.0f, 255, 0, 255, 255}, diff --git a/examples/FillSpread.cpp b/examples/FillSpread.cpp index 738c3b5b..18ff7297 100644 --- a/examples/FillSpread.cpp +++ b/examples/FillSpread.cpp @@ -49,7 +49,7 @@ struct UserExample : tvgexam::Example shape1->appendRect(x1, y1, 2.0f * r, 2.0f * r); auto fill1 = tvg::RadialGradient::gen(); - fill1->radial(x1 + r, y1 + r, 40.0f); + fill1->radial(x1 + r, y1 + r, 40.0f, x1 + r, y1 + r, 0.0f); fill1->colorStops(colorStops, colorCnt); fill1->spread(tvg::FillSpread::Pad); shape1->fill(std::move(fill1)); @@ -62,7 +62,7 @@ struct UserExample : tvgexam::Example shape2->appendRect(x1, y1, 2.0f * r, 2.0f * r); auto fill2 = tvg::RadialGradient::gen(); - fill2->radial(x1 + r, y1 + r, 40.0f); + fill2->radial(x1 + r, y1 + r, 40.0f, x1 + r, y1 + r, 0.0f); fill2->colorStops(colorStops, colorCnt); fill2->spread(tvg::FillSpread::Reflect); shape2->fill(std::move(fill2)); @@ -75,7 +75,7 @@ struct UserExample : tvgexam::Example shape3->appendRect(x1, y1, 2.0f * r, 2.0f * r); auto fill3 = tvg::RadialGradient::gen(); - fill3->radial(x1 + r, y1 + r, 40.0f); + fill3->radial(x1 + r, y1 + r, 40.0f, x1 + r, y1 + r, 0.0f); fill3->colorStops(colorStops, colorCnt); fill3->spread(tvg::FillSpread::Repeat); shape3->fill(std::move(fill3)); diff --git a/examples/GradientStroke.cpp b/examples/GradientStroke.cpp index 1958c543..0f90599d 100644 --- a/examples/GradientStroke.cpp +++ b/examples/GradientStroke.cpp @@ -85,7 +85,7 @@ struct UserExample : tvgexam::Example shape2->strokeWidth(80); auto fillStroke2 = tvg::RadialGradient::gen(); - fillStroke2->radial(600, 175, 100); + fillStroke2->radial(600, 175, 100, 600, 175, 0); fillStroke2->colorStops(colorStops2, 2); shape2->strokeFill(std::move(fillStroke2)); diff --git a/examples/GradientTransform.cpp b/examples/GradientTransform.cpp index 78778733..754159c0 100644 --- a/examples/GradientTransform.cpp +++ b/examples/GradientTransform.cpp @@ -98,7 +98,7 @@ struct UserExample : tvgexam::Example //RadialGradient auto fill3 = tvg::RadialGradient::gen(); - fill3->radial(175, 150, 75); + fill3->radial(175, 150, 75, 175, 150, 0); //Gradient Color Stops tvg::Fill::ColorStop colorStops3[4]; diff --git a/examples/RadialGradient.cpp b/examples/RadialGradient.cpp index 7784edf1..d5cb26ab 100644 --- a/examples/RadialGradient.cpp +++ b/examples/RadialGradient.cpp @@ -38,7 +38,7 @@ struct UserExample : tvgexam::Example //RadialGradient auto fill = tvg::RadialGradient::gen(); - fill->radial(200, 200, 200); + fill->radial(200, 200, 200, 200, 200, 0); //cx, cy, r, fx, fy, fr //Gradient Color Stops tvg::Fill::ColorStop colorStops[2]; @@ -56,7 +56,7 @@ struct UserExample : tvgexam::Example //RadialGradient auto fill2 = tvg::RadialGradient::gen(); - fill2->radial(400, 400, 200); + fill2->radial(400, 400, 200, 400, 400, 0); //cx, cy, r, fx, fy, fr //Gradient Color Stops tvg::Fill::ColorStop colorStops2[3]; @@ -75,7 +75,7 @@ struct UserExample : tvgexam::Example //RadialGradient auto fill3 = tvg::RadialGradient::gen(); - fill3->radial(600, 600, 150); + fill3->radial(600, 600, 150, 700, 600, 20); //cx, cy, r, fx, fy, fr //Gradient Color Stops tvg::Fill::ColorStop colorStops3[4]; diff --git a/examples/Text.cpp b/examples/Text.cpp index 1eb8688f..a2e8d4fd 100644 --- a/examples/Text.cpp +++ b/examples/Text.cpp @@ -154,7 +154,7 @@ struct UserExample : tvgexam::Example //LinearGradient auto fill2 = tvg::RadialGradient::gen(); - fill2->radial(x + w2 * 0.5f, y + h2 * 0.5f, w2 * 0.5f); + fill2->radial(x + w2 * 0.5f, y + h2 * 0.5f, w2 * 0.5f, x + w2 * 0.5f, y + h2 * 0.5f, 0.0f); //Gradient Color Stops tvg::Fill::ColorStop colorStops2[3]; diff --git a/inc/thorvg.h b/inc/thorvg.h index 83c60bd3..435cb2e0 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -767,31 +767,43 @@ public: ~RadialGradient(); /** - * @brief Sets the radial gradient bounds. + * @brief Sets the radial gradient attributes. * - * The radial gradient bounds are defined as a circle centered in a given point (@p cx, @p cy) of a given radius. + * The radial gradient is defined by the end circle with a center (@p cx, @p cy) and a radius @p r and + * the start circle with a center/focal point (@p fx, @p fy) and a radius @p fr. + * The gradient will be rendered such that the gradient stop at an offset of 100% aligns with the edge of the end circle + * and the stop at an offset of 0% aligns with the edge of the start circle. * - * @param[in] cx The horizontal coordinate of the center of the bounding circle. - * @param[in] cy The vertical coordinate of the center of the bounding circle. - * @param[in] radius The radius of the bounding circle. + * @param[in] cx The horizontal coordinate of the center of the end circle. + * @param[in] cy The vertical coordinate of the center of the end circle. + * @param[in] r The radius of the end circle. + * @param[in] fx The horizontal coordinate of the center of the start circle. + * @param[in] fy The vertical coordinate of the center of the start circle. + * @param[in] fr The radius of the start circle. * - * @retval Result::InvalidArguments in case the @p radius value is zero or less. + * @retval Result::InvalidArguments in case the radius @p r or @p fr value is negative. * - * @note In case the @p radius is zero, an object is filled with a single color using the last color specified in the colorStops(). + * @note In case the radius @p r is zero, an object is filled with a single color using the last color specified in the colorStops(). + * @note By manipulating the position and size of the focal point, a wide range of visual effects can be achieved, such as directing + * the gradient focus towards a specific edge or enhancing the depth and complexity of shading patterns. + * If a focal effect is not desired, simply align the focal point (@p fx and @p fy) with the center of the end circle (@p cx and @p cy) + * and set the radius (@p fr) to zero. This will result in a uniform gradient without any focal variations. */ - Result radial(float cx, float cy, float radius) noexcept; + Result radial(float cx, float cy, float r, float fx, float fy, float fr) noexcept; /** - * @brief Gets the radial gradient bounds. + * @brief Gets the radial gradient attributes. * - * The radial gradient bounds are defined as a circle centered in a given point (@p cx, @p cy) of a given radius. - * - * @param[out] cx The horizontal coordinate of the center of the bounding circle. - * @param[out] cy The vertical coordinate of the center of the bounding circle. - * @param[out] radius The radius of the bounding circle. + * @param[out] cx The horizontal coordinate of the center of the end circle. + * @param[out] cy The vertical coordinate of the center of the end circle. + * @param[out] r The radius of the end circle. + * @param[out] fx The horizontal coordinate of the center of the start circle. + * @param[out] fy The vertical coordinate of the center of the start circle. + * @param[out] fr The radius of the start circle. * + * @see RadialGradient::radial() */ - Result radial(float* cx, float* cy, float* radius) const noexcept; + Result radial(float* cx, float* cy, float* r, float* fx = nullptr, float* fy = nullptr, float* fr = nullptr) const noexcept; /** * @brief Creates a new RadialGradient object. diff --git a/src/bindings/capi/thorvg_capi.h b/src/bindings/capi/thorvg_capi.h index 1c8643d2..dac71db9 100644 --- a/src/bindings/capi/thorvg_capi.h +++ b/src/bindings/capi/thorvg_capi.h @@ -1729,36 +1729,52 @@ TVG_API Tvg_Result tvg_linear_gradient_get(Tvg_Gradient* grad, float* x1, float* /*! -* \brief Sets the radial gradient bounds. +* \brief Sets the radial gradient attributes. * -* The radial gradient bounds are defined as a circle centered in a given point (@p cx, @p cy) of a given radius. +* The radial gradient is defined by the end circle with a center (@p cx, @p cy) and a radius @p r and +* the start circle with a center/focal point (@p fx, @p fy) and a radius @p fr. +* The gradient will be rendered such that the gradient stop at an offset of 100% aligns with the edge of the end circle +* and the stop at an offset of 0% aligns with the edge of the start circle. * * \param[in] grad The Tvg_Gradient object of which bounds are to be set. -* \param[in] cx The horizontal coordinate of the center of the bounding circle. -* \param[in] cy The vertical coordinate of the center of the bounding circle. -* \param[in] radius The radius of the bounding circle. +* \param[in] cx The horizontal coordinate of the center of the end circle. +* \param[in] cy The vertical coordinate of the center of the end circle. +* \param[in] r The radius of the end circle. +* \param[in] fx The horizontal coordinate of the center of the start circle. +* \param[in] fy The vertical coordinate of the center of the start circle. +* \param[in] fr The radius of the start circle. * * \return Tvg_Result enumeration. -* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Gradient pointer or the @p radius value less than zero. +* \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Gradient pointer or the radius @p r or @p fr value is negative. +* +* \note In case the radius @p r is zero, an object is filled with a single color using the last color specified in the specified in the tvg_gradient_set_color_stops(). +* \note By manipulating the position and size of the focal point, a wide range of visual effects can be achieved, such as directing +* the gradient focus towards a specific edge or enhancing the depth and complexity of shading patterns. +* If a focal effect is not desired, simply align the focal point (@p fx and @p fy) with the center of the end circle (@p cx and @p cy) +* and set the radius (@p fr) to zero. This will result in a uniform gradient without any focal variations. * -* \note In case the @p radius is zero, an object is filled with a single color using the last color specified in the specified in the tvg_gradient_set_color_stops(). * \see tvg_gradient_set_color_stops() */ -TVG_API Tvg_Result tvg_radial_gradient_set(Tvg_Gradient* grad, float cx, float cy, float radius); +TVG_API Tvg_Result tvg_radial_gradient_set(Tvg_Gradient* grad, float cx, float cy, float r, float fx, float fy, float fr); /*! -* \brief The function gets radial gradient center point ant radius +* \brief The function gets radial gradient attributes. * -* \param[in] grad The Tvg_Gradient object of which bounds are to be set. -* \param[out] cx The horizontal coordinate of the center of the bounding circle. -* \param[out] cy The vertical coordinate of the center of the bounding circle. -* \param[out] radius The radius of the bounding circle. +* \param[in] grad The Tvg_Gradient object of which to get the gradient attributes. +* \param[out] cx The horizontal coordinate of the center of the end circle. +* \param[out] cy The vertical coordinate of the center of the end circle. +* \param[out] r The radius of the end circle. +* \param[out] fx The horizontal coordinate of the center of the start circle. +* \param[out] fy The vertical coordinate of the center of the start circle. +* \param[out] fr The radius of the start circle. * * \return Tvg_Result enumeration. * \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Gradient pointer. +* +* \see tvg_radial_gradient_set() */ -TVG_API Tvg_Result tvg_radial_gradient_get(Tvg_Gradient* grad, float* cx, float* cy, float* radius); +TVG_API Tvg_Result tvg_radial_gradient_get(Tvg_Gradient* grad, float* cx, float* cy, float* r, float* fx, float* fy, float* fr); /*! diff --git a/src/bindings/capi/tvgCapi.cpp b/src/bindings/capi/tvgCapi.cpp index 20e3408b..04433964 100644 --- a/src/bindings/capi/tvgCapi.cpp +++ b/src/bindings/capi/tvgCapi.cpp @@ -607,17 +607,17 @@ TVG_API Tvg_Result tvg_linear_gradient_get(Tvg_Gradient* grad, float* x1, float* } -TVG_API Tvg_Result tvg_radial_gradient_set(Tvg_Gradient* grad, float cx, float cy, float radius) +TVG_API Tvg_Result tvg_radial_gradient_set(Tvg_Gradient* grad, float cx, float cy, float r, float fx, float fy, float fr) { if (!grad) return TVG_RESULT_INVALID_ARGUMENT; - return (Tvg_Result) reinterpret_cast(grad)->radial(cx, cy, radius); + return (Tvg_Result) reinterpret_cast(grad)->radial(cx, cy, r, fx, fy, fr); } -TVG_API Tvg_Result tvg_radial_gradient_get(Tvg_Gradient* grad, float* cx, float* cy, float* radius) +TVG_API Tvg_Result tvg_radial_gradient_get(Tvg_Gradient* grad, float* cx, float* cy, float* r, float* fx, float* fy, float* fr) { if (!grad) return TVG_RESULT_INVALID_ARGUMENT; - return (Tvg_Result) reinterpret_cast(grad)->radial(cx, cy, radius); + return (Tvg_Result) reinterpret_cast(grad)->radial(cx, cy, r, fx, fy, fr); } diff --git a/src/loaders/lottie/tvgLottieModel.cpp b/src/loaders/lottie/tvgLottieModel.cpp index 782a0314..21708c5e 100644 --- a/src/loaders/lottie/tvgLottieModel.cpp +++ b/src/loaders/lottie/tvgLottieModel.cpp @@ -294,7 +294,7 @@ Fill* LottieGradient::fill(float frameNo, LottieExpressions* exps) auto progress = this->height(frameNo, exps) * 0.01f; if (tvg::zero(progress)) { - P(static_cast(fill))->radial(s.x, s.y, r, s.x, s.y, 0.0f); + static_cast(fill)->radial(s.x, s.y, r, s.x, s.y, 0.0f); } else { if (tvg::equal(progress, 1.0f)) progress = 0.99f; auto startAngle = rad2deg(tvg::atan2(e.y - s.y, e.x - s.x)); @@ -302,7 +302,7 @@ Fill* LottieGradient::fill(float frameNo, LottieExpressions* exps) auto fx = s.x + cos(angle) * progress * r; auto fy = s.y + sin(angle) * progress * r; // Lottie doesn't have any focal radius concept - P(static_cast(fill))->radial(s.x, s.y, r, fx, fy, 0.0f); + static_cast(fill)->radial(s.x, s.y, r, fx, fy, 0.0f); } } diff --git a/src/renderer/tvgFill.cpp b/src/renderer/tvgFill.cpp index fb7b3579..394f5241 100644 --- a/src/renderer/tvgFill.cpp +++ b/src/renderer/tvgFill.cpp @@ -163,17 +163,20 @@ RadialGradient::~RadialGradient() } -Result RadialGradient::radial(float cx, float cy, float r) noexcept +Result RadialGradient::radial(float cx, float cy, float r, float fx, float fy, float fr) noexcept { - return pImpl->radial(cx, cy, r, cx, cy, 0.0f); + return pImpl->radial(cx, cy, r, fx, fy, fr); } -Result RadialGradient::radial(float* cx, float* cy, float* r) const noexcept +Result RadialGradient::radial(float* cx, float* cy, float* r, float* fx, float* fy, float* fr) const noexcept { if (cx) *cx = pImpl->cx; if (cy) *cy = pImpl->cy; if (r) *r = pImpl->r; + if (fx) *fx = pImpl->fx; + if (fy) *fy = pImpl->fy; + if (fr) *fr = pImpl->fr; return Result::Success; } diff --git a/test/capi/capiRadialGradient.cpp b/test/capi/capiRadialGradient.cpp index bc91870b..c1d2e164 100644 --- a/test/capi/capiRadialGradient.cpp +++ b/test/capi/capiRadialGradient.cpp @@ -41,13 +41,16 @@ TEST_CASE("Set gradient center point and radius", "[capiRadialGradient]") { Tvg_Gradient *gradient = tvg_radial_gradient_new(); REQUIRE(gradient); - REQUIRE(tvg_radial_gradient_set(gradient, 10.0, 15.0, 30.0) == TVG_RESULT_SUCCESS); + REQUIRE(tvg_radial_gradient_set(gradient, 10.0, 15.0, 30.0, 11.0, 16.0, 1.0) == TVG_RESULT_SUCCESS); - float cx, cy, radius; - REQUIRE(tvg_radial_gradient_get(gradient, &cx, &cy, &radius) == TVG_RESULT_SUCCESS); + float cx, cy, r, fx, fy, fr; + REQUIRE(tvg_radial_gradient_get(gradient, &cx, &cy, &r, &fx, &fy, &fr) == TVG_RESULT_SUCCESS); REQUIRE(cx == Approx(10.0).margin(0.000001)); REQUIRE(cy == Approx(15.0).margin(0.000001)); - REQUIRE(radius == Approx(30.0).margin(0.000001)); + REQUIRE(r == Approx(30.0).margin(0.000001)); + REQUIRE(fx == Approx(11.0).margin(0.000001)); + REQUIRE(fy == Approx(16.0).margin(0.000001)); + REQUIRE(fr == Approx(1.0).margin(0.000001)); REQUIRE(tvg_gradient_del(gradient) == TVG_RESULT_SUCCESS); } @@ -194,7 +197,7 @@ TEST_CASE("Stroke Radial Gradient", "[capiRadialGradient]") Tvg_Gradient *gradient = tvg_radial_gradient_new(); REQUIRE(gradient); - REQUIRE(tvg_radial_gradient_set(gradient, 10.0, 15.0, 30.0) == TVG_RESULT_SUCCESS); + REQUIRE(tvg_radial_gradient_set(gradient, 10.0, 15.0, 30.0, 11.0, 16.0, 0.0) == TVG_RESULT_SUCCESS); Tvg_Color_Stop color_stops[2] = { {0.0, 0, 0, 0, 255}, @@ -218,11 +221,14 @@ TEST_CASE("Stroke Radial Gradient", "[capiRadialGradient]") REQUIRE(color_stops_ret); REQUIRE(color_stops_count_ret == 2); - float cx, cy, radius; - REQUIRE(tvg_radial_gradient_get(gradient_ret, &cx, &cy, &radius) == TVG_RESULT_SUCCESS); + float cx, cy, r, fx, fy, fr; + REQUIRE(tvg_radial_gradient_get(gradient_ret, &cx, &cy, &r, &fx, &fy, &fr) == TVG_RESULT_SUCCESS); REQUIRE(cx == Approx(10.0).margin(0.000001)); REQUIRE(cy == Approx(15.0).margin(0.000001)); - REQUIRE(radius == Approx(30.0).margin(0.000001)); + REQUIRE(r == Approx(30.0).margin(0.000001)); + REQUIRE(fx == Approx(11.0).margin(0.000001)); + REQUIRE(fy == Approx(16.0).margin(0.000001)); + REQUIRE(fr == Approx(0.0).margin(0.000001)); REQUIRE(tvg_paint_del(shape) == TVG_RESULT_SUCCESS); } diff --git a/test/capi/capiText.cpp b/test/capi/capiText.cpp index 0cbd19cc..7801face 100644 --- a/test/capi/capiText.cpp +++ b/test/capi/capiText.cpp @@ -145,7 +145,7 @@ TEST_CASE("Set gradient text fill", "[capiText]") Tvg_Gradient *gradientRad = tvg_radial_gradient_new(); REQUIRE(gradientRad); - REQUIRE(tvg_radial_gradient_set(gradientRad, 10.0, 15.0, 30.0) == TVG_RESULT_SUCCESS); + REQUIRE(tvg_radial_gradient_set(gradientRad, 10.0, 15.0, 30.0, 10.0, 15.0, 0.0) == TVG_RESULT_SUCCESS); Tvg_Gradient *gradientLin = tvg_linear_gradient_new(); REQUIRE(gradientLin); diff --git a/test/testFill.cpp b/test/testFill.cpp index 8f5b099b..90c4e8b0 100644 --- a/test/testFill.cpp +++ b/test/testFill.cpp @@ -151,24 +151,31 @@ TEST_CASE("Radial Filling", "[tvgFill]") auto fill = RadialGradient::gen(); REQUIRE(fill); - float cx, cy, radius; + float cx, cy, r, fx, fy, fr; - REQUIRE(fill->radial(0, 0, -1) == Result::InvalidArguments); + REQUIRE(fill->radial(0, 0, -1, 0, 0, 0) == Result::InvalidArguments); + REQUIRE(fill->radial(0, 0, 0, 0, 0, -1) == Result::InvalidArguments); REQUIRE(fill->radial(nullptr, nullptr, nullptr) == Result::Success); - REQUIRE(fill->radial(100, 120, 50) == Result::Success); + REQUIRE(fill->radial(100, 120, 50, 10, 20, 5) == Result::Success); - REQUIRE(fill->radial(&cx, nullptr, &radius) == Result::Success); + REQUIRE(fill->radial(&cx, nullptr, &r) == Result::Success); REQUIRE(cx == 100.0f); - REQUIRE(radius == 50.0f); + REQUIRE(r == 50.0f); - REQUIRE(fill->radial(nullptr, &cy, nullptr) == Result::Success); + REQUIRE(fill->radial(nullptr, &cy, nullptr, &fx, &fy, &fr) == Result::Success); REQUIRE(cy == 120); + REQUIRE(fx == 10); + REQUIRE(fy == 20); + REQUIRE(fr == 5); - REQUIRE(fill->radial(0, 0, 0) == Result::Success); - REQUIRE(fill->radial(&cx, &cy, &radius) == Result::Success); + REQUIRE(fill->radial(0, 0, 0, 0, 0, 0) == Result::Success); + REQUIRE(fill->radial(&cx, &cy, &r, &fx, &fy, &fr) == Result::Success); REQUIRE(cx == 0.0f); REQUIRE(cy == 0.0f); - REQUIRE(radius == 0.0f); + REQUIRE(r == 0.0f); + REQUIRE(fx == 0.0f); + REQUIRE(fy == 0.0f); + REQUIRE(fr == 0.0f); } TEST_CASE("Linear Filling Duplication", "[tvgFill]") @@ -241,7 +248,7 @@ TEST_CASE("Radial Filling Duplication", "[tvgFill]") REQUIRE(fill->colorStops(cs, 4) == Result::Success); REQUIRE(fill->spread(FillSpread::Reflect) == Result::Success); - REQUIRE(fill->radial(100.0f, 120.0f, 50.0f) == Result::Success); + REQUIRE(fill->radial(100.0f, 120.0f, 50.0f, 10.0f, 20.0f, 5.0f) == Result::Success); auto m = Matrix{1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, -7.7f, -8.8f, -9.9f}; REQUIRE(fill->transform(m) == Result::Success); @@ -252,11 +259,14 @@ TEST_CASE("Radial Filling Duplication", "[tvgFill]") REQUIRE(dup->spread() == FillSpread::Reflect); - float cx, cy, radius; - REQUIRE(dup->radial(&cx, &cy, &radius) == Result::Success); + float cx, cy, r, fx, fy, fr; + REQUIRE(dup->radial(&cx, &cy, &r, &fx, &fy, &fr) == Result::Success); REQUIRE(cx == 100.0f); REQUIRE(cy == 120.0f); - REQUIRE(radius == 50.0f); + REQUIRE(r == 50.0f); + REQUIRE(fx == 10.0f); + REQUIRE(fy == 20.0f); + REQUIRE(fr == 5.0f); const Fill::ColorStop* cs2 = nullptr; REQUIRE(fill->colorStops(&cs2) == 4); diff --git a/test/testSwEngine.cpp b/test/testSwEngine.cpp index 8f64bd4f..5e069fff 100644 --- a/test/testSwEngine.cpp +++ b/test/testSwEngine.cpp @@ -521,7 +521,7 @@ TEST_CASE("Filling Draw", "[tvgSwEngine]") REQUIRE(linearFill->spread(FillSpread::Repeat) == Result::Success); REQUIRE(radialFill->spread(FillSpread::Pad) == Result::Success); REQUIRE(linearFill->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success); - REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); //Filled Shapes auto shape3 = tvg::Shape::gen(); @@ -570,7 +570,7 @@ TEST_CASE("Filling Opaque Draw", "[tvgSwEngine]") REQUIRE(linearFill->colorStops(cs, 4) == Result::Success); REQUIRE(radialFill->colorStops(cs, 4) == Result::Success); REQUIRE(linearFill->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success); - REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); //Filled Shapes auto shape3 = tvg::Shape::gen(); @@ -619,7 +619,7 @@ TEST_CASE("Filling AlphaMask", "[tvgSwEngine]") REQUIRE(linearFill->colorStops(cs, 4) == Result::Success); REQUIRE(radialFill->colorStops(cs, 4) == Result::Success); REQUIRE(linearFill->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success); - REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); //Mask auto mask = tvg::Shape::gen(); @@ -678,7 +678,7 @@ TEST_CASE("Filling InvAlphaMask", "[tvgSwEngine]") REQUIRE(linearFill->colorStops(cs, 4) == Result::Success); REQUIRE(radialFill->colorStops(cs, 4) == Result::Success); REQUIRE(linearFill->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success); - REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); //Mask auto mask = tvg::Shape::gen(); @@ -737,7 +737,7 @@ TEST_CASE("Filling LumaMask", "[tvgSwEngine]") REQUIRE(linearFill->colorStops(cs, 4) == Result::Success); REQUIRE(radialFill->colorStops(cs, 4) == Result::Success); REQUIRE(linearFill->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success); - REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); //Mask auto mask = tvg::Shape::gen(); @@ -796,7 +796,7 @@ TEST_CASE("Filling Clipping", "[tvgSwEngine]") REQUIRE(linearFill->colorStops(cs, 4) == Result::Success); REQUIRE(radialFill->colorStops(cs, 4) == Result::Success); REQUIRE(linearFill->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success); - REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); //Clipper auto clipper = tvg::Shape::gen(); @@ -855,7 +855,7 @@ TEST_CASE("RLE Filling Draw", "[tvgSwEngine]") REQUIRE(linearFill->colorStops(cs, 4) == Result::Success); REQUIRE(radialFill->colorStops(cs, 4) == Result::Success); REQUIRE(linearFill->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success); - REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); //Filled Shapes auto shape3 = tvg::Shape::gen(); @@ -904,7 +904,7 @@ TEST_CASE("RLE Filling Opaque Draw", "[tvgSwEngine]") REQUIRE(linearFill->colorStops(cs, 4) == Result::Success); REQUIRE(radialFill->colorStops(cs, 4) == Result::Success); REQUIRE(linearFill->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success); - REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); //Filled Shapes auto shape3 = tvg::Shape::gen(); @@ -953,7 +953,7 @@ TEST_CASE("RLE Filling AlphaMask", "[tvgSwEngine]") REQUIRE(linearFill->colorStops(cs, 4) == Result::Success); REQUIRE(radialFill->colorStops(cs, 4) == Result::Success); REQUIRE(linearFill->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success); - REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); //Mask auto mask = tvg::Shape::gen(); @@ -1012,7 +1012,7 @@ TEST_CASE("RLE Filling InvAlphaMask", "[tvgSwEngine]") REQUIRE(linearFill->colorStops(cs, 4) == Result::Success); REQUIRE(radialFill->colorStops(cs, 4) == Result::Success); REQUIRE(linearFill->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success); - REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); //Mask auto mask = tvg::Shape::gen(); @@ -1071,7 +1071,7 @@ TEST_CASE("RLE Filling LumaMask", "[tvgSwEngine]") REQUIRE(linearFill->colorStops(cs, 4) == Result::Success); REQUIRE(radialFill->colorStops(cs, 4) == Result::Success); REQUIRE(linearFill->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success); - REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); //Mask auto mask = tvg::Shape::gen(); @@ -1130,7 +1130,7 @@ TEST_CASE("RLE Filling InvLumaMask", "[tvgSwEngine]") REQUIRE(linearFill->colorStops(cs, 4) == Result::Success); REQUIRE(radialFill->colorStops(cs, 4) == Result::Success); REQUIRE(linearFill->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success); - REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); //Mask auto mask = tvg::Shape::gen(); @@ -1189,7 +1189,7 @@ TEST_CASE("RLE Filling Clipping", "[tvgSwEngine]") REQUIRE(linearFill->colorStops(cs, 4) == Result::Success); REQUIRE(radialFill->colorStops(cs, 4) == Result::Success); REQUIRE(linearFill->linear(0.0f, 0.0f, 100.0f, 120.0f) == Result::Success); - REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); //Mask auto clipper = tvg::Shape::gen(); @@ -1391,7 +1391,7 @@ TEST_CASE("Blending with Gradient Filling", "[tvgSwEngine]") auto radialFill = RadialGradient::gen(); REQUIRE(radialFill); REQUIRE(radialFill->colorStops(cs, 4) == Result::Success); - REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); auto shape2 = tvg::Shape::gen(); REQUIRE(shape2); @@ -1422,7 +1422,7 @@ TEST_CASE("Blending with Gradient Filling", "[tvgSwEngine]") auto radialFill2 = RadialGradient::gen(); REQUIRE(radialFill2); REQUIRE(radialFill2->colorStops(cs, 4) == Result::Success); - REQUIRE(radialFill2->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill2->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); auto mask2 = tvg::Shape::gen(); REQUIRE(mask2); @@ -1458,7 +1458,7 @@ TEST_CASE("Blending with Gradient Filling", "[tvgSwEngine]") auto radialFill3 = RadialGradient::gen(); REQUIRE(radialFill3); REQUIRE(radialFill3->colorStops(cs, 4) == Result::Success); - REQUIRE(radialFill3->radial(50.0f, 50.0f, 50.0f) == Result::Success); + REQUIRE(radialFill3->radial(50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0.0f) == Result::Success); auto mask4 = tvg::Shape::gen(); REQUIRE(mask4);