| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "flutter/impeller/geometry/round_superellipse.h" |
| |
| #include "flutter/impeller/geometry/round_rect.h" |
| #include "flutter/impeller/geometry/round_superellipse_param.h" |
| |
| namespace impeller { |
| |
| RoundSuperellipse RoundSuperellipse::MakeRectRadii( |
| const Rect& in_bounds, |
| const RoundingRadii& in_radii) { |
| if (!in_bounds.IsFinite()) { |
| return {}; |
| } |
| Rect bounds = in_bounds.GetPositive(); |
| // RoundingRadii::Scaled might return an empty radii if bounds or in_radii is |
| // empty, which is expected. Pass along the bounds even if the radii is empty |
| // as it would still have a valid location and/or 1-dimensional size which |
| // might appear when stroked |
| return RoundSuperellipse(bounds, in_radii.Scaled(bounds)); |
| } |
| |
| [[nodiscard]] bool RoundSuperellipse::Contains(const Point& p) const { |
| if (!bounds_.Contains(p)) { |
| return false; |
| } |
| auto param = RoundSuperellipseParam::MakeBoundsRadii(bounds_, radii_); |
| return param.Contains(p); |
| } |
| |
| RoundRect RoundSuperellipse::ToApproximateRoundRect() const { |
| // Experiments have shown that using the same corner radii for the RRect |
| // provides an approximation that is close to optimal, as achieving a perfect |
| // match is not feasible. |
| return RoundRect::MakeRectRadii(GetBounds(), GetRadii()); |
| } |
| |
| RoundSuperellipsePathSource::RoundSuperellipsePathSource( |
| const RoundSuperellipse& round_superellipse) |
| : round_superellipse_(round_superellipse) {} |
| |
| RoundSuperellipsePathSource::~RoundSuperellipsePathSource() = default; |
| |
| FillType RoundSuperellipsePathSource::GetFillType() const { |
| return FillType::kNonZero; |
| } |
| |
| Rect RoundSuperellipsePathSource::GetBounds() const { |
| return round_superellipse_.GetBounds(); |
| } |
| |
| bool RoundSuperellipsePathSource::IsConvex() const { |
| return true; |
| } |
| |
| void RoundSuperellipsePathSource::Dispatch(PathReceiver& receiver) const { |
| auto param = RoundSuperellipseParam::MakeBoundsRadii( |
| round_superellipse_.GetBounds(), round_superellipse_.GetRadii()); |
| param.Dispatch(receiver); |
| } |
| |
| } // namespace impeller |