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 SkPointPriv_DEFINED |
9 | #define SkPointPriv_DEFINED |
10 | |
11 | #include "include/core/SkPoint.h" |
12 | #include "include/core/SkRect.h" |
13 | |
14 | class SkPointPriv { |
15 | public: |
16 | enum Side { |
17 | kLeft_Side = -1, |
18 | kOn_Side = 0, |
19 | kRight_Side = 1, |
20 | }; |
21 | |
22 | static bool AreFinite(const SkPoint array[], int count) { |
23 | return SkScalarsAreFinite(&array[0].fX, count << 1); |
24 | } |
25 | |
26 | static const SkScalar* AsScalars(const SkPoint& pt) { return &pt.fX; } |
27 | |
28 | static bool CanNormalize(SkScalar dx, SkScalar dy) { |
29 | return SkScalarsAreFinite(dx, dy) && (dx || dy); |
30 | } |
31 | |
32 | static SkScalar DistanceToLineBetweenSqd(const SkPoint& pt, const SkPoint& a, |
33 | const SkPoint& b, Side* side = nullptr); |
34 | |
35 | static SkScalar DistanceToLineBetween(const SkPoint& pt, const SkPoint& a, |
36 | const SkPoint& b, Side* side = nullptr) { |
37 | return SkScalarSqrt(DistanceToLineBetweenSqd(pt, a, b, side)); |
38 | } |
39 | |
40 | static SkScalar DistanceToLineSegmentBetweenSqd(const SkPoint& pt, const SkPoint& a, |
41 | const SkPoint& b); |
42 | |
43 | static SkScalar DistanceToLineSegmentBetween(const SkPoint& pt, const SkPoint& a, |
44 | const SkPoint& b) { |
45 | return SkScalarSqrt(DistanceToLineSegmentBetweenSqd(pt, a, b)); |
46 | } |
47 | |
48 | static SkScalar DistanceToSqd(const SkPoint& pt, const SkPoint& a) { |
49 | SkScalar dx = pt.fX - a.fX; |
50 | SkScalar dy = pt.fY - a.fY; |
51 | return dx * dx + dy * dy; |
52 | } |
53 | |
54 | static bool EqualsWithinTolerance(const SkPoint& p1, const SkPoint& p2) { |
55 | return !CanNormalize(p1.fX - p2.fX, p1.fY - p2.fY); |
56 | } |
57 | |
58 | static bool EqualsWithinTolerance(const SkPoint& pt, const SkPoint& p, SkScalar tol) { |
59 | return SkScalarNearlyZero(pt.fX - p.fX, tol) |
60 | && SkScalarNearlyZero(pt.fY - p.fY, tol); |
61 | } |
62 | |
63 | static SkScalar LengthSqd(const SkPoint& pt) { |
64 | return SkPoint::DotProduct(pt, pt); |
65 | } |
66 | |
67 | static void Negate(SkIPoint& pt) { |
68 | pt.fX = -pt.fX; |
69 | pt.fY = -pt.fY; |
70 | } |
71 | |
72 | static void RotateCCW(const SkPoint& src, SkPoint* dst) { |
73 | // use a tmp in case src == dst |
74 | SkScalar tmp = src.fX; |
75 | dst->fX = src.fY; |
76 | dst->fY = -tmp; |
77 | } |
78 | |
79 | static void RotateCCW(SkPoint* pt) { |
80 | RotateCCW(*pt, pt); |
81 | } |
82 | |
83 | static void RotateCW(const SkPoint& src, SkPoint* dst) { |
84 | // use a tmp in case src == dst |
85 | SkScalar tmp = src.fX; |
86 | dst->fX = -src.fY; |
87 | dst->fY = tmp; |
88 | } |
89 | |
90 | static void RotateCW(SkPoint* pt) { |
91 | RotateCW(*pt, pt); |
92 | } |
93 | |
94 | static bool SetLengthFast(SkPoint* pt, float length); |
95 | |
96 | static SkPoint MakeOrthog(const SkPoint& vec, Side side = kLeft_Side) { |
97 | SkASSERT(side == kRight_Side || side == kLeft_Side); |
98 | return (side == kRight_Side) ? SkPoint{-vec.fY, vec.fX} : SkPoint{vec.fY, -vec.fX}; |
99 | } |
100 | |
101 | // counter-clockwise fan |
102 | static void SetRectFan(SkPoint v[], SkScalar l, SkScalar t, SkScalar r, SkScalar b, |
103 | size_t stride) { |
104 | SkASSERT(stride >= sizeof(SkPoint)); |
105 | |
106 | ((SkPoint*)((intptr_t)v + 0 * stride))->set(l, t); |
107 | ((SkPoint*)((intptr_t)v + 1 * stride))->set(l, b); |
108 | ((SkPoint*)((intptr_t)v + 2 * stride))->set(r, b); |
109 | ((SkPoint*)((intptr_t)v + 3 * stride))->set(r, t); |
110 | } |
111 | |
112 | // tri strip with two counter-clockwise triangles |
113 | static void SetRectTriStrip(SkPoint v[], SkScalar l, SkScalar t, SkScalar r, SkScalar b, |
114 | size_t stride) { |
115 | SkASSERT(stride >= sizeof(SkPoint)); |
116 | |
117 | ((SkPoint*)((intptr_t)v + 0 * stride))->set(l, t); |
118 | ((SkPoint*)((intptr_t)v + 1 * stride))->set(l, b); |
119 | ((SkPoint*)((intptr_t)v + 2 * stride))->set(r, t); |
120 | ((SkPoint*)((intptr_t)v + 3 * stride))->set(r, b); |
121 | } |
122 | static void SetRectTriStrip(SkPoint v[], const SkRect& rect, size_t stride) { |
123 | SetRectTriStrip(v, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, stride); |
124 | } |
125 | }; |
126 | |
127 | #endif |
128 | |