@@ -55,5 +55,189 @@ TEST(RectTest, RectMakeSize) {
55
55
}
56
56
}
57
57
58
+ TEST (RectTest, NormalizePoint) {
59
+ // Tests finite rects including:
60
+ // - points at the corners, inside, and outside
61
+ // - rects that are non-empty or empty through either zero or
62
+ // negative width and/or height
63
+ // - all combinations of integer and scalar rects and points.
64
+
65
+ // Tests one rectangle in all 4 combinations of integer and scalar data
66
+ // and also against NaN point values
67
+ auto test_one = [](int64_t l, int64_t t, int64_t r, int64_t b, //
68
+ const std::string& rect_desc, //
69
+ int64_t px, int64_t py, //
70
+ const std::string& pt_desc, //
71
+ Point expected) {
72
+ // Scalar point inside Scalar rect
73
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, b).NormalizePoint (Point (px, py)),
74
+ expected)
75
+ << " Point(" << pt_desc << " ) in " << rect_desc << " Rect" ;
76
+ // Scalar point inside Integer rect
77
+ ASSERT_EQ (IRect::MakeLTRB (l, t, r, b).NormalizePoint (Point (px, py)),
78
+ expected)
79
+ << " Point(" << pt_desc << " ) in " << rect_desc << " IRect" ;
80
+ // Integer point inside Scalar rect
81
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, b).NormalizePoint (IPoint (px, py)),
82
+ expected)
83
+ << " IPoint(" << pt_desc << " ) in " << rect_desc << " Rect" ;
84
+ // Integer point inside Integer rect
85
+ ASSERT_EQ (IRect::MakeLTRB (l, t, r, b).NormalizePoint (IPoint (px, py)),
86
+ expected)
87
+ << " IPoint(" << pt_desc << " ) in " << rect_desc << " IRect" ;
88
+
89
+ auto nan = std::numeric_limits<Scalar>::quiet_NaN ();
90
+ auto nan_x = Point (nan, py);
91
+ auto nan_y = Point (px, nan);
92
+ auto nan_p = Point (nan, nan);
93
+ // Nan Scalar point inside Scalar and integer rects
94
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, b).NormalizePoint (nan_x), Point ())
95
+ << " Point(NaN x) in " << rect_desc << " Rect" ;
96
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, b).NormalizePoint (nan_y), Point ())
97
+ << " Point(NaN y) in " << rect_desc << " Rect" ;
98
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, b).NormalizePoint (nan_p), Point ())
99
+ << " Point(NaN x&y) in " << rect_desc << " Rect" ;
100
+ ASSERT_EQ (IRect::MakeLTRB (l, t, r, b).NormalizePoint (nan_x), Point ())
101
+ << " Point(NaN x) in " << rect_desc << " Rect" ;
102
+ ASSERT_EQ (IRect::MakeLTRB (l, t, r, b).NormalizePoint (nan_y), Point ())
103
+ << " Point(NaN y) in " << rect_desc << " Rect" ;
104
+ ASSERT_EQ (IRect::MakeLTRB (l, t, r, b).NormalizePoint (nan_p), Point ())
105
+ << " Point(NaN x&y) in " << rect_desc << " Rect" ;
106
+ };
107
+
108
+ // Tests a rectangle using test_one both normally and all variants of
109
+ // being empty by reversing the lr and tb points.
110
+ auto test = [&test_one](int64_t l, int64_t t, int64_t r, int64_t b, //
111
+ int64_t px, int64_t py, //
112
+ const std::string& pt_desc, Point expected) {
113
+ test_one (l, t, r, b, " non-empty" , px, py, pt_desc, expected);
114
+ test_one (l, t, l, b, " LR empty" , px, py, pt_desc, Point ());
115
+ test_one (r, t, l, b, " LR reversed" , px, py, pt_desc, Point ());
116
+ test_one (l, t, r, t, " TB empty" , px, py, pt_desc, Point ());
117
+ test_one (l, b, r, t, " TB reversed" , px, py, pt_desc, Point ());
118
+ test_one (l, t, l, t, " all empty" , px, py, pt_desc, Point ());
119
+ test_one (r, b, l, t, " all reversed" , px, py, pt_desc, Point ());
120
+ };
121
+
122
+ test (100 , 100 , 200 , 200 , 100 , 100 , " UL" , Point (0 , 0 ));
123
+ test (100 , 100 , 200 , 200 , 200 , 100 , " UR" , Point (1 , 0 ));
124
+ test (100 , 100 , 200 , 200 , 200 , 200 , " LR" , Point (1 , 1 ));
125
+ test (100 , 100 , 200 , 200 , 100 , 200 , " LL" , Point (0 , 1 ));
126
+ test (100 , 100 , 200 , 200 , 150 , 150 , " Center" , Point (0.5 , 0.5 ));
127
+ test (100 , 100 , 200 , 200 , 0 , 0 , " outside UL" , Point (-1 , -1 ));
128
+ test (100 , 100 , 200 , 200 , 300 , 0 , " outside UR" , Point (2 , -1 ));
129
+ test (100 , 100 , 200 , 200 , 300 , 300 , " outside LR" , Point (2 , 2 ));
130
+ test (100 , 100 , 200 , 200 , 0 , 300 , " outside LL" , Point (-1 , 2 ));
131
+
132
+ // We can't test the true min and max due to overflow of the xywh
133
+ // internal representation, but we can test with half their values.
134
+ // When TRect is converted to ltrb notation, we can relax this
135
+ // restriction.
136
+ int64_t min_int = std::numeric_limits<int64_t >::min () / 2 ;
137
+ int64_t max_int = std::numeric_limits<int64_t >::max () / 2 ;
138
+ test (min_int, 100 , max_int, 200 , 0 , 150 , " max int center" , Point (0.5 , 0.5 ));
139
+ }
140
+
141
+ TEST (RectTest, NormalizePointToNonFiniteRects) {
142
+ // Tests non-finite Scalar rects including:
143
+ // - points at the corners, inside, and outside
144
+ // - rects that are non-empty or empty through either zero or
145
+ // negative width and/or height
146
+
147
+ // Tests one rectangle against supplied point values and NaN replacements.
148
+ auto test = [](Scalar l, Scalar t, Scalar r, Scalar b, //
149
+ Scalar px, Scalar py, //
150
+ const std::string& pt_desc, //
151
+ Point expected) {
152
+ auto nan = std::numeric_limits<Scalar>::quiet_NaN ();
153
+ auto inf = std::numeric_limits<Scalar>::infinity ();
154
+
155
+ // Scalar point inside Scalar rect
156
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, b).NormalizePoint (Point (px, py)),
157
+ expected)
158
+ << " Point(" << pt_desc << " ) in Rect" ;
159
+ // Scalar point inside Scalar rect with NaN left
160
+ ASSERT_EQ (Rect::MakeLTRB (nan, t, r, b).NormalizePoint (Point (px, py)),
161
+ Point ())
162
+ << " Point(" << pt_desc << " ) in Rect NaN Left" ;
163
+ // Scalar point inside Scalar rect with NaN top
164
+ ASSERT_EQ (Rect::MakeLTRB (l, nan, r, b).NormalizePoint (Point (px, py)),
165
+ Point ())
166
+ << " Point(" << pt_desc << " ) in Rect NaN Top" ;
167
+ // Scalar point inside Scalar rect with NaN right
168
+ ASSERT_EQ (Rect::MakeLTRB (l, t, nan, b).NormalizePoint (Point (px, py)),
169
+ Point ())
170
+ << " Point(" << pt_desc << " ) in Rect NaN Left" ;
171
+ // Scalar point inside Scalar rect with NaN bottom
172
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, nan).NormalizePoint (Point (px, py)),
173
+ Point ())
174
+ << " Point(" << pt_desc << " ) in Rect NaN Top" ;
175
+ // Scalar point inside Scalar rect with infinite left
176
+ ASSERT_EQ (Rect::MakeLTRB (-inf, t, r, b).NormalizePoint (Point (px, py)),
177
+ Point ())
178
+ << " Point(" << pt_desc << " ) in Rect -Inf Left" ;
179
+ // Scalar point inside Scalar rect with infinite top
180
+ ASSERT_EQ (Rect::MakeLTRB (l, -inf, r, b).NormalizePoint (Point (px, py)),
181
+ Point ())
182
+ << " Point(" << pt_desc << " ) in Rect -Inf Top" ;
183
+ // Scalar point inside Scalar rect with infinite right
184
+ ASSERT_EQ (Rect::MakeLTRB (l, t, inf, b).NormalizePoint (Point (px, py)),
185
+ Point (0 , expected.y ))
186
+ << " Point(" << pt_desc << " ) in Rect Inf Right" ;
187
+ // Scalar point inside Scalar rect with infinite bottom
188
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, inf).NormalizePoint (Point (px, py)),
189
+ Point (expected.x , 0 ))
190
+ << " Point(" << pt_desc << " ) in Rect Inf Bottom" ;
191
+
192
+ // Testing with NaN points
193
+ auto nan_x = Point (nan, py);
194
+ auto nan_y = Point (px, nan);
195
+ auto nan_p = Point (nan, nan);
196
+ // Nan Scalar point inside Scalar rect
197
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, b).NormalizePoint (nan_x), Point ())
198
+ << " Point(NaN x) in Rect" ;
199
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, b).NormalizePoint (nan_y), Point ())
200
+ << " Point(NaN y) in Rect" ;
201
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, b).NormalizePoint (nan_p), Point ())
202
+ << " Point(NaN x&y) in Rect" ;
203
+
204
+ // Testing with infinite points
205
+ auto inf_x = Point (inf, py);
206
+ auto inf_y = Point (px, inf);
207
+ auto inf_p = Point (inf, inf);
208
+ // Infinite Scalar point inside Scalar rect
209
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, b).NormalizePoint (inf_x), Point ())
210
+ << " Point(Infinite x) in Rect" ;
211
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, b).NormalizePoint (inf_y), Point ())
212
+ << " Point(Infinite y) in Rect" ;
213
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, b).NormalizePoint (inf_p), Point ())
214
+ << " Point(Infinite x&y) in Rect" ;
215
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, b).NormalizePoint (-inf_x), Point ())
216
+ << " Point(-Infinite x) in Rect" ;
217
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, b).NormalizePoint (-inf_y), Point ())
218
+ << " Point(-Infinite y) in Rect" ;
219
+ ASSERT_EQ (Rect::MakeLTRB (l, t, r, b).NormalizePoint (-inf_p), Point ())
220
+ << " Point(-Infinite x&y) in Rect" ;
221
+ };
222
+
223
+ test (100 , 100 , 200 , 200 , 100 , 100 , " UL" , Point (0 , 0 ));
224
+ test (100 , 100 , 200 , 200 , 200 , 100 , " UR" , Point (1 , 0 ));
225
+ test (100 , 100 , 200 , 200 , 200 , 200 , " LR" , Point (1 , 1 ));
226
+ test (100 , 100 , 200 , 200 , 100 , 200 , " LL" , Point (0 , 1 ));
227
+ test (100 , 100 , 200 , 200 , 150 , 150 , " Center" , Point (0.5 , 0.5 ));
228
+ test (100 , 100 , 200 , 200 , 0 , 0 , " outside UL" , Point (-1 , -1 ));
229
+ test (100 , 100 , 200 , 200 , 300 , 0 , " outside UR" , Point (2 , -1 ));
230
+ test (100 , 100 , 200 , 200 , 300 , 300 , " outside LR" , Point (2 , 2 ));
231
+ test (100 , 100 , 200 , 200 , 0 , 300 , " outside LL" , Point (-1 , 2 ));
232
+
233
+ // We can't test the true min and max due to overflow of the xywh
234
+ // internal representation, but we can test with half their values.
235
+ // When TRect is converted to ltrb notation, we can relax this
236
+ // restriction.
237
+ int64_t min_int = std::numeric_limits<int64_t >::min () / 2 ;
238
+ int64_t max_int = std::numeric_limits<int64_t >::max () / 2 ;
239
+ test (min_int, 100 , max_int, 200 , 0 , 150 , " max int center" , Point (0.5 , 0.5 ));
240
+ }
241
+
58
242
} // namespace testing
59
243
} // namespace impeller
0 commit comments