Coverage Report

Created: 2024-05-20 07:14

/src/skia/include/private/base/SkPoint_impl.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2006 The Android Open Source Project
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 SkPoint_DEFINED
9
#define SkPoint_DEFINED
10
11
#include "include/private/base/SkAPI.h"
12
#include "include/private/base/SkFloatingPoint.h"
13
#include "include/private/base/SkSafe32.h"
14
15
#include <cmath>
16
#include <cstdint>
17
18
struct SkIPoint;
19
20
/** SkIVector provides an alternative name for SkIPoint. SkIVector and SkIPoint
21
    can be used interchangeably for all purposes.
22
*/
23
typedef SkIPoint SkIVector;
24
25
/** \struct SkIPoint
26
    SkIPoint holds two 32-bit integer coordinates.
27
*/
28
struct SkIPoint {
29
    int32_t fX; //!< x-axis value
30
    int32_t fY; //!< y-axis value
31
32
    /** Sets fX to x, fY to y.
33
34
        @param x  integer x-axis value of constructed SkIPoint
35
        @param y  integer y-axis value of constructed SkIPoint
36
        @return   SkIPoint (x, y)
37
    */
38
53.6k
    static constexpr SkIPoint Make(int32_t x, int32_t y) {
39
53.6k
        return {x, y};
40
53.6k
    }
41
42
    /** Returns x-axis value of SkIPoint.
43
44
        @return  fX
45
    */
46
1.41M
    constexpr int32_t x() const { return fX; }
47
48
    /** Returns y-axis value of SkIPoint.
49
50
        @return  fY
51
    */
52
1.41M
    constexpr int32_t y() const { return fY; }
53
54
    /** Returns true if fX and fY are both zero.
55
56
        @return  true if fX is zero and fY is zero
57
    */
58
0
    bool isZero() const { return (fX | fY) == 0; }
59
60
    /** Sets fX to x and fY to y.
61
62
        @param x  new value for fX
63
        @param y  new value for fY
64
    */
65
337k
    void set(int32_t x, int32_t y) {
66
337k
        fX = x;
67
337k
        fY = y;
68
337k
    }
69
70
    /** Returns SkIPoint changing the signs of fX and fY.
71
72
        @return  SkIPoint as (-fX, -fY)
73
    */
74
49.9k
    SkIPoint operator-() const {
75
49.9k
        return {-fX, -fY};
76
49.9k
    }
77
78
    /** Offsets SkIPoint by ivector v. Sets SkIPoint to (fX + v.fX, fY + v.fY).
79
80
        @param v  ivector to add
81
    */
82
0
    void operator+=(const SkIVector& v) {
83
0
        fX = Sk32_sat_add(fX, v.fX);
84
0
        fY = Sk32_sat_add(fY, v.fY);
85
0
    }
86
87
    /** Subtracts ivector v from SkIPoint. Sets SkIPoint to: (fX - v.fX, fY - v.fY).
88
89
        @param v  ivector to subtract
90
    */
91
1.25k
    void operator-=(const SkIVector& v) {
92
1.25k
        fX = Sk32_sat_sub(fX, v.fX);
93
1.25k
        fY = Sk32_sat_sub(fY, v.fY);
94
1.25k
    }
95
96
    /** Returns true if SkIPoint is equivalent to SkIPoint constructed from (x, y).
97
98
        @param x  value compared with fX
99
        @param y  value compared with fY
100
        @return   true if SkIPoint equals (x, y)
101
    */
102
0
    bool equals(int32_t x, int32_t y) const {
103
0
        return fX == x && fY == y;
104
0
    }
105
106
    /** Returns true if a is equivalent to b.
107
108
        @param a  SkIPoint to compare
109
        @param b  SkIPoint to compare
110
        @return   true if a.fX == b.fX and a.fY == b.fY
111
    */
112
0
    friend bool operator==(const SkIPoint& a, const SkIPoint& b) {
113
0
        return a.fX == b.fX && a.fY == b.fY;
114
0
    }
115
116
    /** Returns true if a is not equivalent to b.
117
118
        @param a  SkIPoint to compare
119
        @param b  SkIPoint to compare
120
        @return   true if a.fX != b.fX or a.fY != b.fY
121
    */
122
0
    friend bool operator!=(const SkIPoint& a, const SkIPoint& b) {
123
0
        return a.fX != b.fX || a.fY != b.fY;
124
0
    }
125
126
    /** Returns ivector from b to a; computed as (a.fX - b.fX, a.fY - b.fY).
127
128
        Can also be used to subtract ivector from ivector, returning ivector.
129
130
        @param a  SkIPoint or ivector to subtract from
131
        @param b  ivector to subtract
132
        @return   ivector from b to a
133
    */
134
4.70k
    friend SkIVector operator-(const SkIPoint& a, const SkIPoint& b) {
135
4.70k
        return { Sk32_sat_sub(a.fX, b.fX), Sk32_sat_sub(a.fY, b.fY) };
136
4.70k
    }
137
138
    /** Returns SkIPoint resulting from SkIPoint a offset by ivector b, computed as:
139
        (a.fX + b.fX, a.fY + b.fY).
140
141
        Can also be used to offset SkIPoint b by ivector a, returning SkIPoint.
142
        Can also be used to add ivector to ivector, returning ivector.
143
144
        @param a  SkIPoint or ivector to add to
145
        @param b  SkIPoint or ivector to add
146
        @return   SkIPoint equal to a offset by b
147
    */
148
0
    friend SkIPoint operator+(const SkIPoint& a, const SkIVector& b) {
149
0
        return { Sk32_sat_add(a.fX, b.fX), Sk32_sat_add(a.fY, b.fY) };
150
0
    }
151
};
152
153
struct SkPoint;
154
155
/** SkVector provides an alternative name for SkPoint. SkVector and SkPoint can
156
    be used interchangeably for all purposes.
157
*/
158
typedef SkPoint SkVector;
159
160
/** \struct SkPoint
161
    SkPoint holds two 32-bit floating point coordinates.
162
*/
163
struct SK_API SkPoint {
164
    float fX; //!< x-axis value
165
    float fY; //!< y-axis value
166
167
    /** Sets fX to x, fY to y. Used both to set SkPoint and vector.
168
169
        @param x  float x-axis value of constructed SkPoint or vector
170
        @param y  float y-axis value of constructed SkPoint or vector
171
        @return   SkPoint (x, y)
172
    */
173
74.7M
    static constexpr SkPoint Make(float x, float y) {
174
74.7M
        return {x, y};
175
74.7M
    }
176
177
    /** Returns x-axis value of SkPoint or vector.
178
179
        @return  fX
180
    */
181
97.3M
    constexpr float x() const { return fX; }
182
183
    /** Returns y-axis value of SkPoint or vector.
184
185
        @return  fY
186
    */
187
97.4M
    constexpr float y() const { return fY; }
188
189
    /** Returns true if fX and fY are both zero.
190
191
        @return  true if fX is zero and fY is zero
192
    */
193
49.9M
    bool isZero() const { return (0 == fX) & (0 == fY); }
194
195
    /** Sets fX to x and fY to y.
196
197
        @param x  new value for fX
198
        @param y  new value for fY
199
    */
200
1.52G
    void set(float x, float y) {
201
1.52G
        fX = x;
202
1.52G
        fY = y;
203
1.52G
    }
204
205
    /** Sets fX to x and fY to y, promoting integers to float values.
206
207
        Assigning a large integer value directly to fX or fY may cause a compiler
208
        error, triggered by narrowing conversion of int to float. This safely
209
        casts x and y to avoid the error.
210
211
        @param x  new value for fX
212
        @param y  new value for fY
213
    */
214
0
    void iset(int32_t x, int32_t y) {
215
0
        fX = static_cast<float>(x);
216
0
        fY = static_cast<float>(y);
217
0
    }
218
219
    /** Sets fX to p.fX and fY to p.fY, promoting integers to float values.
220
221
        Assigning an SkIPoint containing a large integer value directly to fX or fY may
222
        cause a compiler error, triggered by narrowing conversion of int to float.
223
        This safely casts p.fX and p.fY to avoid the error.
224
225
        @param p  SkIPoint members promoted to float
226
    */
227
0
    void iset(const SkIPoint& p) {
228
0
        fX = static_cast<float>(p.fX);
229
0
        fY = static_cast<float>(p.fY);
230
0
    }
231
232
    /** Sets fX to absolute value of pt.fX; and fY to absolute value of pt.fY.
233
234
        @param pt  members providing magnitude for fX and fY
235
    */
236
0
    void setAbs(const SkPoint& pt) {
237
0
        fX = std::abs(pt.fX);
238
0
        fY = std::abs(pt.fY);
239
0
    }
240
241
    /** Adds offset to each SkPoint in points array with count entries.
242
243
        @param points  SkPoint array
244
        @param count   entries in array
245
        @param offset  vector added to points
246
    */
247
0
    static void Offset(SkPoint points[], int count, const SkVector& offset) {
248
0
        Offset(points, count, offset.fX, offset.fY);
249
0
    }
250
251
    /** Adds offset (dx, dy) to each SkPoint in points array of length count.
252
253
        @param points  SkPoint array
254
        @param count   entries in array
255
        @param dx      added to fX in points
256
        @param dy      added to fY in points
257
    */
258
0
    static void Offset(SkPoint points[], int count, float dx, float dy) {
259
0
        for (int i = 0; i < count; ++i) {
260
0
            points[i].offset(dx, dy);
261
0
        }
262
0
    }
263
264
    /** Adds offset (dx, dy) to SkPoint.
265
266
        @param dx  added to fX
267
        @param dy  added to fY
268
    */
269
4.83k
    void offset(float dx, float dy) {
270
4.83k
        fX += dx;
271
4.83k
        fY += dy;
272
4.83k
    }
273
274
    /** Returns the Euclidean distance from origin, computed as:
275
276
            sqrt(fX * fX + fY * fY)
277
278
        .
279
280
        @return  straight-line distance to origin
281
    */
282
288k
    float length() const { return SkPoint::Length(fX, fY); }
283
284
    /** Returns the Euclidean distance from origin, computed as:
285
286
            sqrt(fX * fX + fY * fY)
287
288
        .
289
290
        @return  straight-line distance to origin
291
    */
292
0
    float distanceToOrigin() const { return this->length(); }
293
294
    /** Scales (fX, fY) so that length() returns one, while preserving ratio of fX to fY,
295
        if possible. If prior length is nearly zero, sets vector to (0, 0) and returns
296
        false; otherwise returns true.
297
298
        @return  true if former length is not zero or nearly zero
299
300
        example: https://fiddle.skia.org/c/@Point_normalize_2
301
    */
302
    bool normalize();
303
304
    /** Sets vector to (x, y) scaled so length() returns one, and so that
305
        (fX, fY) is proportional to (x, y).  If (x, y) length is nearly zero,
306
        sets vector to (0, 0) and returns false; otherwise returns true.
307
308
        @param x  proportional value for fX
309
        @param y  proportional value for fY
310
        @return   true if (x, y) length is not zero or nearly zero
311
312
        example: https://fiddle.skia.org/c/@Point_setNormalize
313
    */
314
    bool setNormalize(float x, float y);
315
316
    /** Scales vector so that distanceToOrigin() returns length, if possible. If former
317
        length is nearly zero, sets vector to (0, 0) and return false; otherwise returns
318
        true.
319
320
        @param length  straight-line distance to origin
321
        @return        true if former length is not zero or nearly zero
322
323
        example: https://fiddle.skia.org/c/@Point_setLength
324
    */
325
    bool setLength(float length);
326
327
    /** Sets vector to (x, y) scaled to length, if possible. If former
328
        length is nearly zero, sets vector to (0, 0) and return false; otherwise returns
329
        true.
330
331
        @param x       proportional value for fX
332
        @param y       proportional value for fY
333
        @param length  straight-line distance to origin
334
        @return        true if (x, y) length is not zero or nearly zero
335
336
        example: https://fiddle.skia.org/c/@Point_setLength_2
337
    */
338
    bool setLength(float x, float y, float length);
339
340
    /** Sets dst to SkPoint times scale. dst may be SkPoint to modify SkPoint in place.
341
342
        @param scale  factor to multiply SkPoint by
343
        @param dst    storage for scaled SkPoint
344
345
        example: https://fiddle.skia.org/c/@Point_scale
346
    */
347
    void scale(float scale, SkPoint* dst) const;
348
349
    /** Scales SkPoint in place by scale.
350
351
        @param value  factor to multiply SkPoint by
352
    */
353
5.00M
    void scale(float value) { this->scale(value, this); }
354
355
    /** Changes the sign of fX and fY.
356
    */
357
3.35M
    void negate() {
358
3.35M
        fX = -fX;
359
3.35M
        fY = -fY;
360
3.35M
    }
361
362
    /** Returns SkPoint changing the signs of fX and fY.
363
364
        @return  SkPoint as (-fX, -fY)
365
    */
366
3.78M
    SkPoint operator-() const {
367
3.78M
        return {-fX, -fY};
368
3.78M
    }
369
370
    /** Adds vector v to SkPoint. Sets SkPoint to: (fX + v.fX, fY + v.fY).
371
372
        @param v  vector to add
373
    */
374
95.1M
    void operator+=(const SkVector& v) {
375
95.1M
        fX += v.fX;
376
95.1M
        fY += v.fY;
377
95.1M
    }
378
379
    /** Subtracts vector v from SkPoint. Sets SkPoint to: (fX - v.fX, fY - v.fY).
380
381
        @param v  vector to subtract
382
    */
383
2.95M
    void operator-=(const SkVector& v) {
384
2.95M
        fX -= v.fX;
385
2.95M
        fY -= v.fY;
386
2.95M
    }
387
388
    /** Returns SkPoint multiplied by scale.
389
390
        @param scale  float to multiply by
391
        @return       SkPoint as (fX * scale, fY * scale)
392
    */
393
126M
    SkPoint operator*(float scale) const {
394
126M
        return {fX * scale, fY * scale};
395
126M
    }
396
397
    /** Multiplies SkPoint by scale. Sets SkPoint to: (fX * scale, fY * scale).
398
399
        @param scale  float to multiply by
400
        @return       reference to SkPoint
401
    */
402
21.4M
    SkPoint& operator*=(float scale) {
403
21.4M
        fX *= scale;
404
21.4M
        fY *= scale;
405
21.4M
        return *this;
406
21.4M
    }
407
408
    /** Returns true if both fX and fY are measurable values.
409
410
        @return  true for values other than infinities and NaN
411
    */
412
273M
    bool isFinite() const {
413
273M
        return SkIsFinite(fX, fY);
414
273M
    }
415
416
    /** Returns true if SkPoint is equivalent to SkPoint constructed from (x, y).
417
418
        @param x  value compared with fX
419
        @param y  value compared with fY
420
        @return   true if SkPoint equals (x, y)
421
    */
422
7.27M
    bool equals(float x, float y) const {
423
7.27M
        return fX == x && fY == y;
424
7.27M
    }
425
426
    /** Returns true if a is equivalent to b.
427
428
        @param a  SkPoint to compare
429
        @param b  SkPoint to compare
430
        @return   true if a.fX == b.fX and a.fY == b.fY
431
    */
432
35.3G
    friend bool operator==(const SkPoint& a, const SkPoint& b) {
433
35.3G
        return a.fX == b.fX && a.fY == b.fY;
434
35.3G
    }
435
436
    /** Returns true if a is not equivalent to b.
437
438
        @param a  SkPoint to compare
439
        @param b  SkPoint to compare
440
        @return   true if a.fX != b.fX or a.fY != b.fY
441
    */
442
780M
    friend bool operator!=(const SkPoint& a, const SkPoint& b) {
443
780M
        return a.fX != b.fX || a.fY != b.fY;
444
780M
    }
445
446
    /** Returns vector from b to a, computed as (a.fX - b.fX, a.fY - b.fY).
447
448
        Can also be used to subtract vector from SkPoint, returning SkPoint.
449
        Can also be used to subtract vector from vector, returning vector.
450
451
        @param a  SkPoint to subtract from
452
        @param b  SkPoint to subtract
453
        @return   vector from b to a
454
    */
455
1.78G
    friend SkVector operator-(const SkPoint& a, const SkPoint& b) {
456
1.78G
        return {a.fX - b.fX, a.fY - b.fY};
457
1.78G
    }
458
459
    /** Returns SkPoint resulting from SkPoint a offset by vector b, computed as:
460
        (a.fX + b.fX, a.fY + b.fY).
461
462
        Can also be used to offset SkPoint b by vector a, returning SkPoint.
463
        Can also be used to add vector to vector, returning vector.
464
465
        @param a  SkPoint or vector to add to
466
        @param b  SkPoint or vector to add
467
        @return   SkPoint equal to a offset by b
468
    */
469
286M
    friend SkPoint operator+(const SkPoint& a, const SkVector& b) {
470
286M
        return {a.fX + b.fX, a.fY + b.fY};
471
286M
    }
472
473
    /** Returns the Euclidean distance from origin, computed as:
474
475
            sqrt(x * x + y * y)
476
477
        .
478
479
        @param x  component of length
480
        @param y  component of length
481
        @return   straight-line distance to origin
482
483
        example: https://fiddle.skia.org/c/@Point_Length
484
    */
485
    static float Length(float x, float y);
486
487
    /** Scales (vec->fX, vec->fY) so that length() returns one, while preserving ratio of vec->fX
488
        to vec->fY, if possible. If original length is nearly zero, sets vec to (0, 0) and returns
489
        zero; otherwise, returns length of vec before vec is scaled.
490
491
        Returned prior length may be INFINITY if it can not be represented by float.
492
493
        Note that normalize() is faster if prior length is not required.
494
495
        @param vec  normalized to unit length
496
        @return     original vec length
497
498
        example: https://fiddle.skia.org/c/@Point_Normalize
499
    */
500
    static float Normalize(SkVector* vec);
501
502
    /** Returns the Euclidean distance between a and b.
503
504
        @param a  line end point
505
        @param b  line end point
506
        @return   straight-line distance from a to b
507
    */
508
56.8M
    static float Distance(const SkPoint& a, const SkPoint& b) {
509
56.8M
        return Length(a.fX - b.fX, a.fY - b.fY);
510
56.8M
    }
511
512
    /** Returns the dot product of vector a and vector b.
513
514
        @param a  left side of dot product
515
        @param b  right side of dot product
516
        @return   product of input magnitudes and cosine of the angle between them
517
    */
518
1.47G
    static float DotProduct(const SkVector& a, const SkVector& b) {
519
1.47G
        return a.fX * b.fX + a.fY * b.fY;
520
1.47G
    }
521
522
    /** Returns the cross product of vector a and vector b.
523
524
        a and b form three-dimensional vectors with z-axis value equal to zero. The
525
        cross product is a three-dimensional vector with x-axis and y-axis values equal
526
        to zero. The cross product z-axis component is returned.
527
528
        @param a  left side of cross product
529
        @param b  right side of cross product
530
        @return   area spanned by vectors signed by angle direction
531
    */
532
1.06G
    static float CrossProduct(const SkVector& a, const SkVector& b) {
533
1.06G
        return a.fX * b.fY - a.fY * b.fX;
534
1.06G
    }
535
536
    /** Returns the cross product of vector and vec.
537
538
        Vector and vec form three-dimensional vectors with z-axis value equal to zero.
539
        The cross product is a three-dimensional vector with x-axis and y-axis values
540
        equal to zero. The cross product z-axis component is returned.
541
542
        @param vec  right side of cross product
543
        @return     area spanned by vectors signed by angle direction
544
    */
545
1.04G
    float cross(const SkVector& vec) const {
546
1.04G
        return CrossProduct(*this, vec);
547
1.04G
    }
548
549
    /** Returns the dot product of vector and vector vec.
550
551
        @param vec  right side of dot product
552
        @return     product of input magnitudes and cosine of the angle between them
553
    */
554
157M
    float dot(const SkVector& vec) const {
555
157M
        return DotProduct(*this, vec);
556
157M
    }
557
558
};
559
560
#endif