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