Flutter Engine
The Flutter Engine
Rect.h
Go to the documentation of this file.
1/*
2 * Copyright 2021 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef skgpu_graphite_geom_Rect_DEFINED
9#define skgpu_graphite_geom_Rect_DEFINED
10
11#include "include/core/SkRect.h"
12#include "src/base/SkVx.h"
13
14namespace skgpu::graphite {
15
16#define AI SK_ALWAYS_INLINE
17
18/**
19 * SIMD rect implementation. Values are stored internally in the form: [left, top, -right, -bot].
20 *
21 * Some operations (e.g., intersect, inset) may return a negative or empty rect
22 * (negative meaning, left >= right or top >= bot).
23 *
24 * Operations on a rect that is either negative or empty, while well-defined, might not give the
25 * intended result. It is the caller's responsibility to check isEmptyOrNegative() if needed.
26 */
27class Rect {
28 using float2 = skvx::float2;
29 using float4 = skvx::float4;
30public:
31 AI Rect() = default;
32 AI Rect(float l, float t, float r, float b) : fVals(NegateBotRight({l,t,r,b})) {}
34 AI Rect(const SkRect& r) : fVals(NegateBotRight(float4::Load(r.asScalars()))) {}
35
37 return Rect(NegateBotRight(ltrb));
38 }
39
40 AI static Rect XYWH(float x, float y, float w, float h) {
41 return Rect(x, y, x + w, y + h);
42 }
44 return Rect(topLeft, topLeft + size);
45 }
46 AI static Rect WH(float w, float h) {
47 return Rect(0, 0, w, h);
48 }
49 AI static Rect WH(float2 size) {
50 return Rect(float2(0), size);
51 }
52 AI static Rect Point(float2 p) {
53 return Rect(p, p);
54 }
55 AI static Rect FromVals(float4 vals) { // vals.zw must already be negated.
56 return Rect(vals);
57 }
58
59 // Constructs a Rect with ltrb = [-inf, -inf, inf, inf], useful for accumulating intersections
60 AI static Rect Infinite() {
62 }
63 // Constructs a negative Rect with ltrb = [inf, inf, -inf, -inf], useful for accumulating unions
66 }
67
68 AI bool operator==(Rect rect) const { return all(fVals == rect.fVals); }
69 AI bool operator!=(Rect rect) const { return any(fVals != rect.fVals); }
70
71 AI const float4& vals() const { return fVals; } // [left, top, -right, -bot].
72 AI float4& vals() { return fVals; } // [left, top, -right, -bot].
73
74 AI float x() const { return fVals.x(); }
75 AI float y() const { return fVals.y(); }
76 AI float left() const { return fVals.x(); }
77 AI float top() const { return fVals.y(); }
78 AI float right() const { return -fVals.z(); }
79 AI float bot() const { return -fVals.w(); }
80 AI float2 topLeft() const { return fVals.xy(); }
81 AI float2 botRight() const { return -fVals.zw(); }
82 AI float4 ltrb() const { return NegateBotRight(fVals); }
83
84 AI void setLeft(float left) { fVals.x() = left; }
85 AI void setTop(float top) { fVals.y() = top; }
86 AI void setRight(float right) { fVals.z() = -right; }
87 AI void setBot(float bot) { fVals.w() = -bot; }
88 AI void setTopLeft(float2 topLeft) { fVals.xy() = topLeft; }
89 AI void setBotRight(float2 botRight) { fVals.zw() = -botRight; }
90
91 AI SkRect asSkRect() const {
93 this->ltrb().store(&rect);
94 return rect;
95 }
98 skvx::cast<int>(this->ltrb()).store(&rect);
99 return rect;
100 }
101
103 return !all(fVals.xy() + fVals.zw() < 0); // !([l-r, r-b] < 0) == ([w, h] <= 0)
104 // Use "!(-size < 0)" in order to detect NaN.
105 }
106
107 AI float2 size() const { return -(fVals.xy() + fVals.zw()); } // == [-(l-r), -(t-b)] == [w, h]
108
109 AI float2 center() const {
110 float4 p = fVals * float4(.5f, .5f, -.5f, -.5f); // == [l, t, r, b] * .5
111 return p.xy() + p.zw(); // == [(l + r)/2, (t + b)/2]
112 }
113
114 AI float area() const {
115 float2 negativeSize = fVals.xy() + fVals.zw(); // == [l-r, t-b] == [-w, -h]
116 return negativeSize.x() * negativeSize.y();
117 }
118
119 // A rect stored in a complementary form of: [right, bottom, -left, -top]. Store a local
120 // ComplementRect object if intersects() will be called many times.
123 float4 fVals; // [right, bottom, -left, -top]
124 };
125
126 AI bool intersects(ComplementRect comp) const { return all(fVals < comp.fVals); }
127 AI bool contains(Rect rect) const { return all(fVals <= rect.fVals); }
128
129 // Some operations may return a negative or empty rect. Operations on a rect that either is
130 // negative or empty, while well-defined, might not give the intended result. It is the caller's
131 // responsibility to check isEmptyOrNegative() if needed.
132 AI Rect makeRoundIn() const { return ceil(fVals); }
133 AI Rect makeRoundOut() const { return floor(fVals); }
134 AI Rect makeInset(float inset) const { return fVals + inset; }
135 AI Rect makeInset(float2 inset) const { return fVals + inset.xyxy(); }
136 AI Rect makeOutset(float outset) const { return fVals - outset; }
137 AI Rect makeOutset(float2 outset) const { return fVals - outset.xyxy(); }
138 AI Rect makeOffset(float2 offset) const { return fVals + float4(offset, -offset); }
139 AI Rect makeJoin(Rect rect) const { return min(fVals, rect.fVals); }
140 AI Rect makeIntersect(Rect rect) const { return max(fVals, rect.fVals); }
141 AI Rect makeSorted() const { return min(fVals, -fVals.zwxy()); }
142
143 AI Rect& roundIn() { return *this = this->makeRoundIn(); }
144 AI Rect& roundOut() { return *this = this->makeRoundOut(); }
145 AI Rect& inset(float inset) { return *this = this->makeInset(inset); }
146 AI Rect& inset(float2 inset) { return *this = this->makeInset(inset); }
147 AI Rect& outset(float outset) { return *this = this->makeOutset(outset); }
148 AI Rect& outset(float2 outset) { return *this = this->makeOutset(outset); }
149 AI Rect& offset(float2 offset) { return *this = this->makeOffset(offset); }
150 AI Rect& join(Rect rect) { return *this = this->makeJoin(rect); }
151 AI Rect& intersect(Rect rect) { return *this = this->makeIntersect(rect); }
152 AI Rect& sort() { return *this = this->makeSorted(); }
153
154private:
155 AI static float4 NegateBotRight(float4 vals) { // Returns [vals.xy, -vals.zw].
156 using uint4 = skvx::uint4;
157 return sk_bit_cast<float4>(sk_bit_cast<uint4>(vals) ^ uint4(0, 0, 1u << 31, 1u << 31));
158 }
159
160 AI Rect(float4 vals) : fVals(vals) {} // vals.zw must already be negated.
161
162 float4 fVals; // [left, top, -right, -bottom]
163};
164
165#undef AI
166
167} // namespace skgpu::graphite
168
169#endif // skgpu_graphite_geom_Rect_DEFINED
#define AI
Definition: Rect.h:16
constexpr float SK_FloatInfinity
constexpr float SK_FloatNegativeInfinity
static AI Rect XYWH(float2 topLeft, float2 size)
Definition: Rect.h:43
AI void setBot(float bot)
Definition: Rect.h:87
static AI Rect InfiniteInverted()
Definition: Rect.h:64
static AI Rect XYWH(float x, float y, float w, float h)
Definition: Rect.h:40
AI bool contains(Rect rect) const
Definition: Rect.h:127
AI void setTop(float top)
Definition: Rect.h:85
AI float bot() const
Definition: Rect.h:79
AI Rect makeIntersect(Rect rect) const
Definition: Rect.h:140
AI Rect makeOutset(float2 outset) const
Definition: Rect.h:137
AI Rect makeRoundIn() const
Definition: Rect.h:132
AI Rect & inset(float inset)
Definition: Rect.h:145
static AI Rect WH(float2 size)
Definition: Rect.h:49
AI Rect & roundOut()
Definition: Rect.h:144
AI float top() const
Definition: Rect.h:77
AI bool isEmptyNegativeOrNaN() const
Definition: Rect.h:102
AI float left() const
Definition: Rect.h:76
AI Rect makeOutset(float outset) const
Definition: Rect.h:136
static AI Rect LTRB(float4 ltrb)
Definition: Rect.h:36
static AI Rect WH(float w, float h)
Definition: Rect.h:46
AI float y() const
Definition: Rect.h:75
AI void setTopLeft(float2 topLeft)
Definition: Rect.h:88
static AI Rect Infinite()
Definition: Rect.h:60
AI Rect makeInset(float2 inset) const
Definition: Rect.h:135
AI Rect makeSorted() const
Definition: Rect.h:141
AI const float4 & vals() const
Definition: Rect.h:71
AI float area() const
Definition: Rect.h:114
AI SkRect asSkRect() const
Definition: Rect.h:91
AI Rect & inset(float2 inset)
Definition: Rect.h:146
AI float4 & vals()
Definition: Rect.h:72
AI Rect & offset(float2 offset)
Definition: Rect.h:149
AI float2 topLeft() const
Definition: Rect.h:80
AI float2 center() const
Definition: Rect.h:109
AI Rect & join(Rect rect)
Definition: Rect.h:150
AI bool operator!=(Rect rect) const
Definition: Rect.h:69
AI Rect makeInset(float inset) const
Definition: Rect.h:134
AI bool operator==(Rect rect) const
Definition: Rect.h:68
AI Rect(const SkRect &r)
Definition: Rect.h:34
AI float2 size() const
Definition: Rect.h:107
static AI Rect FromVals(float4 vals)
Definition: Rect.h:55
AI bool intersects(ComplementRect comp) const
Definition: Rect.h:126
AI Rect & sort()
Definition: Rect.h:152
AI Rect & outset(float2 outset)
Definition: Rect.h:148
AI void setLeft(float left)
Definition: Rect.h:84
AI Rect & intersect(Rect rect)
Definition: Rect.h:151
AI Rect & roundIn()
Definition: Rect.h:143
AI Rect makeJoin(Rect rect) const
Definition: Rect.h:139
AI float2 botRight() const
Definition: Rect.h:81
AI Rect makeOffset(float2 offset) const
Definition: Rect.h:138
AI SkIRect asSkIRect() const
Definition: Rect.h:96
static AI Rect Point(float2 p)
Definition: Rect.h:52
AI Rect makeRoundOut() const
Definition: Rect.h:133
AI Rect(float l, float t, float r, float b)
Definition: Rect.h:32
AI Rect(float2 topLeft, float2 botRight)
Definition: Rect.h:33
AI void setRight(float right)
Definition: Rect.h:86
AI float4 ltrb() const
Definition: Rect.h:82
AI float right() const
Definition: Rect.h:78
AI void setBotRight(float2 botRight)
Definition: Rect.h:89
AI float x() const
Definition: Rect.h:74
AI Rect & outset(float outset)
Definition: Rect.h:147
static bool b
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
Vec< 4, float > float4
Definition: SkVx.h:1146
SIT bool all(const Vec< 1, T > &x)
Definition: SkVx.h:582
Vec< 2, float > float2
Definition: SkVx.h:1145
Vec< 4, uint32_t > uint4
Definition: SkVx.h:1167
SIN Vec< N, float > floor(const Vec< N, float > &x)
Definition: SkVx.h:703
SIT bool any(const Vec< 1, T > &x)
Definition: SkVx.h:530
SIN Vec< N, float > ceil(const Vec< N, float > &x)
Definition: SkVx.h:702
SkScalar w
SkScalar h
Definition: SkRect.h:32
Definition: SkVx.h:83
SKVX_ALWAYS_INLINE void store(void *ptr) const
Definition: SkVx.h:112