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 "SkPoint.h" 12 13 class SkPointPriv { 14 public: 15 enum Side { 16 kLeft_Side = -1, 17 kOn_Side = 0, 18 kRight_Side = 1, 19 }; 20 AreFinite(const SkPoint array[],int count)21 static bool AreFinite(const SkPoint array[], int count) { 22 return SkScalarsAreFinite(&array[0].fX, count << 1); 23 } 24 AsScalars(const SkPoint & pt)25 static const SkScalar* AsScalars(const SkPoint& pt) { return &pt.fX; } 26 CanNormalize(SkScalar dx,SkScalar dy)27 static bool CanNormalize(SkScalar dx, SkScalar dy) { 28 // Simple enough (and performance critical sometimes) so we inline it. 29 return (dx*dx + dy*dy) > (SK_ScalarNearlyZero * SK_ScalarNearlyZero); 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 DistanceToLineSegmentBetween(const SkPoint & pt,const SkPoint & a,const SkPoint & b)43 static SkScalar DistanceToLineSegmentBetween(const SkPoint& pt, const SkPoint& a, 44 const SkPoint& b) { 45 return SkScalarSqrt(DistanceToLineSegmentBetweenSqd(pt, a, b)); 46 } 47 DistanceToSqd(const SkPoint & pt,const SkPoint & a)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 EqualsWithinTolerance(const SkPoint & p1,const SkPoint & p2)54 static bool EqualsWithinTolerance(const SkPoint& p1, const SkPoint& p2) { 55 return !CanNormalize(p1.fX - p2.fX, p1.fY - p2.fY); 56 } 57 EqualsWithinTolerance(const SkPoint & pt,const SkPoint & p,SkScalar tol)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 LengthSqd(const SkPoint & pt)63 static SkScalar LengthSqd(const SkPoint& pt) { 64 return SkPoint::DotProduct(pt, pt); 65 } 66 Negate(SkIPoint & pt)67 static void Negate(SkIPoint& pt) { 68 pt.fX = -pt.fX; 69 pt.fY = -pt.fY; 70 } 71 RotateCCW(const SkPoint & src,SkPoint * dst)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 RotateCCW(SkPoint * pt)79 static void RotateCCW(SkPoint* pt) { 80 RotateCCW(*pt, pt); 81 } 82 RotateCW(const SkPoint & src,SkPoint * dst)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 RotateCW(SkPoint * pt)90 static void RotateCW(SkPoint* pt) { 91 RotateCW(*pt, pt); 92 } 93 94 static bool SetLengthFast(SkPoint* pt, float length); 95 96 static void SetOrthog(SkPoint* pt, const SkPoint& vec, Side side = kLeft_Side) { 97 // vec could be this 98 SkScalar tmp = vec.fX; 99 if (kRight_Side == side) { 100 pt->fX = -vec.fY; 101 pt->fY = tmp; 102 } else { 103 SkASSERT(kLeft_Side == side); 104 pt->fX = vec.fY; 105 pt->fY = -tmp; 106 } 107 } 108 109 // counter-clockwise fan SetRectFan(SkPoint v[],SkScalar l,SkScalar t,SkScalar r,SkScalar b,size_t stride)110 static void SetRectFan(SkPoint v[], SkScalar l, SkScalar t, SkScalar r, SkScalar b, 111 size_t stride) { 112 SkASSERT(stride >= sizeof(SkPoint)); 113 114 ((SkPoint*)((intptr_t)v + 0 * stride))->set(l, t); 115 ((SkPoint*)((intptr_t)v + 1 * stride))->set(l, b); 116 ((SkPoint*)((intptr_t)v + 2 * stride))->set(r, b); 117 ((SkPoint*)((intptr_t)v + 3 * stride))->set(r, t); 118 } 119 120 // tri strip with two counter-clockwise triangles SetRectTriStrip(SkPoint v[],SkScalar l,SkScalar t,SkScalar r,SkScalar b,size_t stride)121 static void SetRectTriStrip(SkPoint v[], SkScalar l, SkScalar t, SkScalar r, SkScalar b, 122 size_t stride) { 123 SkASSERT(stride >= sizeof(SkPoint)); 124 125 ((SkPoint*)((intptr_t)v + 0 * stride))->set(l, t); 126 ((SkPoint*)((intptr_t)v + 1 * stride))->set(l, b); 127 ((SkPoint*)((intptr_t)v + 2 * stride))->set(r, t); 128 ((SkPoint*)((intptr_t)v + 3 * stride))->set(r, b); 129 } 130 131 }; 132 133 #endif 134