Skip to content

Commit f83a021

Browse files
chinmaygardednfield
authored andcommitted
Support path fill types.
1 parent 10487e3 commit f83a021

File tree

13 files changed

+109
-72
lines changed

13 files changed

+109
-72
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ TEST_F(AiksTest, CanRenderColoredRect) {
4545
paint.color = Color::Red();
4646
canvas.DrawPath(PathBuilder{}
4747
.AddRect(Rect::MakeXYWH(100.0, 100.0, 100.0, 100.0))
48-
.CreatePath(),
48+
.TakePath(),
4949
paint);
5050
// ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
5151
}
@@ -81,7 +81,7 @@ TEST_F(AiksTest, CanRenderStrokes) {
8181
paint.color = Color::Red();
8282
paint.stroke_width = 20.0;
8383
paint.style = Paint::Style::kStroke;
84-
canvas.DrawPath(PathBuilder{}.AddLine({200, 100}, {800, 100}).CreatePath(),
84+
canvas.DrawPath(PathBuilder{}.AddLine({200, 100}, {800, 100}).TakePath(),
8585
paint);
8686
// ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
8787
}
@@ -92,7 +92,7 @@ TEST_F(AiksTest, CanRenderCurvedStrokes) {
9292
paint.color = Color::Red();
9393
paint.stroke_width = 25.0;
9494
paint.style = Paint::Style::kStroke;
95-
canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).CreatePath(), paint);
95+
canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).TakePath(), paint);
9696
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
9797
}
9898

@@ -101,8 +101,8 @@ TEST_F(AiksTest, CanRenderClips) {
101101
Paint paint;
102102
paint.color = Color::Fuchsia();
103103
canvas.ClipPath(
104-
PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 500, 500)).CreatePath());
105-
canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).CreatePath(), paint);
104+
PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 500, 500)).TakePath());
105+
canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).TakePath(), paint);
106106
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
107107
}
108108

@@ -236,14 +236,39 @@ TEST_F(AiksTest, CanRenderRoundedRectWithNonUniformRadii) {
236236
radii.bottom_right = {50, 25};
237237
radii.bottom_left = {25, 50};
238238

239-
auto path = PathBuilder{}
240-
.AddRoundedRect(Rect{100, 100, 500, 500}, radii)
241-
.CreatePath();
239+
auto path =
240+
PathBuilder{}.AddRoundedRect(Rect{100, 100, 500, 500}, radii).TakePath();
242241

243242
canvas.DrawPath(path, paint);
244243

245244
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
246245
}
247246

247+
TEST_F(AiksTest, CanRenderDifferencePaths) {
248+
Canvas canvas;
249+
250+
Paint paint;
251+
paint.color = Color::Red();
252+
253+
PathBuilder builder;
254+
255+
PathBuilder::RoundingRadii radii;
256+
radii.top_left = {50, 25};
257+
radii.top_right = {25, 50};
258+
radii.bottom_right = {50, 25};
259+
radii.bottom_left = {25, 50};
260+
261+
builder.AddRoundedRect({100, 100, 200, 200}, radii);
262+
builder.AddCircle({200, 200}, 50);
263+
auto path = builder.TakePath(FillType::kOdd);
264+
265+
canvas.DrawImage(
266+
std::make_shared<Image>(CreateTextureForFixture("boston.jpg")), {10, 10},
267+
Paint{});
268+
canvas.DrawPath(std::move(path), paint);
269+
270+
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
271+
}
272+
248273
} // namespace testing
249274
} // namespace impeller

impeller/aiks/canvas.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,11 @@ void Canvas::DrawPath(Path path, Paint paint) {
100100
}
101101

102102
void Canvas::DrawRect(Rect rect, Paint paint) {
103-
DrawPath(PathBuilder{}.AddRect(rect).CreatePath(), std::move(paint));
103+
DrawPath(PathBuilder{}.AddRect(rect).TakePath(), std::move(paint));
104104
}
105105

106106
void Canvas::DrawCircle(Point center, Scalar radius, Paint paint) {
107-
DrawPath(PathBuilder{}.AddCircle(center, radius).CreatePath(),
107+
DrawPath(PathBuilder{}.AddCircle(center, radius).TakePath(),
108108
std::move(paint));
109109
}
110110

@@ -120,7 +120,7 @@ void Canvas::SaveLayer(Paint paint, std::optional<Rect> bounds) {
120120
// the size of the render target that would have been allocated will be
121121
// absent. Explicitly add back a clip to reproduce that behavior. Since
122122
// clips never require a render target switch, this is a cheap operation.
123-
ClipPath(PathBuilder{}.AddRect(bounds.value()).CreatePath());
123+
ClipPath(PathBuilder{}.AddRect(bounds.value()).TakePath());
124124
}
125125
}
126126

