File: rrect_f.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (210 lines) | stat: -rw-r--r-- 7,929 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_GFX_GEOMETRY_RRECT_F_H_
#define UI_GFX_GEOMETRY_RRECT_F_H_

#include <memory>
#include <string>

#include "base/component_export.h"
#include "third_party/skia/include/core/SkRRect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/rounded_corners_f.h"
#include "ui/gfx/geometry/skia_conversions.h"

namespace gfx {

class COMPONENT_EXPORT(GEOMETRY_SKIA) RRectF {
 public:
  RRectF() = default;
  ~RRectF() = default;
  RRectF(const RRectF& rect) = default;
  RRectF& operator=(const RRectF& rect) = default;
  explicit RRectF(const SkRRect& rect) : skrrect_(rect) {}
  explicit RRectF(const gfx::RectF& rect) : RRectF(rect, 0.f) {}
  RRectF(const gfx::RectF& rect, float radius) : RRectF(rect, radius, radius) {}
  RRectF(const gfx::RectF& rect, float x_rad, float y_rad)
      : RRectF(rect.x(), rect.y(), rect.width(), rect.height(), x_rad, y_rad) {}
  // Sets all x and y radii to radius.
  RRectF(float x, float y, float width, float height, float radius)
      : RRectF(x, y, width, height, radius, radius) {}
  // Sets all x radii to x_rad, and all y radii to y_rad. If one of x_rad or
  // y_rad are zero, sets ALL radii to zero.
  RRectF(float x, float y, float width, float height, float x_rad, float y_rad);
  // Directly sets all four corners.
  RRectF(float x,
         float y,
         float width,
         float height,
         float upper_left_x,
         float upper_left_y,
         float upper_right_x,
         float upper_right_y,
         float lower_right_x,
         float lower_right_y,
         float lower_left_x,
         float lower_left_y);
  RRectF(const gfx::RectF& rect,
         float upper_left_x,
         float upper_left_y,
         float upper_right_x,
         float upper_right_y,
         float lower_right_x,
         float lower_right_y,
         float lower_left_x,
         float lower_left_y)
      : RRectF(rect.x(),
               rect.y(),
               rect.width(),
               rect.height(),
               upper_left_x,
               upper_left_y,
               upper_right_x,
               upper_right_y,
               lower_right_x,
               lower_right_y,
               lower_left_x,
               lower_left_y) {}
  RRectF(const gfx::RectF& rect, const gfx::RoundedCornersF& corners)
      : RRectF(rect.x(),
               rect.y(),
               rect.width(),
               rect.height(),
               corners.upper_left(),
               corners.upper_left(),
               corners.upper_right(),
               corners.upper_right(),
               corners.lower_right(),
               corners.lower_right(),
               corners.lower_left(),
               corners.lower_left()) {}

  // The rectangular portion of the RRectF, without the corner radii.
  gfx::RectF rect() const { return gfx::SkRectToRectF(skrrect_.rect()); }

  // Returns the radii of the all corners. DCHECKs that all corners
  // have the same radii (the type is <= kOval).
  gfx::Vector2dF GetSimpleRadii() const;
  // Returns the radius of all corners. DCHECKs that all corners have the same
  // radii, and that x_rad == y_rad (the type is <= kSingle).
  float GetSimpleRadius() const;

  // Make the RRectF empty.
  void Clear() { skrrect_.setEmpty(); }

  bool Equals(const RRectF& other) const { return skrrect_ == other.skrrect_; }

  // These are all mutually exclusive, and ordered in increasing complexity. The
  // order is assumed in several functions.
  enum class Type {
    kEmpty,   // Zero width or height.
    kRect,    // Non-zero width and height, and zeroed radii - a pure rectangle.
    kSingle,  // Non-zero width and height, and a single, non-zero value for all
              // X and Y radii.
    kSimple,  // Non-zero width and height, X radii all equal and non-zero, Y
              // radii all equal and non-zero, and x_rad != y_rad.
    kOval,    // Non-zero width and height, X radii all equal to width/2, and Y
              // radii all equal to height/2, and x_rad != y_rad.
    kComplex,  // Non-zero width and height, and arbitrary (non-equal) radii.
  };
  Type GetType() const;

