Added special case for fat width arcs (#161255)

fixes https://github.com/flutter/flutter/issues/158567

This draws arcs as oval sectors when the stroke width is large enough.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] 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/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
gaaclarke 2025-01-14 08:55:30 -08:00 committed by GitHub
parent 836fd6e567
commit e683e1031c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 62 additions and 4 deletions

View File

@ -461,6 +461,45 @@ TEST_P(AiksTest, CanRenderClips) {
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
TEST_P(AiksTest, FatStrokeArc) {
DlScalar stroke_width = 300;
DlScalar aspect = 1.0;
DlScalar start_angle = 0;
DlScalar end_angle = 90;
auto callback = [&]() -> sk_sp<DisplayList> {
if (AiksTest::ImGuiBegin("Controls", nullptr,
ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::SliderFloat("Stroke Width", &stroke_width, 1, 300);
ImGui::SliderFloat("Aspect", &aspect, 0.5, 2.0);
ImGui::SliderFloat("Start Angle", &start_angle, 0, 360);
ImGui::SliderFloat("End Angle", &end_angle, 0, 360);
ImGui::End();
}
DisplayListBuilder builder;
DlPaint grey_paint;
grey_paint.setColor(DlColor(0xff111111));
builder.DrawPaint(grey_paint);
DlPaint white_paint;
white_paint.setColor(DlColor::kWhite());
white_paint.setStrokeWidth(stroke_width);
white_paint.setDrawStyle(DlDrawStyle::kStroke);
DlPaint red_paint;
red_paint.setColor(DlColor::kRed());
Rect rect = Rect::MakeXYWH(100, 100, 100, aspect * 100);
builder.DrawRect(rect, red_paint);
builder.DrawArc(rect, start_angle, end_angle,
/*useCenter=*/false, white_paint);
DlScalar frontier = rect.GetRight() + stroke_width / 2.0;
builder.DrawLine(Point(frontier, 0), Point(frontier, 150), red_paint);
return builder.Build();
};
ASSERT_TRUE(OpenPlaygroundHere(callback));
}
TEST_P(AiksTest, CanRenderOverlappingMultiContourPath) {
DisplayListBuilder builder;

View File

@ -642,10 +642,26 @@ void DlDispatcherBase::drawArc(const DlRect& oval_bounds,
bool use_center) {
AUTO_DEPTH_WATCHER(1u);
PathBuilder builder;
builder.AddArc(oval_bounds, Degrees(start_degrees), Degrees(sweep_degrees),
use_center);
GetCanvas().DrawPath(builder.TakePath(), paint_);
if (paint_.stroke_width >
std::max(oval_bounds.GetWidth(), oval_bounds.GetHeight())) {
// This is a special case for rendering arcs whose stroke width is so large
// you are effectively drawing a sector of a circle.
// https://github.com/flutter/flutter/issues/158567
DlRect expanded_rect = oval_bounds.Expand(Size(paint_.stroke_width / 2));
PathBuilder builder;
Paint fill_paint = paint_;
fill_paint.style = Paint::Style::kFill;
fill_paint.stroke_width = 1;
builder.AddArc(expanded_rect, Degrees(start_degrees),
Degrees(sweep_degrees),
/*use_center=*/true);
GetCanvas().DrawPath(builder.TakePath(), fill_paint);
} else {
PathBuilder builder;
builder.AddArc(oval_bounds, Degrees(start_degrees), Degrees(sweep_degrees),
use_center);
GetCanvas().DrawPath(builder.TakePath(), paint_);
}
}
// |flutter::DlOpReceiver|

View File

@ -690,6 +690,9 @@ impeller_Play_AiksTest_FastGradientTestVerticalReversed_Vulkan.png
impeller_Play_AiksTest_FastGradientTestVertical_Metal.png
impeller_Play_AiksTest_FastGradientTestVertical_OpenGLES.png
impeller_Play_AiksTest_FastGradientTestVertical_Vulkan.png
impeller_Play_AiksTest_FatStrokeArc_Metal.png
impeller_Play_AiksTest_FatStrokeArc_OpenGLES.png
impeller_Play_AiksTest_FatStrokeArc_Vulkan.png
impeller_Play_AiksTest_FilledCirclesRenderCorrectly_Metal.png
impeller_Play_AiksTest_FilledCirclesRenderCorrectly_OpenGLES.png
impeller_Play_AiksTest_FilledCirclesRenderCorrectly_Vulkan.png