1/*
2 * Copyright (C) 2016 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27
28#include <WebCore/AffineTransform.h>
29#include <WebCore/FloatPoint.h>
30#include <WebCore/FloatSize.h>
31#include <WebCore/IntPoint.h>
32#include <WebCore/IntSize.h>
33#include <WebCore/TransformationMatrix.h>
34
35#if USE(CG)
36#include <CoreGraphics/CoreGraphics.h>
37#endif
38
39#if PLATFORM(WIN)
40#include <d2d1.h>
41#endif
42
43namespace TestWebKitAPI {
44
45static void testGetAndSet(WebCore::FloatPoint point)
46{
47 point.setX(1.1f);
48 EXPECT_FLOAT_EQ(1.1f, point.x());
49 point.setY(2.2f);
50 EXPECT_FLOAT_EQ(2.2f, point.y());
51
52 point.set(9.9f, 8.8f);
53 EXPECT_FLOAT_EQ(9.9f, point.x());
54 EXPECT_FLOAT_EQ(8.8f, point.y());
55}
56
57TEST(FloatPoint, DefaultConstruction)
58{
59 WebCore::FloatPoint test;
60
61 EXPECT_FLOAT_EQ(0, test.x());
62 EXPECT_FLOAT_EQ(0, test.y());
63
64 testGetAndSet(test);
65}
66
67TEST(FloatPoint, ValueConstruction)
68{
69 WebCore::FloatPoint test(9.9f, 8.8f);
70
71 EXPECT_FLOAT_EQ(9.9f, test.x());
72 EXPECT_FLOAT_EQ(8.8f, test.y());
73
74 testGetAndSet(test);
75}
76
77TEST(FloatPoint, ZeroConstruction)
78{
79 WebCore::FloatPoint test = WebCore::FloatPoint::zero();
80
81 EXPECT_FLOAT_EQ(0, test.x());
82 EXPECT_FLOAT_EQ(0, test.y());
83}
84
85TEST(FloatPoint, IntPointConstruction)
86{
87 WebCore::IntPoint testInput(2003, 1997);
88 WebCore::FloatPoint test = WebCore::FloatPoint(testInput);
89
90 EXPECT_FLOAT_EQ(2003.0f, test.x());
91 EXPECT_FLOAT_EQ(1997.0f, test.y());
92}
93
94TEST(FloatPoint, FloatSizeConstruction)
95{
96 WebCore::FloatSize testInput(500.7f, 300.2f);
97 WebCore::FloatPoint test = WebCore::FloatPoint(testInput);
98
99 EXPECT_FLOAT_EQ(500.7, test.x());
100 EXPECT_FLOAT_EQ(300.2, test.y());
101}
102
103TEST(FloatPoint, MoveByFloat)
104{
105 WebCore::FloatPoint test(100.0f, 200.0f);
106
107 EXPECT_FLOAT_EQ(100.0f, test.x());
108 EXPECT_FLOAT_EQ(200.0f, test.y());
109
110 test.move(20.2f, 30.3f);
111
112 EXPECT_FLOAT_EQ(120.2f, test.x());
113 EXPECT_FLOAT_EQ(230.3f, test.y());
114
115 test.move(-81.3f, 10.0f);
116
117 EXPECT_FLOAT_EQ(38.9f, test.x());
118 EXPECT_FLOAT_EQ(240.3f, test.y());
119
120 test.move(11.1f, -33.2f);
121
122 EXPECT_FLOAT_EQ(50.0f, test.x());
123 EXPECT_FLOAT_EQ(207.1f, test.y());
124
125 test.move(-5.6f, -9.8f);
126
127 EXPECT_FLOAT_EQ(44.4f, test.x());
128 EXPECT_FLOAT_EQ(197.3f, test.y());
129}
130
131TEST(FloatPoint, MoveByIntSize)
132{
133 WebCore::FloatPoint test(100.0f, 200.0f);
134
135 EXPECT_FLOAT_EQ(100.0f, test.x());
136 EXPECT_FLOAT_EQ(200.0f, test.y());
137
138 WebCore::IntSize first(20, 30);
139
140 test.move(first);
141
142 EXPECT_FLOAT_EQ(120.0f, test.x());
143 EXPECT_FLOAT_EQ(230.0f, test.y());
144
145 WebCore::IntSize second(-81, 10);
146
147 test.move(second);
148
149 EXPECT_FLOAT_EQ(39.0f, test.x());
150 EXPECT_FLOAT_EQ(240.0f, test.y());
151
152 WebCore::IntSize third(11, -33);
153
154 test.move(third);
155
156 EXPECT_FLOAT_EQ(50.0f, test.x());
157 EXPECT_FLOAT_EQ(207.0f, test.y());
158
159 WebCore::IntSize fourth(-6, -10);
160
161 test.move(fourth);
162
163 EXPECT_FLOAT_EQ(44.0f, test.x());
164 EXPECT_FLOAT_EQ(197.0f, test.y());
165}
166
167TEST(FloatPoint, MoveByFloatSize)
168{
169 WebCore::FloatPoint test(100.0f, 200.0f);
170
171 EXPECT_FLOAT_EQ(100.0f, test.x());
172 EXPECT_FLOAT_EQ(200.0f, test.y());
173
174 WebCore::FloatSize first(20.2f, 30.3f);
175
176 test.move(first);
177
178 EXPECT_FLOAT_EQ(120.2f, test.x());
179 EXPECT_FLOAT_EQ(230.3f, test.y());
180
181 WebCore::FloatSize second(-81.3f, 10.0f);
182
183 test.move(second);
184
185 EXPECT_FLOAT_EQ(38.9f, test.x());
186 EXPECT_FLOAT_EQ(240.3f, test.y());
187
188 WebCore::FloatSize third(11.1f, -33.2f);
189
190 test.move(third);
191
192 EXPECT_FLOAT_EQ(50.0f, test.x());
193 EXPECT_FLOAT_EQ(207.1f, test.y());
194
195 WebCore::FloatSize fourth(-5.6f, -9.8f);
196
197 test.move(fourth);
198
199 EXPECT_FLOAT_EQ(44.4f, test.x());
200 EXPECT_FLOAT_EQ(197.3f, test.y());
201}
202
203TEST(FloatPoint, MoveByIntPoint)
204{
205 WebCore::FloatPoint test(100.0f, 200.0f);
206
207 EXPECT_FLOAT_EQ(100.0f, test.x());
208 EXPECT_FLOAT_EQ(200.0f, test.y());
209
210 WebCore::IntPoint first(20, 30);
211
212 test.moveBy(first);
213
214 EXPECT_FLOAT_EQ(120.0f, test.x());
215 EXPECT_FLOAT_EQ(230.0f, test.y());
216
217 WebCore::IntPoint second(-81, 10);
218
219 test.moveBy(second);
220
221 EXPECT_FLOAT_EQ(39.0f, test.x());
222 EXPECT_FLOAT_EQ(240.0f, test.y());
223
224 WebCore::IntPoint third(11, -33);
225
226 test.moveBy(third);
227
228 EXPECT_FLOAT_EQ(50.0f, test.x());
229 EXPECT_FLOAT_EQ(207.0f, test.y());
230
231 WebCore::IntPoint fourth(-6, -10);
232
233 test.moveBy(fourth);
234
235 EXPECT_FLOAT_EQ(44.0f, test.x());
236 EXPECT_FLOAT_EQ(197.0f, test.y());
237}
238
239TEST(FloatPoint, MoveByFloatPoint)
240{
241 WebCore::FloatPoint test(100.0f, 200.0f);
242
243 EXPECT_FLOAT_EQ(100.0f, test.x());
244 EXPECT_FLOAT_EQ(200.0f, test.y());
245
246 WebCore::FloatPoint first(20.2f, 30.3f);
247
248 test.moveBy(first);
249
250 EXPECT_FLOAT_EQ(120.2f, test.x());
251 EXPECT_FLOAT_EQ(230.3f, test.y());
252
253 WebCore::FloatPoint second(-81.3f, 10.0f);
254
255 test.moveBy(second);
256
257 EXPECT_FLOAT_EQ(38.9f, test.x());
258 EXPECT_FLOAT_EQ(240.3f, test.y());
259
260 WebCore::FloatPoint third(11.1f, -33.2f);
261
262 test.moveBy(third);
263
264 EXPECT_FLOAT_EQ(50.0f, test.x());
265 EXPECT_FLOAT_EQ(207.1f, test.y());
266
267 WebCore::FloatPoint fourth(-5.6f, -9.8f);
268
269 test.moveBy(fourth);
270
271 EXPECT_FLOAT_EQ(44.4f, test.x());
272 EXPECT_FLOAT_EQ(197.3f, test.y());
273}
274
275TEST(FloatPoint, Scale)
276{
277 WebCore::FloatPoint test(100.0f, 200.0f);
278
279 EXPECT_FLOAT_EQ(100.0f, test.x());
280 EXPECT_FLOAT_EQ(200.0f, test.y());
281
282 test.scale(2.0f, 2.0f);
283
284 EXPECT_FLOAT_EQ(200.0f, test.x());
285 EXPECT_FLOAT_EQ(400.0f, test.y());
286
287 test.scale(0.5f, 0.5f);
288
289 EXPECT_FLOAT_EQ(100.0f, test.x());
290 EXPECT_FLOAT_EQ(200.0f, test.y());
291
292 test.scale(2);
293
294 EXPECT_FLOAT_EQ(200.0f, test.x());
295 EXPECT_FLOAT_EQ(400.0f, test.y());
296
297 test.scale(1.0f, 0.5f);
298
299 EXPECT_FLOAT_EQ(200.0f, test.x());
300 EXPECT_FLOAT_EQ(200.0f, test.y());
301}
302
303TEST(FloatPoint, Normalize)
304{
305 WebCore::FloatPoint a(30.0f, 40.0f);
306
307 a.normalize();
308
309 EXPECT_FLOAT_EQ(0.6, a.x());
310 EXPECT_FLOAT_EQ(0.8, a.y());
311}
312
313TEST(FloatPoint, Dot)
314{
315 WebCore::FloatPoint a(100.0f, 200.0f);
316 WebCore::FloatPoint b(2.0f, 4.0f);
317 WebCore::FloatPoint c(1.0f, 0.5f);
318
319 EXPECT_NEAR(1000.0f, a.dot(b), 0.0001f);
320 EXPECT_NEAR(200.0f, a.dot(c), 0.0001f);
321}
322
323TEST(FloatPoint, LengthSquared)
324{
325 WebCore::FloatPoint test(100.0f, 200.0f);
326
327 EXPECT_FLOAT_EQ(100.0f, test.x());
328 EXPECT_FLOAT_EQ(200.0f, test.y());
329
330 EXPECT_FLOAT_EQ(50000.0f, test.lengthSquared());
331}
332
333TEST(FloatPoint, ConstrainedBetween)
334{
335 WebCore::FloatPoint left(10.0f, 20.0f);
336 WebCore::FloatPoint right(100.0f, 200.0f);
337
338 WebCore::FloatPoint test1(50.0f, 80.0f);
339 WebCore::FloatPoint test2(8.0f, 80.0f);
340 WebCore::FloatPoint test3(50.0f, 220.0f);
341
342 auto constrained1 = test1.constrainedBetween(left, right);
343 EXPECT_FLOAT_EQ(50.0f, constrained1.x());
344 EXPECT_FLOAT_EQ(80.0f, constrained1.y());
345
346 auto constrained2 = test2.constrainedBetween(left, right);
347 EXPECT_FLOAT_EQ(10.0f, constrained2.x());
348 EXPECT_FLOAT_EQ(80.0f, constrained2.y());
349
350 auto constrained3 = test3.constrainedBetween(left, right);
351 EXPECT_FLOAT_EQ(50.0f, constrained3.x());
352 EXPECT_FLOAT_EQ(200.0f, constrained3.y());
353}
354
355TEST(FloatPoint, ShrunkTo)
356{
357 WebCore::FloatPoint big(100.0f, 200.0f);
358 WebCore::FloatPoint smaller(10.0f, 80.0f);
359
360 auto shrunkTo = big.shrunkTo(smaller);
361
362 EXPECT_FLOAT_EQ(10.0f, shrunkTo.x());
363 EXPECT_FLOAT_EQ(80.0f, shrunkTo.y());
364
365 WebCore::FloatPoint bigish(8.0f, 200.0f);
366
367 auto shrunkTo2 = bigish.shrunkTo(smaller);
368
369 EXPECT_FLOAT_EQ(8.0f, shrunkTo2.x());
370 EXPECT_FLOAT_EQ(80.0f, shrunkTo2.y());
371}
372
373TEST(FloatPoint, ExpandedTo)
374{
375 WebCore::FloatPoint big(100.0f, 200.0f);
376 WebCore::FloatPoint smaller(10.0f, 80.0f);
377
378 auto expandedTo = smaller.expandedTo(big);
379
380 EXPECT_FLOAT_EQ(100.0f, expandedTo.x());
381 EXPECT_FLOAT_EQ(200.0f, expandedTo.y());
382
383 WebCore::FloatPoint bigish(8.0f, 300.0f);
384
385 auto expandedTo2 = bigish.expandedTo(big);
386
387 EXPECT_FLOAT_EQ(100.0f, expandedTo2.x());
388 EXPECT_FLOAT_EQ(300.0f, expandedTo2.y());
389}
390
391TEST(FloatPoint, Transpose)
392{
393 WebCore::FloatPoint test(100.0f, 200.0f);
394
395 EXPECT_FLOAT_EQ(100.0f, test.x());
396 EXPECT_FLOAT_EQ(200.0f, test.y());
397
398 auto transposed = test.transposedPoint();
399
400 EXPECT_FLOAT_EQ(200.0f, transposed.x());
401 EXPECT_FLOAT_EQ(100.0f, transposed.y());
402}
403
404TEST(FloatPoint, Transforms)
405{
406 WebCore::FloatPoint test(100.0f, 200.0f);
407
408 WebCore::AffineTransform affine;
409
410 auto transformed1 = test.matrixTransform(affine);
411
412 EXPECT_FLOAT_EQ(100.0f, transformed1.x());
413 EXPECT_FLOAT_EQ(200.0f, transformed1.y());
414
415 WebCore::AffineTransform affine2(2.0, 0.0, 0.0, 2.0, 0.0, 0.0);
416
417 auto transformed2 = test.matrixTransform(affine2);
418
419 EXPECT_FLOAT_EQ(200.0f, transformed2.x());
420 EXPECT_FLOAT_EQ(400.0f, transformed2.y());
421
422 WebCore::TransformationMatrix matrix;
423
424 auto transformed3 = test.matrixTransform(matrix);
425
426 EXPECT_FLOAT_EQ(100.0f, transformed3.x());
427 EXPECT_FLOAT_EQ(200.0f, transformed3.y());
428
429 auto transformed4 = test.matrixTransform(affine2.toTransformationMatrix());
430
431 EXPECT_FLOAT_EQ(200.0f, transformed4.x());
432 EXPECT_FLOAT_EQ(400.0f, transformed4.y());
433}
434
435TEST(FloatPoint, Math)
436{
437 WebCore::FloatPoint a(100.0f, 200.0f);
438 WebCore::FloatPoint b(100.0f, 200.0f);
439
440 a += b;
441
442 EXPECT_FLOAT_EQ(200.0f, a.x());
443 EXPECT_FLOAT_EQ(400.0f, a.y());
444
445 WebCore::FloatSize c(50.0f, 50.0f);
446
447 a += c;
448
449 EXPECT_FLOAT_EQ(250.0f, a.x());
450 EXPECT_FLOAT_EQ(450.0f, a.y());
451
452 WebCore::FloatSize d(10.0f, 200.0f);
453
454 a -= d;
455
456 EXPECT_FLOAT_EQ(240.0f, a.x());
457 EXPECT_FLOAT_EQ(250.0f, a.y());
458
459 WebCore::FloatSize e(100.0f, 200.0f);
460
461 auto f = b + e;
462
463 EXPECT_FLOAT_EQ(200.0f, f.x());
464 EXPECT_FLOAT_EQ(400.0f, f.y());
465
466 WebCore::FloatPoint g(10.0f, 20.0f);
467
468 auto h = b + g;
469
470 EXPECT_FLOAT_EQ(110.0f, h.x());
471 EXPECT_FLOAT_EQ(220.0f, h.y());
472
473 WebCore::FloatSize i = b - g;
474
475 EXPECT_FLOAT_EQ(90.0f, i.width());
476 EXPECT_FLOAT_EQ(180.0f, i.height());
477
478 WebCore::FloatPoint j = b - e;
479
480 EXPECT_FLOAT_EQ(0.0f, j.x());
481 EXPECT_FLOAT_EQ(0.0f, j.y());
482
483 WebCore::FloatPoint negated = -b;
484
485 EXPECT_FLOAT_EQ(-100.0f, negated.x());
486 EXPECT_FLOAT_EQ(-200.0f, negated.y());
487
488 float value = b * g;
489
490 EXPECT_FLOAT_EQ(5000.0f, value);
491}
492
493TEST(FloatPoint, Equality)
494{
495 WebCore::FloatPoint a(100.0f, 200.0f);
496 WebCore::FloatPoint b(100.0f, 200.0f);
497 WebCore::FloatPoint c(10.0f, 20.0f);
498
499 ASSERT_TRUE(a == b);
500 ASSERT_FALSE(a == c);
501 ASSERT_FALSE(a != b);
502 ASSERT_TRUE(a != c);
503
504 ASSERT_TRUE(WebCore::areEssentiallyEqual(a, b));
505 ASSERT_FALSE(WebCore::areEssentiallyEqual(a, c));
506}
507
508TEST(FloatPoint, Floors)
509{
510 WebCore::FloatPoint a(100.6f, 199.9f);
511
512 WebCore::IntSize flooredSize = WebCore::flooredIntSize(a);
513 EXPECT_FLOAT_EQ(100, flooredSize.width());
514 EXPECT_FLOAT_EQ(199, flooredSize.height());
515
516 WebCore::IntPoint flooredPoint = WebCore::flooredIntPoint(a);
517 EXPECT_FLOAT_EQ(100, flooredPoint.x());
518 EXPECT_FLOAT_EQ(199, flooredPoint.y());
519
520 WebCore::FloatPoint flooredPoint1x = WebCore::floorPointToDevicePixels(a, 1.0);
521 EXPECT_FLOAT_EQ(100.0f, flooredPoint1x.x());
522 EXPECT_FLOAT_EQ(199.0f, flooredPoint1x.y());
523
524 WebCore::FloatPoint flooredPoint2x = WebCore::floorPointToDevicePixels(a, 2.0);
525 EXPECT_FLOAT_EQ(100.5f, flooredPoint2x.x());
526 EXPECT_FLOAT_EQ(199.5f, flooredPoint2x.y());
527}
528
529TEST(FloatPoint, Rounding)
530{
531 WebCore::FloatPoint a(100.4f, 199.9f);
532
533 WebCore::IntPoint roundedPoint = WebCore::roundedIntPoint(a);
534 EXPECT_FLOAT_EQ(100, roundedPoint.x());
535 EXPECT_FLOAT_EQ(200, roundedPoint.y());
536}
537
538TEST(FloatPoint, Ceiling)
539{
540 WebCore::FloatPoint a(100.4f, 199.9f);
541
542 WebCore::IntPoint ceilingPoint = WebCore::ceiledIntPoint(a);
543 EXPECT_FLOAT_EQ(101, ceilingPoint.x());
544 EXPECT_FLOAT_EQ(200, ceilingPoint.y());
545
546 WebCore::FloatPoint ceilingPoint1x = WebCore::ceilPointToDevicePixels(a, 1.0);
547 EXPECT_FLOAT_EQ(101.0f, ceilingPoint1x.x());
548 EXPECT_FLOAT_EQ(200.0f, ceilingPoint1x.y());
549
550 WebCore::FloatPoint ceilingPoint2x = WebCore::ceilPointToDevicePixels(a, 2.0);
551 EXPECT_FLOAT_EQ(100.5f, ceilingPoint2x.x());
552 EXPECT_FLOAT_EQ(200.0f, ceilingPoint2x.y());
553}
554
555TEST(FloatPoint, Casting)
556{
557 WebCore::FloatPoint a(100.4f, 199.9f);
558
559 WebCore::FloatSize floatSize = WebCore::toFloatSize(a);
560 EXPECT_FLOAT_EQ(100.4f, floatSize.width());
561 EXPECT_FLOAT_EQ(199.9f, floatSize.height());
562
563 WebCore::FloatSize b(99.6f, 299.1f);
564
565 WebCore::FloatPoint floatPoint = WebCore::toFloatPoint(b);
566 EXPECT_FLOAT_EQ(99.6f, floatPoint.x());
567 EXPECT_FLOAT_EQ(299.1f, floatPoint.y());
568
569#if USE(CG)
570 CGPoint cgPoint = a;
571
572 EXPECT_FLOAT_EQ(100.4f, cgPoint.x);
573 EXPECT_FLOAT_EQ(199.9f, cgPoint.y);
574
575 CGPoint cgPoint2 = CGPointMake(-22.3f, 14.2f);
576
577 WebCore::FloatPoint testCG(cgPoint2);
578
579 EXPECT_FLOAT_EQ(-22.3f, testCG.x());
580 EXPECT_FLOAT_EQ(14.2f, testCG.y());
581#endif
582
583#if PLATFORM(WIN)
584 D2D_POINT_2F d2dPoint = a;
585
586 EXPECT_FLOAT_EQ(100.4f, d2dPoint.x);
587 EXPECT_FLOAT_EQ(199.9f, d2dPoint.y);
588
589 D2D_POINT_2F d2dPoint2 = D2D1::Point2F(-22.3f, 14.2f);
590
591 WebCore::FloatPoint testD2D(d2dPoint2);
592
593 EXPECT_FLOAT_EQ(-22.3f, testD2D.x());
594 EXPECT_FLOAT_EQ(14.2f, testD2D.y());
595#endif
596}
597
598}
599