| /* |
| * Copyright 2011 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" |
| |
| using namespace rivegm; |
| using namespace rive; |
| |
| static constexpr int kPtsCount = 3; |
| static constexpr Vec2D kPts[kPtsCount] = { |
| {40, 40}, |
| {80, 40}, |
| {120, 40}, |
| }; |
| |
| static Path make_path_move() |
| { |
| PathBuilder builder; |
| for (Vec2D p : kPts) |
| { |
| builder.moveTo(p.x, p.y); |
| } |
| return builder.detach(); |
| } |
| |
| static Path make_path_move_close() |
| { |
| PathBuilder builder; |
| for (Vec2D p : kPts) |
| { |
| builder.moveTo(p.x, p.y).close(); |
| } |
| return builder.detach(); |
| } |
| |
| static Path make_path_move_line() |
| { |
| PathBuilder builder; |
| for (Vec2D p : kPts) |
| { |
| builder.moveTo(p.x, p.y).lineTo(p.x, p.y); |
| } |
| return builder.detach(); |
| } |
| |
| static Path make_path_move_mix() |
| { |
| return PathBuilder() |
| .moveTo(kPts[0].x, kPts[0].y) |
| .moveTo(kPts[1].x, kPts[1].y) |
| .close() |
| .moveTo(kPts[2].x, kPts[2].y) |
| .lineTo(kPts[2].x, kPts[2].y) |
| .detach(); |
| } |
| |
| class EmptyStrokeGM : public GM |
| { |
| public: |
| struct Options |
| { |
| bool stroke = false, feather = false; |
| }; |
| |
| EmptyStrokeGM(Options options) : GM(180, 540), m_options(options) {} |
| |
| private: |
| void onDraw(Renderer* renderer) override |
| { |
| static constexpr Path (*kProcs[])() = { |
| make_path_move, // expect red red red |
| make_path_move_close, // expect black black black |
| make_path_move_line, // expect black black black |
| make_path_move_mix, // expect red black black, |
| }; |
| |
| Paint paint; |
| if (m_options.stroke) |
| { |
| paint->style(RenderPaintStyle::stroke); |
| paint->thickness(21); |
| } |
| if (m_options.feather) |
| { |
| paint->feather(21); |
| } |
| |
| Paint dotPaint; |
| dotPaint->color(0xffff0000); |
| dotPaint->style(RenderPaintStyle::fill); |
| |
| for (size_t j = 0; j < 3; ++j) |
| { |
| paint->cap(static_cast<StrokeCap>((3 - j) % 3)); |
| paint->join(static_cast<StrokeJoin>(j)); |
| for (auto proc : kProcs) |
| { |
| for (int i = 0; i < 3; ++i) |
| { |
| renderer->drawPath(PathBuilder::Oval({kPts[i].x - 3.5f, |
| kPts[i].y - 3.5f, |
| kPts[i].x + 3.5f, |
| kPts[i].y + 3.5f}), |
| dotPaint); |
| } |
| Path path = proc(); |
| path->fillRule(FillRule::clockwise); |
| renderer->drawPath(path, paint); |
| renderer->translate(0, 40); |
| } |
| } |
| } |
| |
| Options m_options; |
| }; |
| GMREGISTER(emptystroke, |
| return new EmptyStrokeGM({.stroke = true, .feather = false});) |
| GMREGISTER(emptyfeather, |
| return new EmptyStrokeGM({.stroke = false, .feather = true});) |
| GMREGISTER(emptystrokefeather, |
| return new EmptyStrokeGM({.stroke = true, .feather = true});) |