  bool IsEmpty() const { return GetType() == Type::kEmpty; }
  bool HasRoundedCorners() const {
    return !IsEmpty() && GetType() != Type::kRect;
  }

  // Enumeration of the corners of a rectangle in clockwise order. Values match
  // SkRRect::Corner.
  enum class Corner {
    kUpperLeft = SkRRect::kUpperLeft_Corner,
    kUpperRight = SkRRect::kUpperRight_Corner,
    kLowerRight = SkRRect::kLowerRight_Corner,
    kLowerLeft = SkRRect::kLowerLeft_Corner,
  };
  // GetCornerRadii may be called for any type of RRect (kRect, kOval, etc.),
  // and it will return "correct" values. If GetType() is kOval or less, all
  // corner values will be identical to each other. SetCornerRadii can similarly
  // be called on any type of RRect, but GetType() may change as a result of the
  // call.
  gfx::Vector2dF GetCornerRadii(Corner corner) const;
  void SetCornerRadii(Corner corner, float x_rad, float y_rad);
  void SetCornerRadii(Corner corner, const gfx::Vector2dF& radii) {
    SetCornerRadii(corner, radii.x(), radii.y());
  }

  // Returns true if |rect| is inside the bounds and corner radii of this
  // RRectF, and if both this RRectF and rect are not empty.
  bool Contains(const RectF& rect) const {
    return skrrect_.contains(gfx::RectFToSkRect(rect));
  }

  // Returns the bounding box that contains the specified rounded corner.
  gfx::RectF CornerBoundingRect(Corner corner) const;

  // Scales the rectangle by |scale|.
  void Scale(float scale) { Scale(scale, scale); }
  // Scales the rectangle by |x_scale| and |y_scale|.
  void Scale(float x_scale, float y_scale);

  // Move the rectangle by a horizontal and vertical distance.
  void Offset(float horizontal, float vertical);
  void Offset(const Vector2dF& distance) { Offset(distance.x(), distance.y()); }
  const RRectF& operator+=(const gfx::Vector2dF& offset);
  const RRectF& operator-=(const gfx::Vector2dF& offset);

  std::string ToString() const;
  bool ApproximatelyEqual(const RRectF& rect, float tolerance) const;

  // Insets bounds by dx and dy, and adjusts radii by dx and dy. dx and dy may
  // be positive, negative, or zero. If either corner radius is zero, the corner
  // has no curvature and is unchanged. Otherwise, if adjusted radius becomes
  // negative, the radius is pinned to zero.
  void Inset(float val) { skrrect_.inset(val, val); }
  void Inset(float dx, float dy) { skrrect_.inset(dx, dy); }
  // Outsets bounds by dx and dy, and adjusts radii by dx and dy. dx and dy may
  // be positive, negative, or zero. If either corner radius is zero, the corner
  // has no curvature and is unchanged. Otherwise, if adjusted radius becomes
  // negative, the radius is pinned to zero.
  void Outset(float val) { skrrect_.outset(val, val); }
  void Outset(float dx, float dy) { skrrect_.outset(dx, dy); }

  explicit operator SkRRect() const { return skrrect_; }

  static RRectF ToEnclosingRRectF(const RRectF& rrect);
  static RRectF ToEnclosingRRectFIgnoringError(const RRectF& rrect,
                                               float error = 0.001f);

 private:
  void GetAllRadii(SkVector radii[4]) const;

  gfx::RoundedCornersF GetRoundedCorners() const;

  SkRRect skrrect_;
};

inline std::ostream& operator<<(std::ostream& os, const RRectF& rect) {
  return os << rect.ToString();
}

inline bool operator==(const RRectF& a, const RRectF& b) {
  return a.Equals(b);
}

inline RRectF operator+(const RRectF& a, const gfx::Vector2dF& b) {
  RRectF result = a;
  result += b;
  return result;
}

inline RRectF operator-(const RRectF& a, const Vector2dF& b) {
  RRectF result = a;
  result -= b;
  return result;
}

}  // namespace gfx

#endif  // UI_GFX_GEOMETRY_RRECT_F_H_