diff --git a/impeller/aiks/aiks_blur_unittests.cc b/impeller/aiks/aiks_blur_unittests.cc index b1593bf72ab7b..03151a3ffbe67 100644 --- a/impeller/aiks/aiks_blur_unittests.cc +++ b/impeller/aiks/aiks_blur_unittests.cc @@ -76,8 +76,9 @@ TEST_P(AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur) { TEST_P(AiksTest, CanRenderBackdropBlurInteractive) { auto callback = [&](AiksContext& renderer) -> std::optional { - auto [a, b] = IMPELLER_PLAYGROUND_LINE(Point(50, 50), Point(300, 200), 30, - Color::White(), Color::White()); + static PlaygroundPoint point_a(Point(50, 50), 30, Color::White()); + static PlaygroundPoint point_b(Point(300, 200), 30, Color::White()); + auto [a, b] = DrawPlaygroundLine(point_a, point_b); Canvas canvas; canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()}); @@ -143,7 +144,9 @@ TEST_P(AiksTest, CanRenderClippedBlur) { TEST_P(AiksTest, ClippedBlurFilterRendersCorrectlyInteractive) { auto callback = [&](AiksContext& renderer) -> std::optional { - auto point = IMPELLER_PLAYGROUND_POINT(Point(400, 400), 20, Color::Green()); + static PlaygroundPoint playground_point(Point(400, 400), 20, + Color::Green()); + auto point = DrawPlaygroundPoint(playground_point); Canvas canvas; canvas.Translate(point - Point(400, 400)); @@ -465,8 +468,9 @@ TEST_P(AiksTest, GaussianBlurRotatedAndClippedInteractive) { ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0), FilterContents::BlurStyle::kNormal, tile_modes[selected_tile_mode])}; - auto [handle_a, handle_b] = IMPELLER_PLAYGROUND_LINE( - Point(362, 309), Point(662, 459), 20, Color::Red(), Color::Red()); + static PlaygroundPoint point_a(Point(362, 309), 20, Color::Red()); + static PlaygroundPoint point_b(Point(662, 459), 20, Color::Red()); + auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b); Vector2 center = Vector2(1024, 768) / 2; canvas.Scale(GetContentScale()); canvas.ClipRect( @@ -567,8 +571,9 @@ TEST_P(AiksTest, GaussianBlurAnimatedBackdrop) { Point(1024 / 2 - boston->GetSize().width / 2, (768 / 2 - boston->GetSize().height / 2) + y), {}); - auto [handle_a, handle_b] = IMPELLER_PLAYGROUND_LINE( - Point(100, 100), Point(900, 700), 20, Color::Red(), Color::Red()); + static PlaygroundPoint point_a(Point(100, 100), 20, Color::Red()); + static PlaygroundPoint point_b(Point(900, 700), 20, Color::Red()); + auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b); canvas.ClipRect( Rect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y)); canvas.ClipRect(Rect::MakeLTRB(100, 100, 900, 700)); diff --git a/impeller/aiks/aiks_gradient_unittests.cc b/impeller/aiks/aiks_gradient_unittests.cc index a06fec82d7dfa..7938fb60f9f3c 100644 --- a/impeller/aiks/aiks_gradient_unittests.cc +++ b/impeller/aiks/aiks_gradient_unittests.cc @@ -702,8 +702,12 @@ TEST_P(AiksTest, GradientStrokesRenderCorrectly) { canvas.Scale(Vector2(scale, scale)); if (add_circle_clip) { - auto [handle_a, handle_b] = IMPELLER_PLAYGROUND_LINE( - Point(60, 300), Point(600, 300), 20, Color::Red(), Color::Red()); + static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20, + Color::Red()); + static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20, + Color::Red()); + auto [handle_a, handle_b] = + DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b); auto screen_to_canvas = canvas.GetCurrentTransform().Invert(); Point point_a = screen_to_canvas * handle_a * GetContentScale(); diff --git a/impeller/aiks/aiks_path_unittests.cc b/impeller/aiks/aiks_path_unittests.cc index 09df07f167580..9d5cc3936e858 100644 --- a/impeller/aiks/aiks_path_unittests.cc +++ b/impeller/aiks/aiks_path_unittests.cc @@ -215,8 +215,12 @@ TEST_P(AiksTest, SolidStrokesRenderCorrectly) { canvas.Scale(Vector2(scale, scale)); if (add_circle_clip) { - auto [handle_a, handle_b] = IMPELLER_PLAYGROUND_LINE( - Point(60, 300), Point(600, 300), 20, Color::Red(), Color::Red()); + static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20, + Color::Red()); + static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20, + Color::Red()); + auto [handle_a, handle_b] = + DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b); auto screen_to_canvas = canvas.GetCurrentTransform().Invert(); Point point_a = screen_to_canvas * handle_a * GetContentScale(); diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index f4911daa72256..cab7c4e75611c 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -1715,8 +1715,9 @@ TEST_P(AiksTest, CoverageOriginShouldBeAccountedForInSubpasses) { const auto offset = Point{25, 25}; const auto size = Size(100, 100); - auto [b0, b1] = IMPELLER_PLAYGROUND_LINE(Point(40, 40), Point(160, 160), 10, - Color::White(), Color::White()); + static PlaygroundPoint point_a(Point(40, 40), 10, Color::White()); + static PlaygroundPoint point_b(Point(160, 160), 10, Color::White()); + auto [b0, b1] = DrawPlaygroundLine(point_a, point_b); auto bounds = Rect::MakeLTRB(b0.x, b0.y, b1.x, b1.y); canvas.DrawRect(bounds, Paint{.color = Color::Yellow(), diff --git a/impeller/display_list/dl_unittests.cc b/impeller/display_list/dl_unittests.cc index 40de533079e50..6b6f8a19c02b4 100644 --- a/impeller/display_list/dl_unittests.cc +++ b/impeller/display_list/dl_unittests.cc @@ -184,8 +184,9 @@ TEST_P(DisplayListTest, CanDrawArc) { break; } - auto [p1, p2] = IMPELLER_PLAYGROUND_LINE( - Point(200, 200), Point(400, 400), 20, Color::White(), Color::White()); + static PlaygroundPoint point_a(Point(200, 200), 20, Color::White()); + static PlaygroundPoint point_b(Point(400, 400), 20, Color::White()); + auto [p1, p2] = DrawPlaygroundLine(point_a, point_b); flutter::DisplayListBuilder builder; flutter::DlPaint paint; @@ -676,8 +677,9 @@ TEST_P(DisplayListTest, CanDrawBackdropFilter) { std::optional bounds; if (use_bounds) { - auto [p1, p2] = IMPELLER_PLAYGROUND_LINE( - Point(350, 150), Point(800, 600), 20, Color::White(), Color::White()); + static PlaygroundPoint point_a(Point(350, 150), 20, Color::White()); + static PlaygroundPoint point_b(Point(800, 600), 20, Color::White()); + auto [p1, p2] = DrawPlaygroundLine(point_a, point_b); bounds = SkRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y); } @@ -694,8 +696,8 @@ TEST_P(DisplayListTest, CanDrawBackdropFilter) { &filter); if (draw_circle) { - auto circle_center = - IMPELLER_PLAYGROUND_POINT(Point(500, 400), 20, Color::Red()); + static PlaygroundPoint center_point(Point(500, 400), 20, Color::Red()); + auto circle_center = DrawPlaygroundPoint(center_point); flutter::DlPaint paint; paint.setDrawStyle(flutter::DlDrawStyle::kStroke); diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index eb94c695caec6..4222715a28ac5 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -300,20 +300,21 @@ TEST_P(EntityTest, TriangleInsideASquare) { auto callback = [&](ContentContext& context, RenderPass& pass) { Point offset(100, 100); - Point a = - IMPELLER_PLAYGROUND_POINT(Point(10, 10) + offset, 20, Color::White()); - Point b = - IMPELLER_PLAYGROUND_POINT(Point(210, 10) + offset, 20, Color::White()); - Point c = - IMPELLER_PLAYGROUND_POINT(Point(210, 210) + offset, 20, Color::White()); - Point d = - IMPELLER_PLAYGROUND_POINT(Point(10, 210) + offset, 20, Color::White()); - Point e = - IMPELLER_PLAYGROUND_POINT(Point(50, 50) + offset, 20, Color::White()); - Point f = - IMPELLER_PLAYGROUND_POINT(Point(100, 50) + offset, 20, Color::White()); - Point g = - IMPELLER_PLAYGROUND_POINT(Point(50, 150) + offset, 20, Color::White()); + static PlaygroundPoint point_a(Point(10, 10) + offset, 20, Color::White()); + Point a = DrawPlaygroundPoint(point_a); + static PlaygroundPoint point_b(Point(210, 10) + offset, 20, Color::White()); + Point b = DrawPlaygroundPoint(point_b); + static PlaygroundPoint point_c(Point(210, 210) + offset, 20, + Color::White()); + Point c = DrawPlaygroundPoint(point_c); + static PlaygroundPoint point_d(Point(10, 210) + offset, 20, Color::White()); + Point d = DrawPlaygroundPoint(point_d); + static PlaygroundPoint point_e(Point(50, 50) + offset, 20, Color::White()); + Point e = DrawPlaygroundPoint(point_e); + static PlaygroundPoint point_f(Point(100, 50) + offset, 20, Color::White()); + Point f = DrawPlaygroundPoint(point_f); + static PlaygroundPoint point_g(Point(50, 150) + offset, 20, Color::White()); + Point g = DrawPlaygroundPoint(point_g); Path path = PathBuilder{} .MoveTo(a) .LineTo(b) @@ -392,10 +393,12 @@ TEST_P(EntityTest, StrokeCapAndJoinTest) { // Cap::kButt demo. { Point off = Point(0, 0) * padding + margin; - auto [a, b] = IMPELLER_PLAYGROUND_LINE(off + a_def, off + b_def, r, - Color::Black(), Color::White()); - auto [c, d] = IMPELLER_PLAYGROUND_LINE(off + c_def, off + d_def, r, - Color::Black(), Color::White()); + static PlaygroundPoint point_a(off + a_def, r, Color::Black()); + static PlaygroundPoint point_b(off + b_def, r, Color::White()); + auto [a, b] = DrawPlaygroundLine(point_a, point_b); + static PlaygroundPoint point_c(off + c_def, r, Color::Black()); + static PlaygroundPoint point_d(off + d_def, r, Color::White()); + auto [c, d] = DrawPlaygroundLine(point_c, point_d); render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(), Cap::kButt, Join::kBevel); } @@ -403,10 +406,12 @@ TEST_P(EntityTest, StrokeCapAndJoinTest) { // Cap::kSquare demo. { Point off = Point(1, 0) * padding + margin; - auto [a, b] = IMPELLER_PLAYGROUND_LINE(off + a_def, off + b_def, r, - Color::Black(), Color::White()); - auto [c, d] = IMPELLER_PLAYGROUND_LINE(off + c_def, off + d_def, r, - Color::Black(), Color::White()); + static PlaygroundPoint point_a(off + a_def, r, Color::Black()); + static PlaygroundPoint point_b(off + b_def, r, Color::White()); + auto [a, b] = DrawPlaygroundLine(point_a, point_b); + static PlaygroundPoint point_c(off + c_def, r, Color::Black()); + static PlaygroundPoint point_d(off + d_def, r, Color::White()); + auto [c, d] = DrawPlaygroundLine(point_c, point_d); render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(), Cap::kSquare, Join::kBevel); } @@ -414,10 +419,12 @@ TEST_P(EntityTest, StrokeCapAndJoinTest) { // Cap::kRound demo. { Point off = Point(2, 0) * padding + margin; - auto [a, b] = IMPELLER_PLAYGROUND_LINE(off + a_def, off + b_def, r, - Color::Black(), Color::White()); - auto [c, d] = IMPELLER_PLAYGROUND_LINE(off + c_def, off + d_def, r, - Color::Black(), Color::White()); + static PlaygroundPoint point_a(off + a_def, r, Color::Black()); + static PlaygroundPoint point_b(off + b_def, r, Color::White()); + auto [a, b] = DrawPlaygroundLine(point_a, point_b); + static PlaygroundPoint point_c(off + c_def, r, Color::Black()); + static PlaygroundPoint point_d(off + d_def, r, Color::White()); + auto [c, d] = DrawPlaygroundLine(point_c, point_d); render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(), Cap::kRound, Join::kBevel); } @@ -425,9 +432,15 @@ TEST_P(EntityTest, StrokeCapAndJoinTest) { // Join::kBevel demo. { Point off = Point(0, 1) * padding + margin; - Point a = IMPELLER_PLAYGROUND_POINT(off + a_def, r, Color::White()); - Point b = IMPELLER_PLAYGROUND_POINT(off + e_def, r, Color::White()); - Point c = IMPELLER_PLAYGROUND_POINT(off + c_def, r, Color::White()); + static PlaygroundPoint point_a = + PlaygroundPoint(off + a_def, r, Color::White()); + static PlaygroundPoint point_b = + PlaygroundPoint(off + e_def, r, Color::White()); + static PlaygroundPoint point_c = + PlaygroundPoint(off + c_def, r, Color::White()); + Point a = DrawPlaygroundPoint(point_a); + Point b = DrawPlaygroundPoint(point_b); + Point c = DrawPlaygroundPoint(point_c); render_path( PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(), Cap::kButt, Join::kBevel); @@ -436,9 +449,12 @@ TEST_P(EntityTest, StrokeCapAndJoinTest) { // Join::kMiter demo. { Point off = Point(1, 1) * padding + margin; - Point a = IMPELLER_PLAYGROUND_POINT(off + a_def, r, Color::White()); - Point b = IMPELLER_PLAYGROUND_POINT(off + e_def, r, Color::White()); - Point c = IMPELLER_PLAYGROUND_POINT(off + c_def, r, Color::White()); + static PlaygroundPoint point_a(off + a_def, r, Color::White()); + static PlaygroundPoint point_b(off + e_def, r, Color::White()); + static PlaygroundPoint point_c(off + c_def, r, Color::White()); + Point a = DrawPlaygroundPoint(point_a); + Point b = DrawPlaygroundPoint(point_b); + Point c = DrawPlaygroundPoint(point_c); render_path( PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(), Cap::kButt, Join::kMiter); @@ -447,9 +463,12 @@ TEST_P(EntityTest, StrokeCapAndJoinTest) { // Join::kRound demo. { Point off = Point(2, 1) * padding + margin; - Point a = IMPELLER_PLAYGROUND_POINT(off + a_def, r, Color::White()); - Point b = IMPELLER_PLAYGROUND_POINT(off + e_def, r, Color::White()); - Point c = IMPELLER_PLAYGROUND_POINT(off + c_def, r, Color::White()); + static PlaygroundPoint point_a(off + a_def, r, Color::White()); + static PlaygroundPoint point_b(off + e_def, r, Color::White()); + static PlaygroundPoint point_c(off + c_def, r, Color::White()); + Point a = DrawPlaygroundPoint(point_a); + Point b = DrawPlaygroundPoint(point_b); + Point c = DrawPlaygroundPoint(point_c); render_path( PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(), Cap::kButt, Join::kRound); @@ -905,10 +924,12 @@ TEST_P(EntityTest, BlendingModeOptions) { BlendMode selected_mode = blend_mode_values[current_blend_index]; Point a, b, c, d; - std::tie(a, b) = IMPELLER_PLAYGROUND_LINE( - Point(400, 100), Point(200, 300), 20, Color::White(), Color::White()); - std::tie(c, d) = IMPELLER_PLAYGROUND_LINE( - Point(470, 190), Point(270, 390), 20, Color::White(), Color::White()); + static PlaygroundPoint point_a(Point(400, 100), 20, Color::White()); + static PlaygroundPoint point_b(Point(200, 300), 20, Color::White()); + std::tie(a, b) = DrawPlaygroundLine(point_a, point_b); + static PlaygroundPoint point_c(Point(470, 190), 20, Color::White()); + static PlaygroundPoint point_d(Point(270, 390), 20, Color::White()); + std::tie(c, d) = DrawPlaygroundLine(point_c, point_d); bool result = true; result = result && @@ -1739,8 +1760,11 @@ TEST_P(EntityTest, RRectShadowTest) { } ImGui::End(); - auto [top_left, bottom_right] = IMPELLER_PLAYGROUND_LINE( - Point(200, 200), Point(600, 400), 30, Color::White(), Color::White()); + static PlaygroundPoint top_left_point(Point(200, 200), 30, Color::White()); + static PlaygroundPoint bottom_right_point(Point(600, 400), 30, + Color::White()); + auto [top_left, bottom_right] = + DrawPlaygroundLine(top_left_point, bottom_right_point); auto rect = Rect::MakeLTRB(top_left.x, top_left.y, bottom_right.x, bottom_right.y); diff --git a/impeller/playground/widgets.cc b/impeller/playground/widgets.cc index ed3f76c380098..b1fd5cd145b9b 100644 --- a/impeller/playground/widgets.cc +++ b/impeller/playground/widgets.cc @@ -2,10 +2,62 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "widgets.h" +#include "impeller/playground/widgets.h" namespace impeller { +Point DrawPlaygroundPoint(PlaygroundPoint& point) { + impeller::Point mouse_pos(ImGui::GetMousePos().x, ImGui::GetMousePos().y); + if (!point.prev_mouse_pos.has_value()) { + point.prev_mouse_pos = mouse_pos; + } + + if (ImGui::IsKeyPressed(ImGuiKey_R)) { + point.position = point.reset_position; + point.dragging = false; + } + + bool hovering = + point.position.GetDistance(mouse_pos) < point.radius && + point.position.GetDistance(point.prev_mouse_pos.value()) < point.radius; + if (!ImGui::IsMouseDown(0)) { + point.dragging = false; + } else if (hovering && ImGui::IsMouseClicked(0)) { + point.dragging = true; + } + if (point.dragging) { + point.position += mouse_pos - point.prev_mouse_pos.value(); + } + ImGui::GetBackgroundDrawList()->AddCircleFilled( + {point.position.x, point.position.y}, point.radius, + ImColor(point.color.red, point.color.green, point.color.blue, + (hovering || point.dragging) ? 0.6f : 0.3f)); + if (hovering || point.dragging) { + ImGui::GetBackgroundDrawList()->AddText( + {point.position.x - point.radius, point.position.y + point.radius + 10}, + ImColor(point.color.red, point.color.green, point.color.blue, 1.0f), + impeller::SPrintF("x:%0.3f y:%0.3f", point.position.x, point.position.y) + .c_str()); + } + point.prev_mouse_pos = mouse_pos; + return point.position; +} + +std::tuple DrawPlaygroundLine(PlaygroundPoint& point_a, + PlaygroundPoint& point_b) { + Point position_a = DrawPlaygroundPoint(point_a); + Point position_b = DrawPlaygroundPoint(point_b); + + auto dir = (position_b - position_a).Normalize() * point_a.radius; + auto line_a = position_a + dir; + auto line_b = position_b - dir; + ImGui::GetBackgroundDrawList()->AddLine( + {line_a.x, line_a.y}, {line_b.x, line_b.y}, + ImColor(point_b.color.red, point_b.color.green, point_b.color.blue, + 0.3f)); + + return std::make_tuple(position_a, position_b); +} // } // namespace impeller diff --git a/impeller/playground/widgets.h b/impeller/playground/widgets.h index 59957451b1ddf..7da9b4b4865cb 100644 --- a/impeller/playground/widgets.h +++ b/impeller/playground/widgets.h @@ -5,6 +5,7 @@ #ifndef FLUTTER_IMPELLER_PLAYGROUND_WIDGETS_H_ #define FLUTTER_IMPELLER_PLAYGROUND_WIDGETS_H_ +#include #include #include "impeller/base/strings.h" @@ -12,67 +13,27 @@ #include "impeller/geometry/point.h" #include "third_party/imgui/imgui.h" -#define IMPELLER_PLAYGROUND_POINT(default_position, radius, color) \ - ({ \ - static impeller::Point position = default_position; \ - static impeller::Point reset_position = default_position; \ - float radius_ = radius; \ - impeller::Color color_ = color; \ - \ - static bool dragging = false; \ - impeller::Point mouse_pos(ImGui::GetMousePos().x, ImGui::GetMousePos().y); \ - static impeller::Point prev_mouse_pos = mouse_pos; \ - \ - if (ImGui::IsKeyPressed(ImGuiKey_R)) { \ - position = reset_position; \ - dragging = false; \ - } \ - \ - bool hovering = position.GetDistance(mouse_pos) < radius_ && \ - position.GetDistance(prev_mouse_pos) < radius_; \ - if (!ImGui::IsMouseDown(0)) { \ - dragging = false; \ - } else if (hovering && ImGui::IsMouseClicked(0)) { \ - dragging = true; \ - } \ - if (dragging) { \ - position += mouse_pos - prev_mouse_pos; \ - } \ - ImGui::GetBackgroundDrawList()->AddCircleFilled( \ - {position.x, position.y}, radius_, \ - ImColor(color_.red, color_.green, color_.blue, \ - (hovering || dragging) ? 0.6f : 0.3f)); \ - if (hovering || dragging) { \ - ImGui::GetBackgroundDrawList()->AddText( \ - {position.x - radius_, position.y + radius_ + 10}, \ - ImColor(color_.red, color.green, color.blue, 1.0f), \ - impeller::SPrintF("x:%0.3f y:%0.3f", position.x, position.y) \ - .c_str()); \ - } \ - prev_mouse_pos = mouse_pos; \ - position; \ - }) +namespace impeller { +struct PlaygroundPoint { + PlaygroundPoint(Point default_position, Scalar p_radius, Color p_color) + : position(default_position), + reset_position(default_position), + radius(p_radius), + color(p_color) {} + Point position; + Point reset_position; + bool dragging = false; + std::optional prev_mouse_pos; + Scalar radius; + Color color; + PlaygroundPoint(const PlaygroundPoint&) = delete; + PlaygroundPoint(PlaygroundPoint&&) = delete; + PlaygroundPoint& operator=(const PlaygroundPoint&) = delete; +}; -#define IMPELLER_PLAYGROUND_LINE(default_position_a, default_position_b, \ - radius, color_a, color_b) \ - ({ \ - impeller::Point position_a = default_position_a; \ - impeller::Point position_b = default_position_b; \ - float r_ = radius; \ - impeller::Color color_a_ = color_a; \ - impeller::Color color_b_ = color_b; \ - \ - position_a = IMPELLER_PLAYGROUND_POINT(position_a, r_, color_a_); \ - position_b = IMPELLER_PLAYGROUND_POINT(position_b, r_, color_b_); \ - \ - auto dir = (position_b - position_a).Normalize() * r_; \ - auto line_a = position_a + dir; \ - auto line_b = position_b - dir; \ - ImGui::GetBackgroundDrawList()->AddLine( \ - {line_a.x, line_a.y}, {line_b.x, line_b.y}, \ - ImColor(color_b.red, color_b.green, color_b.blue, 0.3f)); \ - \ - std::make_tuple(position_a, position_b); \ - }) +Point DrawPlaygroundPoint(PlaygroundPoint& point); +std::tuple DrawPlaygroundLine(PlaygroundPoint& point_a, + PlaygroundPoint& point_b); +} // namespace impeller #endif // FLUTTER_IMPELLER_PLAYGROUND_WIDGETS_H_