Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 7f464aa

Browse files
authored
[Impeller] Add rounded superellipse (#56726)
Support rounded superellipse. Part of flutter/flutter#139321 and flutter/flutter#13914, also related to flutter/flutter#91523. ### Open questions * Alternative names: * Round**ed**Superellipse * Squircle * ContinuousBorderRectangle (or something like this...) * I chose rounded superellipse because this name, albeit its length, precisely describe this shape. "Squircle" is not strictly defined but generally refers any shape intermediate between a rectangle and a circle. * Alternative definition for `corner_radius`: * Currently the `corner_radius` corresponds to SwiftUI parameters. To make the shape definition more generalized, we can instead define the `corner_radius` to be the radius of the corner circles, and make the framework do a look up table. * The down side is, not only the work to re-calculate the table, but also that it doesn't completely eliminates the relationship with SwiftUI, since currently the degree of the superellipse (`n`) is also mapped from the SwiftUI `cornerRadius`, which is not necessary for the shape per se. * To some extent it boils down to the question of whether we'd like this shape to support anything beyond SwiftUI. ### Demo https://github.com/user-attachments/assets/806ac0e9-d62f-4b04-ab6a-83436a11f6f3 Low ratio: (900, 900, 445) <img width="520" alt="image" src="https://github.com/user-attachments/assets/54087467-85cd-4021-91cc-a948866ab5a8"> Mid ratio: (900, 650, 180) <img width="508" alt="image" src="https://github.com/user-attachments/assets/460a4927-0396-462b-948d-0846a781c92c"> High ratio: (900, 650, 17) <img width="490" alt="image" src="https://github.com/user-attachments/assets/8d7f625d-8a3b-4aba-b3f9-f292b874b606"> ## Pre-launch Checklist - [ ] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [ ] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [ ] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I added new tests to check the change I am making or feature I am adding, or the PR is [test-exempt]. See [testing the engine] for instructions on writing and running engine tests. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I signed the [CLA]. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [test-exempt]: https://github.com/flutter/flutter/wiki/Tree-hygiene#tests [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style [testing the engine]: https://github.com/flutter/flutter/wiki/Testing-the-engine [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat
1 parent 3a8204a commit 7f464aa

File tree

6 files changed

+530
-0
lines changed

6 files changed

+530
-0
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43161,6 +43161,8 @@ ORIGIN: ../../../flutter/impeller/entity/geometry/rect_geometry.cc + ../../../fl
4316143161
ORIGIN: ../../../flutter/impeller/entity/geometry/rect_geometry.h + ../../../flutter/LICENSE
4316243162
ORIGIN: ../../../flutter/impeller/entity/geometry/round_rect_geometry.cc + ../../../flutter/LICENSE
4316343163
ORIGIN: ../../../flutter/impeller/entity/geometry/round_rect_geometry.h + ../../../flutter/LICENSE
43164+
ORIGIN: ../../../flutter/impeller/entity/geometry/round_superellipse_geometry.cc + ../../../flutter/LICENSE
43165+
ORIGIN: ../../../flutter/impeller/entity/geometry/round_superellipse_geometry.h + ../../../flutter/LICENSE
4316443166
ORIGIN: ../../../flutter/impeller/entity/geometry/stroke_path_geometry.cc + ../../../flutter/LICENSE
4316543167
ORIGIN: ../../../flutter/impeller/entity/geometry/stroke_path_geometry.h + ../../../flutter/LICENSE
4316643168
ORIGIN: ../../../flutter/impeller/entity/geometry/superellipse_geometry.cc + ../../../flutter/LICENSE
@@ -46088,6 +46090,8 @@ FILE: ../../../flutter/impeller/entity/geometry/rect_geometry.cc
4608846090
FILE: ../../../flutter/impeller/entity/geometry/rect_geometry.h
4608946091
FILE: ../../../flutter/impeller/entity/geometry/round_rect_geometry.cc
4609046092
FILE: ../../../flutter/impeller/entity/geometry/round_rect_geometry.h
46093+
FILE: ../../../flutter/impeller/entity/geometry/round_superellipse_geometry.cc
46094+
FILE: ../../../flutter/impeller/entity/geometry/round_superellipse_geometry.h
4609146095
FILE: ../../../flutter/impeller/entity/geometry/stroke_path_geometry.cc
4609246096
FILE: ../../../flutter/impeller/entity/geometry/stroke_path_geometry.h
4609346097
FILE: ../../../flutter/impeller/entity/geometry/superellipse_geometry.cc

impeller/display_list/canvas.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "impeller/entity/geometry/point_field_geometry.h"
3838
#include "impeller/entity/geometry/rect_geometry.h"
3939
#include "impeller/entity/geometry/round_rect_geometry.h"
40+
#include "impeller/entity/geometry/round_superellipse_geometry.h"
4041
#include "impeller/entity/geometry/stroke_path_geometry.h"
4142
#include "impeller/entity/save_layer_utils.h"
4243
#include "impeller/geometry/color.h"

impeller/entity/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ impeller_component("entity") {
199199
"geometry/rect_geometry.h",
200200
"geometry/round_rect_geometry.cc",
201201
"geometry/round_rect_geometry.h",
202+
"geometry/round_superellipse_geometry.cc",
203+
"geometry/round_superellipse_geometry.h",
202204
"geometry/stroke_path_geometry.cc",
203205
"geometry/stroke_path_geometry.h",
204206
"geometry/superellipse_geometry.cc",

impeller/entity/entity_unittests.cc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "impeller/entity/entity_playground.h"
3838
#include "impeller/entity/geometry/geometry.h"
3939
#include "impeller/entity/geometry/point_field_geometry.h"
40+
#include "impeller/entity/geometry/round_superellipse_geometry.h"
4041
#include "impeller/entity/geometry/stroke_path_geometry.h"
4142
#include "impeller/entity/geometry/superellipse_geometry.h"
4243
#include "impeller/geometry/color.h"
@@ -2321,6 +2322,41 @@ TEST_P(EntityTest, DrawSuperEllipse) {
23212322
ASSERT_TRUE(OpenPlaygroundHere(callback));
23222323
}
23232324

2325+
TEST_P(EntityTest, DrawRoundSuperEllipse) {
2326+
auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2327+
// UI state.
2328+
static float center_x = 100;
2329+
static float center_y = 100;
2330+
static float width = 900;
2331+
static float height = 900;
2332+
static float corner_radius = 300;
2333+
static Color color = Color::Red();
2334+
2335+
ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
2336+
ImGui::SliderFloat("Center X", &center_x, 0, 1000);
2337+
ImGui::SliderFloat("Center Y", &center_y, 0, 1000);
2338+
ImGui::SliderFloat("Width", &width, 0, 1000);
2339+
ImGui::SliderFloat("Height", &height, 0, 1000);
2340+
ImGui::SliderFloat("Corner radius", &corner_radius, 0, 500);
2341+
ImGui::End();
2342+
2343+
auto contents = std::make_shared<SolidColorContents>();
2344+
std::unique_ptr<RoundSuperellipseGeometry> geom =
2345+
std::make_unique<RoundSuperellipseGeometry>(
2346+
Rect::MakeOriginSize({center_x, center_y}, {width, height}),
2347+
corner_radius);
2348+
contents->SetColor(color);
2349+
contents->SetGeometry(geom.get());
2350+
2351+
Entity entity;
2352+
entity.SetContents(contents);
2353+
2354+
return entity.Render(context, pass);
2355+
};
2356+
2357+
ASSERT_TRUE(OpenPlaygroundHere(callback));
2358+
}
2359+
23242360
TEST_P(EntityTest, SolidColorApplyColorFilter) {
23252361
auto contents = SolidColorContents();
23262362
contents.SetColor(Color::CornflowerBlue().WithAlpha(0.75));

0 commit comments

Comments
 (0)