| /* | |
| * Copyright 2026 Rive | |
| */ | |
| #include "gm.hpp" | |
| #include "gmutils.hpp" | |
| #include "rive/math/math_types.hpp" | |
| #include "rive/renderer.hpp" | |
| #include "common/rand.hpp" | |
| using namespace rivegm; | |
| using namespace rive; | |
| namespace | |
| { | |
| enum class UseFeather : bool | |
| { | |
| No, | |
| Yes, | |
| }; | |
| enum class ShapeSize | |
| { | |
| Small, | |
| Large, | |
| Stretch, | |
| }; | |
| template <UseFeather Feather, | |
| ShapeSize InnerSize, | |
| BlendMode Blend = BlendMode::srcOver> | |
| class ClipShapesGM : public GM | |
| { | |
| public: | |
| static constexpr int32_t SectionSize = 400; | |
| static constexpr int32_t Spacing = 50; | |
| static constexpr int32_t RoundRadius = 50; | |
| static constexpr int32_t SectionCount = 3; | |
| static constexpr int32_t ImageDim = SectionCount * SectionSize; | |
| ClipShapesGM() : GM(ImageDim, ImageDim) {} | |
| void onDraw(rive::Renderer* renderer) override | |
| { | |
| { | |
| Paint p; | |
| p->color(0xff000000); | |
| renderer->drawPath( | |
| PathBuilder::Rect( | |
| {0.0f, 0.0f, float(ImageDim), float(ImageDim)}), | |
| p); | |
| } | |
| { | |
| Paint p; | |
| p->color(0xff2c1642); | |
| p->feather(10.0f); | |
| auto yStep = 40.0f; | |
| for (auto y = 20.0f; y < float(SectionCount * SectionSize); y++) | |
| { | |
| auto path = PathBuilder::Rect({ | |
| -100.0f, | |
| y, | |
| float(ImageDim) + 100.0f, | |
| y + yStep * 0.3f, | |
| }); | |
| path->fillRule(FillRule::clockwise); | |
| renderer->drawPath(path, p); | |
| y += yStep; | |
| yStep *= 1.12f; | |
| } | |
| } | |
| constexpr uint32_t Colors[SectionCount][SectionCount] = { | |
| { | |
| 0xff881177, | |
| 0xffeedd00, | |
| 0xff00bbcc, | |
| }, | |
| { | |
| 0xffaa3355, | |
| 0xff99dd55, | |
| 0xffee9944, | |
| }, | |
| { | |
| 0xffcc6666, | |
| 0xff3366bb, | |
| 0xff22ccbb, | |
| }, | |
| }; | |
| for (auto yIndex = 0; yIndex < 3; yIndex++) | |
| { | |
| for (auto xIndex = 0; xIndex < 3; xIndex++) | |
| { | |
| renderer->save(); | |
| { | |
| const auto box = AABB{ | |
| float(SectionSize * xIndex + Spacing / 2), | |
| float(SectionSize * yIndex + Spacing / 2), | |
| float(SectionSize * (xIndex + 1) - Spacing / 2), | |
| float(SectionSize * (yIndex + 1) - Spacing / 2), | |
| }; | |
| auto clipper = PathBuilder::RRect(box, | |
| float(RoundRadius), | |
| float(RoundRadius)); | |
| renderer->clipPath(clipper); | |
| Paint p; | |
| p->color(Colors[xIndex][yIndex]); | |
| p->blendMode(Blend); | |
| if constexpr (Feather == UseFeather::Yes) | |
| { | |
| p->feather(float(Spacing)); | |
| } | |
| if constexpr (InnerSize == ShapeSize::Large) | |
| { | |
| const auto dim = | |
| float(SectionCount * SectionSize) * 0.5f; | |
| auto path = PathBuilder::Circle(dim, dim, dim * 0.8f); | |
| path->fillRule(FillRule::clockwise); | |
| renderer->drawPath(path, p); | |
| } | |
| else | |
| { | |
| auto x = lerp(box.right(), | |
| box.left(), | |
| float(xIndex) / float(SectionCount - 1)); | |
| auto y = lerp(box.bottom(), | |
| box.top(), | |
| float(yIndex) / float(SectionCount - 1)); | |
| auto path = | |
| PathBuilder::Circle(x, y, SectionSize * 0.24f); | |
| path->fillRule(FillRule::clockwise); | |
| renderer->drawPath(path, p); | |
| } | |
| } | |
| renderer->restore(); | |
| } | |
| } | |
| } | |
| }; | |
| } // namespace | |
| GMREGISTER(clip_shapes_large_corners, | |
| return (new ClipShapesGM<UseFeather::No, ShapeSize::Large>())) | |
| GMREGISTER(clip_shapes_large_corners_feathered, | |
| return (new ClipShapesGM<UseFeather::Yes, ShapeSize::Large>())) | |
| GMREGISTER(clip_shapes_small_corners, | |
| return (new ClipShapesGM<UseFeather::No, ShapeSize::Small>())) | |
| GMREGISTER(clip_shapes_small_corners_feathered, | |
| return (new ClipShapesGM<UseFeather::Yes, ShapeSize::Small>())) | |
| GMREGISTER(clip_shapes_large_corners_feathered_blend, | |
| return (new ClipShapesGM<UseFeather::Yes, | |
| ShapeSize::Large, | |
| BlendMode::screen>())) | |
| GMREGISTER(clip_shapes_small_corners_feathered_blend, | |
| return (new ClipShapesGM<UseFeather::Yes, | |
| ShapeSize::Small, | |
| BlendMode::screen>())) |