@@ -187,7 +187,7 @@ void Canvas::DrawImageRect(std::shared_ptr<Image> image,
187187
contents->SetSourceRect(source);
188188

189189
Entity entity;
190-
entity.SetPath(PathBuilder{}.AddRect(dest).CreatePath());
190+
entity.SetPath(PathBuilder{}.AddRect(dest).TakePath());
191191
entity.SetContents(contents);
192192
entity.SetTransformation(GetCurrentTransformation());
193193

impeller/display_list/display_list_impeller.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ static Rect ToRect(const SkRect& rect) {
213213
void DisplayListImpeller::clipRect(const SkRect& rect,
214214
SkClipOp clip_op,
215215
bool is_aa) {
216-
auto path = PathBuilder{}.AddRect(ToRect(rect)).CreatePath();
216+
auto path = PathBuilder{}.AddRect(ToRect(rect)).TakePath();
217217
canvas_.ClipPath(std::move(path));
218218
}
219219

@@ -238,7 +238,7 @@ void DisplayListImpeller::clipRRect(const SkRRect& rrect,
238238
auto path =
239239
PathBuilder{}
240240
.AddRoundedRect(ToRect(rrect.getBounds()), ToRoundingRadii(rrect))
241-
.CreatePath();
241+
.TakePath();
242242
canvas_.ClipPath(std::move(path));
243243
}
244244

@@ -266,25 +266,25 @@ void DisplayListImpeller::drawPaint() {
266266

267267
// |flutter::Dispatcher|
268268
void DisplayListImpeller::drawLine(const SkPoint& p0, const SkPoint& p1) {
269-
auto path = PathBuilder{}.AddLine(ToPoint(p0), ToPoint(p1)).CreatePath();
269+
auto path = PathBuilder{}.AddLine(ToPoint(p0), ToPoint(p1)).TakePath();
270270
canvas_.DrawPath(std::move(path), paint_);
271271
}
272272

273273
// |flutter::Dispatcher|
274274
void DisplayListImpeller::drawRect(const SkRect& rect) {
275-
auto path = PathBuilder{}.AddRect(ToRect(rect)).CreatePath();
275+
auto path = PathBuilder{}.AddRect(ToRect(rect)).TakePath();
276276
canvas_.DrawPath(std::move(path), paint_);
277277
}
278278

279279
// |flutter::Dispatcher|
280280
void DisplayListImpeller::drawOval(const SkRect& bounds) {
281-
auto path = PathBuilder{}.AddOval(ToRect(bounds)).CreatePath();
281+
auto path = PathBuilder{}.AddOval(ToRect(bounds)).TakePath();
282282
canvas_.DrawPath(std::move(path), paint_);
283283
}
284284

285285
// |flutter::Dispatcher|
286286
void DisplayListImpeller::drawCircle(const SkPoint& center, SkScalar radius) {
287-
auto path = PathBuilder{}.AddCircle(ToPoint(center), radius).CreatePath();
287+
auto path = PathBuilder{}.AddCircle(ToPoint(center), radius).TakePath();
288288
canvas_.DrawPath(std::move(path), paint_);
289289
}
290290

@@ -293,7 +293,7 @@ void DisplayListImpeller::drawRRect(const SkRRect& rrect) {
293293
auto path =
294294
PathBuilder{}
295295
.AddRoundedRect(ToRect(rrect.getBounds()), ToRoundingRadii(rrect))
296-
.CreatePath();
296+
.TakePath();
297297
canvas_.DrawPath(std::move(path), paint_);
298298
}
299299

impeller/entity/contents.cc

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ bool LinearGradientContents::Render(const ContentRenderer& renderer,
6868

6969
auto vertices_builder = VertexBufferBuilder<VS::PerVertexData>();
7070
{
71-
auto result = Tessellator{}.Tessellate(entity.GetPath().CreatePolyline(),
72-
[&vertices_builder](Point point) {
73-
VS::PerVertexData vtx;
74-
vtx.vertices = point;
75-
vertices_builder.AppendVertex(vtx);
76-
});
71+
auto result = Tessellator{entity.GetPath().GetFillType()}.Tessellate(
72+
entity.GetPath().CreatePolyline(), [&vertices_builder](Point point) {
73+
VS::PerVertexData vtx;
74+
vtx.vertices = point;
75+
vertices_builder.AppendVertex(vtx);
76+
});
7777
if (!result) {
7878
return false;
7979
}
@@ -124,7 +124,7 @@ static VertexBuffer CreateSolidFillVertices(const Path& path,
124124

125125
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
126126

127-
auto tesselation_result = Tessellator{}.Tessellate(
127+
auto tesselation_result = Tessellator{path.GetFillType()}.Tessellate(
128128
path.CreatePolyline(), [&vtx_builder](auto point) {
129129
VS::PerVertexData vtx;
130130
vtx.vertices = point;
@@ -225,15 +225,16 @@ bool TextureContents::Render(const ContentRenderer& renderer,
225225

226226
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
227227
{
228-
const auto tess_result = Tessellator{}.Tessellate(
229-
entity.GetPath().CreatePolyline(),
230-
[&vertex_builder, &coverage_rect](Point vtx) {
231-
VS::PerVertexData data;
232-
data.vertices = vtx;
233-
data.texture_coords =
234-
((vtx - coverage_rect->origin) / coverage_rect->size);
235-
vertex_builder.AppendVertex(data);
236-
});
228+
const auto tess_result =
229+
Tessellator{entity.GetPath().GetFillType()}.Tessellate(
230+
entity.GetPath().CreatePolyline(),
231+
[&vertex_builder, &coverage_rect](Point vtx) {
232+
VS::PerVertexData data;
233+
data.vertices = vtx;
234+
data.texture_coords =
235+
((vtx - coverage_rect->origin) / coverage_rect->size);
236+
vertex_builder.AppendVertex(data);
237+
});
237238
if (!tess_result) {
238239
return false;
239240
}

impeller/entity/entity_pass.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,7 @@ bool EntityPass::Render(ContentRenderer& renderer,
184184
}
185185

186186
Entity entity;
187-
entity.SetPath(
188-
PathBuilder{}.AddRect(subpass_coverage.value()).CreatePath());
187+
entity.SetPath(PathBuilder{}.AddRect(subpass_coverage.value()).TakePath());
189188
entity.SetContents(std::move(offscreen_texture_contents));
190189
entity.SetStencilDepth(stencil_depth_);
191190
entity.SetTransformation(xformation_);

impeller/entity/entity_unittests.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ TEST_F(EntityTest, CanCreateEntity) {
2020

2121
TEST_F(EntityTest, CanDrawRect) {
2222
Entity entity;
23-
entity.SetPath(PathBuilder{}.AddRect({100, 100, 100, 100}).CreatePath());
23+
entity.SetPath(PathBuilder{}.AddRect({100, 100, 100, 100}).TakePath());
2424
entity.SetContents(SolidColorContents::Make(Color::Red()));
2525
// ASSERT_TRUE(OpenPlaygroundHere(entity));
2626
}

impeller/geometry/geometry_unittests.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ TEST(GeometryTest, BoundingBoxCubic) {
192192
TEST(GeometryTest, BoundingBoxOfCompositePathIsCorrect) {
193193
PathBuilder builder;
194194
builder.AddRoundedRect({{10, 10}, {300, 300}}, {50, 50, 50, 50});
195-
auto path = builder.CreatePath();
195+
auto path = builder.TakePath();
196196
auto actual = path.GetBoundingBox();
197197
Rect expected(10, 10, 300, 300);
198198
ASSERT_TRUE(actual.has_value());

impeller/geometry/path.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ size_t Path::GetComponentCount() const {
1616
return components_.size();
1717
}
1818

19+
void Path::SetFillType(FillType fill) {
20+
fill_ = fill;
21+
}
22+
23+
FillType Path::GetFillType() const {
24+
return fill_;
25+
}
26+
1927
Path& Path::AddLinearComponent(Point p1, Point p2) {
2028
linears_.emplace_back(p1, p2);
2129
components_.emplace_back(ComponentType::kLinear, linears_.size() - 1);

impeller/geometry/path.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@
1212

1313
namespace impeller {
1414

15+
enum class FillType {
16+
kNonZero, // The default winding order.
17+
kOdd,
18+
kPositive,
19+
kNegative,
20+
kAbsGeqTwo,
21+
};
22+
1523
//------------------------------------------------------------------------------
1624
/// @brief Paths are lightweight objects that describe a collection of
1725
/// linear, quadratic, or cubic segments.
@@ -36,6 +44,10 @@ class Path {
3644

3745
size_t GetComponentCount() const;
3846

47+
void SetFillType(FillType fill);
48+
49+
FillType GetFillType() const;
50+
3951
Path& AddLinearComponent(Point p1, Point p2);
4052

4153
Path& AddQuadraticComponent(Point p1, Point cp, Point p2);
@@ -82,6 +94,7 @@ class Path {
8294
: type(aType), index(aIndex) {}
8395
};
8496

97+
FillType fill_ = FillType::kNonZero;
8598
std::vector<ComponentIndexPair> components_;
8699
std::vector<LinearPathComponent> linears_;
87100
std::vector<QuadraticPathComponent> quads_;

impeller/geometry/path_builder.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,16 @@ PathBuilder::PathBuilder() = default;
1212

1313
PathBuilder::~PathBuilder() = default;
1414

15-
Path PathBuilder::CreatePath() const {
16-
return prototype_;
15+
Path PathBuilder::CopyPath(FillType fill) const {
16+
auto path = prototype_;
17+
path.SetFillType(fill);
18+
return path;
19+
}
20+
21+
Path PathBuilder::TakePath(FillType fill) {
22+
auto path = std::move(prototype_);
23+
path.SetFillType(fill);
24+
return path;
1725
}
1826

1927
PathBuilder& PathBuilder::MoveTo(Point point, bool relative) {

0 commit comments

Comments
 (0)