summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-05-06 19:26:26 +0000
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-05-06 19:26:26 +0000
commit98a5211c4b27cf865eade6696ce3cf5ff8b95baf (patch)
tree1a1cd96ad246a83227e8ae088efee1b9ecfebe82 /core
parent5787a30168c5581642a24ba3166d7efc24cc3de0 (diff)
downloadsrc-98a5211c4b27cf865eade6696ce3cf5ff8b95baf.tar.gz
use SkPoint, creating an alias for GrPoint
http://codereview.appspot.com/4498041/ git-svn-id: http://skia.googlecode.com/svn/trunk/src@1268 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'core')
-rw-r--r--core/SkPoint.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/core/SkPoint.cpp b/core/SkPoint.cpp
index feca12f7..b5941d58 100644
--- a/core/SkPoint.cpp
+++ b/core/SkPoint.cpp
@@ -36,6 +36,29 @@ void SkIPoint::rotateCCW(SkIPoint* dst) const {
///////////////////////////////////////////////////////////////////////////////
+void SkPoint::setIRectFan(int l, int t, int r, int b, size_t stride) {
+ SkASSERT(stride >= sizeof(SkPoint));
+
+ ((SkPoint*)((intptr_t)this + 0 * stride))->set(SkIntToScalar(l),
+ SkIntToScalar(t));
+ ((SkPoint*)((intptr_t)this + 1 * stride))->set(SkIntToScalar(l),
+ SkIntToScalar(b));
+ ((SkPoint*)((intptr_t)this + 2 * stride))->set(SkIntToScalar(r),
+ SkIntToScalar(b));
+ ((SkPoint*)((intptr_t)this + 3 * stride))->set(SkIntToScalar(r),
+ SkIntToScalar(t));
+}
+
+void SkPoint::setRectFan(SkScalar l, SkScalar t, SkScalar r, SkScalar b,
+ size_t stride) {
+ SkASSERT(stride >= sizeof(SkPoint));
+
+ ((SkPoint*)((intptr_t)this + 0 * stride))->set(l, t);
+ ((SkPoint*)((intptr_t)this + 1 * stride))->set(l, b);
+ ((SkPoint*)((intptr_t)this + 2 * stride))->set(r, b);
+ ((SkPoint*)((intptr_t)this + 3 * stride))->set(r, t);
+}
+
void SkPoint::rotateCW(SkPoint* dst) const {
SkASSERT(dst);
@@ -343,3 +366,39 @@ bool SkPoint::setLength(SkFixed ox, SkFixed oy, SkFixed length) {
#endif
+///////////////////////////////////////////////////////////////////////////////
+
+SkScalar SkPoint::distanceToLineSegmentBetweenSqd(const SkPoint& a,
+ const SkPoint& b) const {
+ // See comments to distanceToLineBetweenSqd. If the projection of c onto
+ // u is between a and b then this returns the same result as that
+ // function. Otherwise, it returns the distance to the closer of a and
+ // b. Let the projection of v onto u be v'. There are three cases:
+ // 1. v' points opposite to u. c is not between a and b and is closer
+ // to a than b.
+ // 2. v' points along u and has magnitude less than y. c is between
+ // a and b and the distance to the segment is the same as distance
+ // to the line ab.
+ // 3. v' points along u and has greater magnitude than u. c is not
+ // not between a and b and is closer to b than a.
+ // v' = (u dot v) * u / |u|. So if (u dot v)/|u| is less than zero we're
+ // in case 1. If (u dot v)/|u| is > |u| we are in case 3. Otherwise
+ // we're in case 2. We actually compare (u dot v) to 0 and |u|^2 to
+ // avoid a sqrt to compute |u|.
+
+ SkVector u = b - a;
+ SkVector v = *this - a;
+
+ SkScalar uLengthSqd = u.lengthSqd();
+ SkScalar uDotV = SkPoint::DotProduct(u, v);
+
+ if (uDotV <= 0) {
+ return v.lengthSqd();
+ } else if (uDotV > uLengthSqd) {
+ return b.distanceToSqd(*this);
+ } else {
+ SkScalar det = u.cross(v);
+ return SkScalarMulDiv(det, det, uLengthSqd);
+ }
+}
+