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 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 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 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 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 SetRectFan(SkPoint v[],SkScalar l,SkScalar t,SkScalar r,SkScalar b,size_t stride)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 SetRectTriStrip(SkPoint v[],SkScalar l,SkScalar t,SkScalar r,SkScalar b,size_t stride)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 } SetRectTriStrip(SkPoint v[],const SkRect & rect,size_t stride)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