| Flutter Impeller |

aiks_path_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "flutter/impeller/aiks/aiks_unittests.h"
6
7 #include "impeller/aiks/canvas.h"
8 #include "impeller/geometry/path_builder.h"
9 #include "impeller/playground/widgets.h"
10 #include "third_party/imgui/imgui.h"
11
12 ////////////////////////////////////////////////////////////////////////////////
13 // This is for tests of Canvas that are interested the results of rendering
14 // paths.
15 ////////////////////////////////////////////////////////////////////////////////
16
17 namespace impeller {
18 namespace testing {
19
20 TEST_P(AiksTest, RotateColorFilteredPath) {
21 Canvas canvas;
22 canvas.Concat(Matrix::MakeTranslation({300, 300}));
23 canvas.Concat(Matrix::MakeRotationZ(Radians(kPiOver2)));
24 auto arrow_stem =
25 PathBuilder{}.MoveTo({120, 190}).LineTo({120, 50}).TakePath();
26 auto arrow_head = PathBuilder{}
27 .MoveTo({50, 120})
28 .LineTo({120, 190})
29 .LineTo({190, 120})
30 .TakePath();
31 auto paint = Paint{
32 .stroke_width = 15.0,
33 .stroke_cap = Cap::kRound,
34 .stroke_join = Join::kRound,
35 .style = Paint::Style::kStroke,
36 .color_filter =
37 ColorFilter::MakeBlend(BlendMode::kSourceIn, Color::AliceBlue()),
38 };
39
40 canvas.DrawPath(std::move(arrow_stem), paint);
41 canvas.DrawPath(std::move(arrow_head), paint);
42 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
43 }
44
45 TEST_P(AiksTest, CanRenderStrokes) {
46 Canvas canvas;
47 Paint paint;
48 paint.color = Color::Red();
49 paint.stroke_width = 20.0;
50 paint.style = Paint::Style::kStroke;
51 canvas.DrawPath(PathBuilder{}.AddLine({200, 100}, {800, 100}).TakePath(),
52 paint);
53 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
54 }
55
56 TEST_P(AiksTest, CanRenderCurvedStrokes) {
57 Canvas canvas;
58 Paint paint;
59 paint.color = Color::Red();
60 paint.stroke_width = 25.0;
61 paint.style = Paint::Style::kStroke;
62 canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).TakePath(), paint);
63 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
64 }
65
66 TEST_P(AiksTest, CanRenderThickCurvedStrokes) {
67 Canvas canvas;
68 Paint paint;
69 paint.color = Color::Red();
70 paint.stroke_width = 100.0;
71 paint.style = Paint::Style::kStroke;
72 canvas.DrawPath(PathBuilder{}.AddCircle({100, 100}, 50).TakePath(), paint);
73 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
74 }
75
76 TEST_P(AiksTest, CanRenderStrokePathThatEndsAtSharpTurn) {
77 Canvas canvas;
78
79 Paint paint;
80 paint.color = Color::Red();
81 paint.style = Paint::Style::kStroke;
82 paint.stroke_width = 200;
83
84 Rect rect = Rect::MakeXYWH(100, 100, 200, 200);
85 PathBuilder builder;
86 builder.AddArc(rect, Degrees(0), Degrees(90), false);
87
88 canvas.DrawPath(builder.TakePath(), paint);
89 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
90 }
91
92 TEST_P(AiksTest, CanRenderStrokePathWithCubicLine) {
93 Canvas canvas;
94
95 Paint paint;
96 paint.color = Color::Red();
97 paint.style = Paint::Style::kStroke;
98 paint.stroke_width = 20;
99
100 PathBuilder builder;
101 builder.AddCubicCurve({0, 200}, {50, 400}, {350, 0}, {400, 200});
102
103 canvas.DrawPath(builder.TakePath(), paint);
104 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
105 }
106
107 TEST_P(AiksTest, CanRenderDifferencePaths) {
108 Canvas canvas;
109
110 Paint paint;
111 paint.color = Color::Red();
112
113 PathBuilder builder;
114
115 PathBuilder::RoundingRadii radii;
116 radii.top_left = {50, 25};
117 radii.top_right = {25, 50};
118 radii.bottom_right = {50, 25};
119 radii.bottom_left = {25, 50};
120
121 builder.AddRoundedRect(Rect::MakeXYWH(100, 100, 200, 200), radii);
122 builder.AddCircle({200, 200}, 50);
123 auto path = builder.TakePath(FillType::kOdd);
124
125 canvas.DrawImage(
126 std::make_shared<Image>(CreateTextureForFixture("boston.jpg")), {10, 10},
127 Paint{});
128 canvas.DrawPath(std::move(path), paint);
129
130 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
131 }
132
133 // Regression test for https://github.com/flutter/flutter/issues/134816.
134 //
135 // It should be possible to draw 3 lines, and not have an implicit close path.
136 TEST_P(AiksTest, CanDrawAnOpenPath) {
137 Canvas canvas;
138
139 // Starting at (50, 50), draw lines from:
140 // 1. (50, height)
141 // 2. (width, height)
142 // 3. (width, 50)
143 PathBuilder builder;
144 builder.MoveTo({50, 50});
145 builder.LineTo({50, 100});
146 builder.LineTo({100, 100});
147 builder.LineTo({100, 50});
148
149 Paint paint;
150 paint.color = Color::Red();
151 paint.style = Paint::Style::kStroke;
152 paint.stroke_width = 10;
153
154 canvas.DrawPath(builder.TakePath(), paint);
155
156 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
157 }
158
159 TEST_P(AiksTest, CanDrawAnOpenPathThatIsntARect) {
160 Canvas canvas;
161
162 // Draw a stroked path that is explicitly closed to verify
163 // It doesn't become a rectangle.
164 PathBuilder builder;
165 builder.MoveTo({50, 50});
166 builder.LineTo({520, 120});
167 builder.LineTo({300, 310});
168 builder.LineTo({100, 50});
169 builder.Close();
170
171 Paint paint;
172 paint.color = Color::Red();
173 paint.style = Paint::Style::kStroke;
174 paint.stroke_width = 10;
175
176 canvas.DrawPath(builder.TakePath(), paint);
177
178 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
179 }
180
181 TEST_P(AiksTest, SolidStrokesRenderCorrectly) {
182 // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
183 auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
184 static Color color = Color::Black().WithAlpha(0.5);
185 static float scale = 3;
186 static bool add_circle_clip = true;
187
188 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
189 ImGui::ColorEdit4("Color", reinterpret_cast<float*>(&color));
190 ImGui::SliderFloat("Scale", &scale, 0, 6);
191 ImGui::Checkbox("Circle clip", &add_circle_clip);
192 ImGui::End();
193
194 Canvas canvas;
195 canvas.Scale(GetContentScale());
196 Paint paint;
197
198 paint.color = Color::White();
199 canvas.DrawPaint(paint);
200
201 paint.color = color;
202 paint.style = Paint::Style::kStroke;
203 paint.stroke_width = 10;
204
205 Path path = PathBuilder{}
206 .MoveTo({20, 20})
207 .QuadraticCurveTo({60, 20}, {60, 60})
208 .Close()
209 .MoveTo({60, 20})
210 .QuadraticCurveTo({60, 60}, {20, 60})
211 .TakePath();
212
213 canvas.Scale(Vector2(scale, scale));
214
215 if (add_circle_clip) {
216 auto [handle_a, handle_b] = IMPELLER_PLAYGROUND_LINE(
217 Point(60, 300), Point(600, 300), 20, Color::Red(), Color::Red());
218
219 auto screen_to_canvas = canvas.GetCurrentTransform().Invert();
220 Point point_a = screen_to_canvas * handle_a * GetContentScale();
221 Point point_b = screen_to_canvas * handle_b * GetContentScale();
222
223 Point middle = (point_a + point_b) / 2;
224 auto radius = point_a.GetDistance(middle);
225 canvas.ClipPath(PathBuilder{}.AddCircle(middle, radius).TakePath());
226 }
227
228 for (auto join : {Join::kBevel, Join::kRound, Join::kMiter}) {
229 paint.stroke_join = join;
230 for (auto cap : {Cap::kButt, Cap::kSquare, Cap::kRound}) {
231 paint.stroke_cap = cap;
232 canvas.DrawPath(path.Clone(), paint);
233 canvas.Translate({80, 0});
234 }
235 canvas.Translate({-240, 60});
236 }
237
238 return canvas.EndRecordingAsPicture();
239 };
240
241 ASSERT_TRUE(OpenPlaygroundHere(callback));
242 }
243
244 TEST_P(AiksTest, DrawLinesRenderCorrectly) {
245 Canvas canvas;
246 canvas.Scale(GetContentScale());
247 Paint paint;
248 paint.color = Color::Blue();
249 paint.stroke_width = 10;
250
251 auto draw = [&canvas](Paint& paint) {
252 for (auto cap : {Cap::kButt, Cap::kSquare, Cap::kRound}) {
253 paint.stroke_cap = cap;
254 Point origin = {100, 100};
255 Point p0 = {50, 0};
256 Point p1 = {150, 0};
257 canvas.DrawLine({150, 100}, {250, 100}, paint);
258 for (int d = 15; d < 90; d += 15) {
259 Matrix m = Matrix::MakeRotationZ(Degrees(d));
260 canvas.DrawLine(origin + m * p0, origin + m * p1, paint);
261 }
262 canvas.DrawLine({100, 150}, {100, 250}, paint);
263 canvas.DrawCircle({origin}, 35, paint);
264
265 canvas.DrawLine({250, 250}, {250, 250}, paint);
266
267 canvas.Translate({250, 0});
268 }
269 canvas.Translate({-750, 250});
270 };
271
272 std::vector<Color> colors = {
273 Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
274 Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
275 Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
276 Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
277 Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
278 Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
279 Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
280 std::vector<Scalar> stops = {
281 0.0,
282 (1.0 / 6.0) * 1,
283 (1.0 / 6.0) * 2,
284 (1.0 / 6.0) * 3,
285 (1.0 / 6.0) * 4,
286 (1.0 / 6.0) * 5,
287 1.0,
288 };
289
290 auto texture = CreateTextureForFixture("airplane.jpg",
291 /*enable_mipmapping=*/true);
292
293 draw(paint);
294
295 paint.color_source = ColorSource::MakeRadialGradient(
296 {100, 100}, 200, std::move(colors), std::move(stops),
297 Entity::TileMode::kMirror, {});
298 draw(paint);
299
300 paint.color_source = ColorSource::MakeImage(
301 texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
302 Matrix::MakeTranslation({-150, 75}));
303 draw(paint);
304
305 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
306 }
307
308 TEST_P(AiksTest, DrawRectStrokesRenderCorrectly) {
309 Canvas canvas;
310 Paint paint;
311 paint.color = Color::Red();
312 paint.style = Paint::Style::kStroke;
313 paint.stroke_width = 10;
314
315 canvas.Translate({100, 100});
316 canvas.DrawPath(
317 PathBuilder{}.AddRect(Rect::MakeSize(Size{100, 100})).TakePath(),
318 {paint});
319
320 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
321 }
322
323 TEST_P(AiksTest, DrawRectStrokesWithBevelJoinRenderCorrectly) {
324 Canvas canvas;
325 Paint paint;
326 paint.color = Color::Red();
327 paint.style = Paint::Style::kStroke;
328 paint.stroke_width = 10;
329 paint.stroke_join = Join::kBevel;
330
331 canvas.Translate({100, 100});
332 canvas.DrawPath(
333 PathBuilder{}.AddRect(Rect::MakeSize(Size{100, 100})).TakePath(),
334 {paint});
335
336 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
337 }
338
339 TEST_P(AiksTest, CanDrawMultiContourConvexPath) {
340 PathBuilder builder = {};
341 for (auto i = 0; i < 10; i++) {
342 if (i % 2 == 0) {
343 builder.AddCircle(Point(100 + 50 * i, 100 + 50 * i), 100);
344 } else {
345 builder.MoveTo({100.f + 50.f * i - 100, 100.f + 50.f * i});
346 builder.LineTo({100.f + 50.f * i, 100.f + 50.f * i - 100});
347 builder.LineTo({100.f + 50.f * i - 100, 100.f + 50.f * i - 100});
348 builder.Close();
349 }
350 }
351 builder.SetConvexity(Convexity::kConvex);
352
353 Canvas canvas;
354 canvas.DrawPath(builder.TakePath(), {.color = Color::Red().WithAlpha(0.4)});
355
356 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
357 }
358
359 TEST_P(AiksTest, ArcWithZeroSweepAndBlur) {
360 Canvas canvas;
361 canvas.Scale(GetContentScale());
362
363 Paint paint;
364 paint.color = Color::Red();
365 std::vector<Color> colors = {Color{1.0, 0.0, 0.0, 1.0},
366 Color{0.0, 0.0, 0.0, 1.0}};
367 std::vector<Scalar> stops = {0.0, 1.0};
368 paint.color_source = ColorSource::MakeSweepGradient(
369 {100, 100}, Degrees(45), Degrees(135), std::move(colors),
370 std::move(stops), Entity::TileMode::kMirror, {});
371 paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
372 .style = FilterContents::BlurStyle::kNormal,
373 .sigma = Sigma(20),
374 };
375
376 PathBuilder builder;
377 builder.AddArc(Rect::MakeXYWH(10, 10, 100, 100), Degrees(0), Degrees(0),
378 false);
379 canvas.DrawPath(builder.TakePath(), paint);
380
381 // Check that this empty picture can be created without crashing.
382 canvas.EndRecordingAsPicture();
383 }
384
385 TEST_P(AiksTest, CanRenderClips) {
386 Canvas canvas;
387 Paint paint;
388 paint.color = Color::Fuchsia();
389 canvas.ClipPath(
390 PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 500, 500)).TakePath());
391 canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).TakePath(), paint);
392 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
393 }
394
395 } // namespace testing
396 } // namespace impeller
impeller::Paint::stroke_cap
Cap stroke_cap
Definition: paint.h:56
impeller::Color::Blue
static constexpr Color Blue()
Definition: color.h:268
impeller::AiksPlayground
Definition: aiks_playground.h:17
impeller::Canvas::EndRecordingAsPicture
Picture EndRecordingAsPicture()
Definition: canvas.cc:657
impeller::Cap::kRound
@ kRound
impeller::Cap::kSquare
@ kSquare
impeller::AiksContext
Definition: aiks_context.h:20
impeller::Canvas::DrawPath
void DrawPath(Path path, const Paint &paint)
Definition: canvas.cc:250
impeller::Color::Red
static constexpr Color Red()
Definition: color.h:264
impeller::Path::Clone
Path Clone() const
Deeply clone this path and all data associated with it.
Definition: path.cc:76
impeller::Paint::Style::kStroke
@ kStroke
aiks_unittests.h
impeller::Paint
Definition: paint.h:22
impeller::FillType::kOdd
@ kOdd
impeller::TRect< Scalar >::MakeXYWH
constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition: rect.h:34
impeller::Color
Definition: color.h:124
impeller::Paint::color
Color color
Definition: paint.h:51
impeller::Canvas
Definition: canvas.h:48
impeller::PathBuilder
Definition: path_builder.h:14
impeller::Paint::MaskBlurDescriptor::style
FilterContents::BlurStyle style
Definition: paint.h:39
impeller::Vector2
Point Vector2
Definition: point.h:312
impeller::Paint::MaskBlurDescriptor
Definition: paint.h:38
impeller::ColorSource::MakeSweepGradient
static ColorSource MakeSweepGradient(Point center, Degrees start_angle, Degrees end_angle, std::vector< Color > colors, std::vector< Scalar > stops, Entity::TileMode tile_mode, Matrix effect_transform)
Definition: color_source.cc:138
impeller::PathBuilder::AddRoundedRect
PathBuilder & AddRoundedRect(Rect rect, RoundingRadii radii)
Definition: path_builder.cc:149
impeller::Color::Fuchsia
static constexpr Color Fuchsia()
Definition: color.h:458
impeller::ColorSource::MakeImage
static ColorSource MakeImage(std::shared_ptr< Texture > texture, Entity::TileMode x_tile_mode, Entity::TileMode y_tile_mode, SamplerDescriptor sampler_descriptor, Matrix effect_transform)
Definition: color_source.cc:163
impeller::FilterContents::BlurStyle::kNormal
@ kNormal
Blurred inside and outside.
impeller::PathBuilder::SetConvexity
PathBuilder & SetConvexity(Convexity value)
Definition: path_builder.cc:84
impeller::Cap::kButt
@ kButt
impeller::Entity::TileMode::kRepeat
@ kRepeat
impeller::Matrix::MakeTranslation
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95
impeller::Canvas::DrawLine
void DrawLine(const Point &p0, const Point &p1, const Paint &paint)
Definition: canvas.cc:310
impeller::Paint::color_source
ColorSource color_source
Definition: paint.h:52
impeller::Canvas::GetCurrentTransform
const Matrix & GetCurrentTransform() const
Definition: canvas.cc:205
impeller::PathBuilder::AddRect
PathBuilder & AddRect(Rect rect)
Definition: path_builder.cc:116
impeller::PathBuilder::RoundingRadii::bottom_right
Point bottom_right
Definition: path_builder.h:111
impeller::Join::kMiter
@ kMiter
impeller::Canvas::Concat
void Concat(const Matrix &transform)
Definition: canvas.cc:189
impeller::kPiOver2
constexpr float kPiOver2
Definition: constants.h:32
impeller::Canvas::DrawImage
void DrawImage(const std::shared_ptr< Image > &image, Point offset, const Paint &paint, SamplerDescriptor sampler={})
Definition: canvas.cc:612
impeller::Entity::TileMode::kMirror
@ kMirror
path_builder.h
impeller::PathBuilder::RoundingRadii
Definition: path_builder.h:107
impeller::TSize< Scalar >
impeller::Point
TPoint< Scalar > Point
Definition: point.h:308
impeller::Canvas::Scale
void Scale(const Vector2 &scale)
Definition: canvas.cc:222
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:55
impeller::ColorFilter::MakeBlend
static std::shared_ptr< ColorFilter > MakeBlend(BlendMode blend_mode, Color color)
Definition: color_filter.cc:23
widgets.h
impeller::Paint::style
Style style
Definition: paint.h:59
impeller::Color::WithAlpha
constexpr Color WithAlpha(Scalar new_alpha) const
Definition: color.h:270
impeller::Canvas::DrawCircle
void DrawCircle(const Point &center, Scalar radius, const Paint &paint)
Definition: canvas.cc:395
impeller::PathBuilder::LineTo
PathBuilder & LineTo(Point point, bool relative=false)
Insert a line from the current position to point.
Definition: path_builder.cc:51
impeller::Color::White
static constexpr Color White()
Definition: color.h:256
impeller::PathBuilder::AddCubicCurve
PathBuilder & AddCubicCurve(Point p1, Point cp1, Point cp2, Point p2)
Move to point p1, then insert a cubic curve from p1 to p2 with control points cp1 and cp2.
Definition: path_builder.cc:107
impeller::Sigma
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
Definition: sigma.h:32
impeller::PathBuilder::RoundingRadii::top_left
Point top_left
Definition: path_builder.h:108
impeller::Radians
Definition: scalar.h:38
impeller::PathBuilder::AddLine
PathBuilder & AddLine(const Point &p1, const Point &p2)
Move to point p1, then insert a line from p1 to p2.
Definition: path_builder.cc:370
canvas.h
impeller::PathBuilder::TakePath
Path TakePath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:21
impeller::Canvas::DrawPaint
void DrawPaint(const Paint &paint)
Definition: canvas.cc:260
impeller::Join::kRound
@ kRound
impeller::Matrix::Invert
Matrix Invert() const
Definition: matrix.cc:97
impeller::ColorSource::MakeRadialGradient
static ColorSource MakeRadialGradient(Point center, Scalar radius, std::vector< Color > colors, std::vector< Scalar > stops, Entity::TileMode tile_mode, Matrix effect_transform)
Definition: color_source.cc:108
impeller::Close
void Close(PathBuilder *builder)
Definition: tessellator.cc:36
impeller::Join::kBevel
@ kBevel
impeller::Matrix::MakeRotationZ
static Matrix MakeRotationZ(Radians r)
Definition: matrix.h:209
impeller::PathBuilder::Close
PathBuilder & Close()
Definition: path_builder.cc:44
impeller::LineTo
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:22
impeller::TRect< Scalar >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:44
impeller::PathBuilder::RoundingRadii::top_right
Point top_right
Definition: path_builder.h:110
impeller::TPoint< Scalar >
impeller::PathBuilder::MoveTo
PathBuilder & MoveTo(Point point, bool relative=false)
Definition: path_builder.cc:37
impeller::Color::Black
static constexpr Color Black()
Definition: color.h:258
impeller::PathBuilder::RoundingRadii::bottom_left
Point bottom_left
Definition: path_builder.h:109
impeller::BlendMode::kSourceIn
@ kSourceIn
impeller::Degrees
Definition: scalar.h:46
impeller::PathBuilder::AddCircle
PathBuilder & AddCircle(const Point &center, Scalar radius)
Definition: path_builder.cc:134
impeller::Color::AliceBlue
static constexpr Color AliceBlue()
Definition: color.h:274
impeller::TPoint::GetDistance
constexpr Type GetDistance(const TPoint &p) const
Definition: point.h:195
impeller::testing::TEST_P
TEST_P(AiksTest, CanRenderLinearGradientClamp)
Definition: aiks_gradient_unittests.cc:48
impeller::Convexity::kConvex
@ kConvex
impeller::Canvas::ClipPath
void ClipPath(Path path, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition: canvas.cc:419
IMPELLER_PLAYGROUND_LINE
#define IMPELLER_PLAYGROUND_LINE(default_position_a, default_position_b, radius, color_a, color_b)
Definition: widgets.h:56
impeller
Definition: aiks_context.cc:10
impeller::Paint::mask_blur_descriptor
std::optional< MaskBlurDescriptor > mask_blur_descriptor
Definition: paint.h:65
impeller::Paint::stroke_width
Scalar stroke_width
Definition: paint.h:55
impeller::TRect< Scalar >
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::PathBuilder::AddArc
PathBuilder & AddArc(const Rect &oval_bounds, Radians start, Radians sweep, bool use_center=false)
Definition: path_builder.cc:264
impeller::Paint::stroke_join
Join stroke_join
Definition: paint.h:57
impeller::Canvas::Translate
void Translate(const Vector3 &offset)
Definition: canvas.cc:218