| /* |
| * Copyright 2021 Google Inc. |
| * Copyright 2022 Rive |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "gm.hpp" |
| #include "gmutils.hpp" |
| #include "rive/renderer.hpp" |
| #include "rive/math/math_types.hpp" |
| |
| using namespace rivegm; |
| using namespace rive; |
| |
| constexpr int kSize = 1000; |
| |
| // Makes sure PathInnerTriangulateOp uses correct stencil settings when there is |
| // a clip in the stencil buffer. |
| static void draw_clipped_flower(Renderer* renderer, |
| FillRule fillType, |
| bool asNestedClip) |
| { |
| constexpr static int NUM_PETALS = 9; |
| constexpr static float M = kSize / 3.f; |
| constexpr static float A = kSize / 2.f; |
| Path flower; |
| flower->fillRule(fillType); |
| flower->moveTo(1 * M + A, 0 * M + A); |
| for (int i = 1; i <= NUM_PETALS; ++i) |
| { |
| float c1 = 2 * rive::math::PI * (i - 2 / 3.f) / NUM_PETALS; |
| float c2 = 2 * rive::math::PI * (i - 1 / 3.f) / NUM_PETALS; |
| float theta = 2 * rive::math::PI * i / NUM_PETALS; |
| flower->cubicTo(cosf(c1) * 1.65 * M + A, |
| sinf(c1) * 1.65 * M + A, |
| cosf(c2) * 1.65 * M + A, |
| sinf(c2) * 1.65 * M + A, |
| cosf(theta) * M + A, |
| sinf(theta) * M + A); |
| } |
| flower->close(); |
| path_addOval( |
| flower, |
| AABB(-.75f * M + A, -.75f * M + A, .75f * M + A, .75f * M + A)); |
| |
| if (asNestedClip) |
| { |
| renderer->clipPath(flower); |
| } |
| |
| PathBuilder clip; |
| clip.fillRule(fillType); |
| constexpr static int kGridCount = 50; |
| constexpr static float kCellSize = (float)kSize / kGridCount; |
| for (int y = 0; y < kGridCount; y += fillType == FillRule::evenOdd ? 2 : 1) |
| { |
| clip.addRect(AABB(0, y * kCellSize, kSize, (y + 1) * kCellSize), |
| (y & 1) ? rivegm::PathDirection::cw |
| : rivegm::PathDirection::ccw); |
| } |
| for (int x = fillType == FillRule::evenOdd ? 1 : 0; x < kGridCount; |
| x += fillType == FillRule::evenOdd ? 2 : 1) |
| { |
| clip.addRect(AABB(x * kCellSize, 0, (x + 1) * kCellSize, kSize), |
| (x & 1) ? rivegm::PathDirection::cw |
| : rivegm::PathDirection::ccw); |
| } |
| renderer->clipPath(clip.detach()); |
| |
| Paint p; |
| p->color(0xffff00ff); |
| if (asNestedClip) |
| { |
| renderer->drawPath(PathBuilder::Rect({0, 0, kSize, kSize}), p); |
| } |
| else |
| { |
| renderer->drawPath(flower, p); |
| } |
| } |
| |
| DEF_SIMPLE_GM_WITH_CLEAR_COLOR(largeclippedpath_winding, |
| 0xff00ffff, |
| kSize, |
| kSize, |
| renderer) |
| { |
| draw_clipped_flower(renderer, FillRule::nonZero, /*asNestedClip=*/false); |
| } |
| |
| DEF_SIMPLE_GM_WITH_CLEAR_COLOR(largeclippedpath_winding_nested, |
| 0xff00ffff, |
| kSize, |
| kSize, |
| renderer) |
| { |
| draw_clipped_flower(renderer, FillRule::nonZero, /*asNestedClip=*/true); |
| } |
| |
| DEF_SIMPLE_GM_WITH_CLEAR_COLOR(largeclippedpath_evenodd, |
| 0xff00ffff, |
| kSize, |
| kSize, |
| renderer) |
| { |
| draw_clipped_flower(renderer, FillRule::evenOdd, /*asNestedClip=*/false); |
| } |
| |
| DEF_SIMPLE_GM_WITH_CLEAR_COLOR(largeclippedpath_evenodd_nested, |
| 0xff00ffff, |
| kSize, |
| kSize, |
| renderer) |
| { |
| draw_clipped_flower(renderer, FillRule::evenOdd, /*asNestedClip=*/true); |
| } |
| |
| DEF_SIMPLE_GM_WITH_CLEAR_COLOR(largeclippedpath_clockwise, |
| 0xff00ffff, |
| kSize, |
| kSize, |
| renderer) |
| { |
| draw_clipped_flower(renderer, FillRule::clockwise, /*asNestedClip=*/false); |
| } |
| |
| DEF_SIMPLE_GM_WITH_CLEAR_COLOR(largeclippedpath_clockwise_nested, |
| 0xff00ffff, |
| kSize, |
| kSize, |
| renderer) |
| { |
| draw_clipped_flower(renderer, FillRule::clockwise, /*asNestedClip=*/true); |
| } |