Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions impeller/entity/geometry/geometry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,27 @@ namespace impeller {

/// Given a convex polyline, create a triangle fan structure.
std::pair<std::vector<Point>, std::vector<uint16_t>> TessellateConvex(
Path::Polyline polyline) {
const Path::Polyline& polyline) {
std::vector<Point> output;
std::vector<uint16_t> indices;

for (auto j = 0u; j < polyline.contours.size(); j++) {
const auto& points = polyline.points();

for (auto j = 0u; j < polyline.contours().size(); j++) {
auto [start, end] = polyline.GetContourPointBounds(j);
auto center = polyline.points[start];
auto center = points[start];

// Some polygons will not self close and an additional triangle
// must be inserted, others will self close and we need to avoid
// inserting an extra triangle.
if (polyline.points[end - 1] == polyline.points[start]) {
if (points[end - 1] == points[start]) {
end--;
}
output.emplace_back(center);
output.emplace_back(polyline.points[start + 1]);
output.emplace_back(points[start + 1]);

for (auto i = start + 2; i < end; i++) {
const auto& point_b = polyline.points[i];
const auto& point_b = points[i];
output.emplace_back(point_b);

indices.emplace_back(0);
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/geometry/geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ GeometryResult ComputeUVGeometryForRect(Rect source_rect,
/// @brief Given a polyline created from a convex filled path, perform a
/// tessellation.
std::pair<std::vector<Point>, std::vector<uint16_t>> TessellateConvex(
Path::Polyline polyline);
const Path::Polyline& polyline);

class Geometry {
public:
Expand Down
44 changes: 22 additions & 22 deletions impeller/entity/geometry/stroke_path_geometry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -237,29 +237,29 @@ StrokePathGeometry::CreateSolidStrokeVertices(
auto polyline = path.CreatePolyline(scale);

VS::PerVertexData vtx;
const auto& contours = polyline.contours();
const auto& points = polyline.points();

// Offset state.
Point offset;
Point previous_offset; // Used for computing joins.

auto compute_offset = [&polyline, &offset, &previous_offset,
auto compute_offset = [&points, &offset, &previous_offset,
&stroke_width](size_t point_i) {
previous_offset = offset;
Point direction =
(polyline.points[point_i] - polyline.points[point_i - 1]).Normalize();
Point direction = (points[point_i] - points[point_i - 1]).Normalize();
offset = Vector2{-direction.y, direction.x} * stroke_width * 0.5;
};

for (size_t contour_i = 0; contour_i < polyline.contours.size();
contour_i++) {
auto contour = polyline.contours[contour_i];
for (size_t contour_i = 0; contour_i < contours.size(); contour_i++) {
auto contour = contours[contour_i];
size_t contour_start_point_i, contour_end_point_i;
std::tie(contour_start_point_i, contour_end_point_i) =
polyline.GetContourPointBounds(contour_i);

switch (contour_end_point_i - contour_start_point_i) {
case 1: {
Point p = polyline.points[contour_start_point_i];
Point p = points[contour_start_point_i];
cap_proc(vtx_builder, p, {-stroke_width * 0.5f, 0}, scale, false);
cap_proc(vtx_builder, p, {stroke_width * 0.5f, 0}, scale, false);
continue;
Expand All @@ -282,60 +282,60 @@ StrokePathGeometry::CreateSolidStrokeVertices(
// vertices at the start of the new contour (thus connecting the two
// contours with two zero volume triangles, which will be discarded by
// the rasterizer).
vtx.position = polyline.points[contour_start_point_i - 1];
vtx.position = points[contour_start_point_i - 1];
// Append two vertices when "picking up" the pen so that the triangle
// drawn when moving to the beginning of the new contour will have zero
// volume.
vtx_builder.AppendVertex(vtx);
vtx_builder.AppendVertex(vtx);

vtx.position = polyline.points[contour_start_point_i];
vtx.position = points[contour_start_point_i];
// Append two vertices at the beginning of the new contour, which
// appends two triangles of zero area.
vtx_builder.AppendVertex(vtx);
vtx_builder.AppendVertex(vtx);
}

// Generate start cap.
if (!polyline.contours[contour_i].is_closed) {
if (!contours[contour_i].is_closed) {
auto cap_offset =
Vector2(-contour.start_direction.y, contour.start_direction.x) *
stroke_width * 0.5; // Counterclockwise normal
cap_proc(vtx_builder, polyline.points[contour_start_point_i], cap_offset,
scale, true);
cap_proc(vtx_builder, points[contour_start_point_i], cap_offset, scale,
true);
}

// Generate contour geometry.
for (size_t point_i = contour_start_point_i + 1;
point_i < contour_end_point_i; point_i++) {
// Generate line rect.
vtx.position = polyline.points[point_i - 1] + offset;
vtx.position = points[point_i - 1] + offset;
vtx_builder.AppendVertex(vtx);
vtx.position = polyline.points[point_i - 1] - offset;
vtx.position = points[point_i - 1] - offset;
vtx_builder.AppendVertex(vtx);
vtx.position = polyline.points[point_i] + offset;
vtx.position = points[point_i] + offset;
vtx_builder.AppendVertex(vtx);
vtx.position = polyline.points[point_i] - offset;
vtx.position = points[point_i] - offset;
vtx_builder.AppendVertex(vtx);

if (point_i < contour_end_point_i - 1) {
compute_offset(point_i + 1);

// Generate join from the current line to the next line.
join_proc(vtx_builder, polyline.points[point_i], previous_offset,
offset, scaled_miter_limit, scale);
join_proc(vtx_builder, points[point_i], previous_offset, offset,
scaled_miter_limit, scale);
}
}

// Generate end cap or join.
if (!polyline.contours[contour_i].is_closed) {
if (!contours[contour_i].is_closed) {
auto cap_offset =
Vector2(-contour.end_direction.y, contour.end_direction.x) *
stroke_width * 0.5; // Clockwise normal
cap_proc(vtx_builder, polyline.points[contour_end_point_i - 1],
cap_offset, scale, false);
cap_proc(vtx_builder, points[contour_end_point_i - 1], cap_offset, scale,
false);
} else {
join_proc(vtx_builder, polyline.points[contour_start_point_i], offset,
join_proc(vtx_builder, points[contour_start_point_i], offset,
contour_first_offset, scaled_miter_limit, scale);
}
}
Expand Down
2 changes: 1 addition & 1 deletion impeller/geometry/geometry_benchmarks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static void BM_Polyline(benchmark::State& state, Args&&... args) {
size_t single_point_count = 0u;
while (state.KeepRunning()) {
auto polyline = path.CreatePolyline(1.0f);
single_point_count = polyline.points.size();
single_point_count = polyline.points().size();
point_count += single_point_count;
if (tessellate) {
tess.Tessellate(
Expand Down
74 changes: 37 additions & 37 deletions impeller/geometry/geometry_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -600,8 +600,8 @@ TEST(GeometryTest, EmptyPath) {
ASSERT_POINT_NEAR(c.destination, Point());

Path::Polyline polyline = path.CreatePolyline(1.0f);
ASSERT_TRUE(polyline.points.empty());
ASSERT_TRUE(polyline.contours.empty());
ASSERT_TRUE(polyline.points().empty());
ASSERT_TRUE(polyline.contours().empty());
}

TEST(GeometryTest, SimplePath) {
Expand Down Expand Up @@ -2016,13 +2016,13 @@ TEST(GeometryTest, PathCreatePolyLineDoesNotDuplicatePoints) {

auto polyline = path.CreatePolyline(1.0f);

ASSERT_EQ(polyline.contours.size(), 2u);
ASSERT_EQ(polyline.points.size(), 5u);
ASSERT_EQ(polyline.points[0].x, 10);
ASSERT_EQ(polyline.points[1].x, 20);
ASSERT_EQ(polyline.points[2].x, 30);
ASSERT_EQ(polyline.points[3].x, 40);
ASSERT_EQ(polyline.points[4].x, 50);
ASSERT_EQ(polyline.contours().size(), 2u);
ASSERT_EQ(polyline.points().size(), 5u);
ASSERT_EQ(polyline.points()[0].x, 10);
ASSERT_EQ(polyline.points()[1].x, 20);
ASSERT_EQ(polyline.points()[2].x, 30);
ASSERT_EQ(polyline.points()[3].x, 40);
ASSERT_EQ(polyline.points()[4].x, 50);
}

TEST(GeometryTest, PathBuilderSetsCorrectContourPropertiesForAddCommands) {
Expand Down Expand Up @@ -2101,12 +2101,12 @@ TEST(GeometryTest, PathCreatePolylineGeneratesCorrectContourData) {
.Close()
.TakePath()
.CreatePolyline(1.0f);
ASSERT_EQ(polyline.points.size(), 6u);
ASSERT_EQ(polyline.contours.size(), 2u);
ASSERT_EQ(polyline.contours[0].is_closed, false);
ASSERT_EQ(polyline.contours[0].start_index, 0u);
ASSERT_EQ(polyline.contours[1].is_closed, true);
ASSERT_EQ(polyline.contours[1].start_index, 2u);
ASSERT_EQ(polyline.points().size(), 6u);
ASSERT_EQ(polyline.contours().size(), 2u);
ASSERT_EQ(polyline.contours()[0].is_closed, false);
ASSERT_EQ(polyline.contours()[0].start_index, 0u);
ASSERT_EQ(polyline.contours()[1].is_closed, true);
ASSERT_EQ(polyline.contours()[1].start_index, 2u);
}

TEST(GeometryTest, PolylineGetContourPointBoundsReturnsCorrectRanges) {
Expand All @@ -2132,15 +2132,15 @@ TEST(GeometryTest, PathAddRectPolylineHasCorrectContourData) {
.AddRect(Rect::MakeLTRB(50, 60, 70, 80))
.TakePath()
.CreatePolyline(1.0f);
ASSERT_EQ(polyline.contours.size(), 1u);
ASSERT_TRUE(polyline.contours[0].is_closed);
ASSERT_EQ(polyline.contours[0].start_index, 0u);
ASSERT_EQ(polyline.points.size(), 5u);
ASSERT_EQ(polyline.points[0], Point(50, 60));
ASSERT_EQ(polyline.points[1], Point(70, 60));
ASSERT_EQ(polyline.points[2], Point(70, 80));
ASSERT_EQ(polyline.points[3], Point(50, 80));
ASSERT_EQ(polyline.points[4], Point(50, 60));
ASSERT_EQ(polyline.contours().size(), 1u);
ASSERT_TRUE(polyline.contours()[0].is_closed);
ASSERT_EQ(polyline.contours()[0].start_index, 0u);
ASSERT_EQ(polyline.points().size(), 5u);
ASSERT_EQ(polyline.points()[0], Point(50, 60));
ASSERT_EQ(polyline.points()[1], Point(70, 60));
ASSERT_EQ(polyline.points()[2], Point(70, 80));
ASSERT_EQ(polyline.points()[3], Point(50, 80));
ASSERT_EQ(polyline.points()[4], Point(50, 60));
}

TEST(GeometryTest, PathPolylineDuplicatesAreRemovedForSameContour) {
Expand All @@ -2157,19 +2157,19 @@ TEST(GeometryTest, PathPolylineDuplicatesAreRemovedForSameContour) {
.LineTo({0, 100}) // Insert duplicate at end of contour.
.TakePath()
.CreatePolyline(1.0f);
ASSERT_EQ(polyline.contours.size(), 2u);
ASSERT_EQ(polyline.contours[0].start_index, 0u);
ASSERT_TRUE(polyline.contours[0].is_closed);
ASSERT_EQ(polyline.contours[1].start_index, 4u);
ASSERT_FALSE(polyline.contours[1].is_closed);
ASSERT_EQ(polyline.points.size(), 7u);
ASSERT_EQ(polyline.points[0], Point(50, 50));
ASSERT_EQ(polyline.points[1], Point(100, 50));
ASSERT_EQ(polyline.points[2], Point(100, 100));
ASSERT_EQ(polyline.points[3], Point(50, 50));
ASSERT_EQ(polyline.points[4], Point(50, 50));
ASSERT_EQ(polyline.points[5], Point(0, 50));
ASSERT_EQ(polyline.points[6], Point(0, 100));
ASSERT_EQ(polyline.contours().size(), 2u);
ASSERT_EQ(polyline.contours()[0].start_index, 0u);
ASSERT_TRUE(polyline.contours()[0].is_closed);
ASSERT_EQ(polyline.contours()[1].start_index, 4u);
ASSERT_FALSE(polyline.contours()[1].is_closed);
ASSERT_EQ(polyline.points().size(), 7u);
ASSERT_EQ(polyline.points()[0], Point(50, 50));
ASSERT_EQ(polyline.points()[1], Point(100, 50));
ASSERT_EQ(polyline.points()[2], Point(100, 100));
ASSERT_EQ(polyline.points()[3], Point(50, 50));
ASSERT_EQ(polyline.points()[4], Point(50, 50));
ASSERT_EQ(polyline.points()[5], Point(0, 50));
ASSERT_EQ(polyline.points()[6], Point(0, 100));
}

TEST(GeometryTest, MatrixPrinting) {
Expand Down
Loading