Flutter Impeller
round_rect.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 namespace impeller {
8 
10  const RoundingRadii& in_radii) {
11  if (!in_bounds.IsFinite()) {
12  return {};
13  }
14  Rect bounds = in_bounds.GetPositive();
15  // RoundingRadii::Scaled might return an empty radii if bounds or in_radii is
16  // empty, which is expected. Pass along the bounds even if the radii is empty
17  // as it would still have a valid location and/or 1-dimensional size which
18  // might appear when stroked
19  return RoundRect(bounds, in_radii.Scaled(bounds));
20 }
21 
22 // Determine if p is inside the elliptical corner curve defined by the
23 // indicated corner point and the indicated radii.
24 // p - is the test point in absolute coordinates
25 // corner - is the location of the associated corner in absolute coordinates
26 // direction - is the sign of (corner - center), or the sign of coordinates
27 // as they move in the direction of the corner from inside the
28 // rect ((-1,-1) for the upper left corner for instance)
29 // radii - the non-negative X and Y size of the corner's radii.
30 static bool CornerContains(const Point& p,
31  const Point& corner,
32  const Point& direction,
33  const Size& radii) {
34  FML_DCHECK(radii.width >= 0.0f && radii.height >= 0.0f);
35  if (radii.IsEmpty()) {
36  // This corner is not curved, therefore the containment is the same as
37  // the previously checked bounds containment.
38  return true;
39  }
40 
41  // The positive X,Y distance between the corner and the point.
42  Point corner_relative = (corner - p) * direction;
43 
44  // The distance from the "center" of the corner's elliptical curve.
45  // If both numbers are positive then we need to do an elliptical distance
46  // check to determine if it is inside the curve.
47  // If either number is negative, then the point is outside this quadrant
48  // and is governed by inclusion in the bounds and inclusion within other
49  // corners of this round rect. In that case, we return true here to allow
50  // further evaluation within other quadrants.
51  Point quadrant_relative = radii - corner_relative;
52  if (quadrant_relative.x <= 0.0f || quadrant_relative.y <= 0.0f) {
53  // Not within the curved quadrant of this corner, therefore "inside"
54  // relative to this one corner.
55  return true;
56  }
57 
58  // Dividing the quadrant_relative point by the radii gives a corresponding
59  // location within a unit circle which can be more easily tested for
60  // containment. We can use x^2 + y^2 and compare it against the radius
61  // squared (1.0) to avoid the sqrt.
62  Point quadrant_unit_circle_point = quadrant_relative / radii;
63  return quadrant_unit_circle_point.GetLengthSquared() <= 1.0;
64 }
65 
66 // The sign of the direction that points move as they approach the indicated
67 // corner from within the rectangle.
68 static constexpr Point kUpperLeftDirection(-1.0f, -1.0f);
69 static constexpr Point kUpperRightDirection(1.0f, -1.0f);
70 static constexpr Point kLowerLeftDirection(-1.0f, 1.0f);
71 static constexpr Point kLowerRightDirection(1.0f, 1.0f);
72 
73 [[nodiscard]] bool RoundRect::Contains(const Point& p) const {
74  if (!bounds_.Contains(p)) {
75  return false;
76  }
78  radii_.top_left) ||
80  radii_.top_right) ||
82  radii_.bottom_left) ||
84  radii_.bottom_right)) {
85  return false;
86  }
87  return true;
88 }
89 
90 } // namespace impeller
static bool CornerContains(const Point &p, const Point &corner, const Point &direction, const Size &radii)
Definition: round_rect.cc:30
static constexpr Point kUpperLeftDirection(-1.0f, -1.0f)
static constexpr Point kLowerRightDirection(1.0f, 1.0f)
static constexpr Point kUpperRightDirection(1.0f, -1.0f)
static constexpr Point kLowerLeftDirection(-1.0f, 1.0f)
static RoundRect MakeRectRadii(const Rect &rect, const RoundingRadii &radii)
Definition: round_rect.cc:9
bool Contains(const Point &p) const
Returns true iff the provided point |p| is inside the half-open interior of this rectangle.
Definition: round_rect.cc:73
RoundingRadii Scaled(const Rect &bounds) const
Returns a scaled copy of this object, ensuring that the sum of the corner radii on each side does not...
constexpr Type GetLengthSquared() const
Definition: point.h:204
constexpr bool Contains(const TPoint< Type > &p) const
Returns true iff the provided point |p| is inside the half-open interior of this rectangle.
Definition: rect.h:235
constexpr TRect GetPositive() const
Get a version of this rectangle that has a non-negative size.
Definition: rect.h:402
IsFinite() const
Returns true if all of the fields of this floating point rectangle are finite.
Definition: rect.h:292
constexpr TPoint< T > GetLeftBottom() const
Definition: rect.h:371
constexpr TPoint< T > GetRightTop() const
Definition: rect.h:367
constexpr TPoint< T > GetRightBottom() const
Definition: rect.h:375
constexpr TPoint< T > GetLeftTop() const
Definition: rect.h:363
Type height
Definition: size.h:29
Type width
Definition: size.h:28
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
Definition: size.h:123