add gpu backend (not hooked up yet)



git-svn-id: http://skia.googlecode.com/svn/trunk@649 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrPoint.h b/gpu/include/GrPoint.h
new file mode 100644
index 0000000..bb24959
--- /dev/null
+++ b/gpu/include/GrPoint.h
@@ -0,0 +1,287 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrPoint_DEFINED
+#define GrPoint_DEFINED
+
+#include "GrTypes.h"
+#include "GrScalar.h"
+
+/**
+ *  2D Point struct
+ */
+struct GrPoint {
+public:
+    GrScalar fX, fY;
+
+    GrPoint() {}
+    GrPoint(GrScalar x, GrScalar y) { fX = x; fY = y; }
+    
+    GrScalar x() const { return fX; }
+    GrScalar y() const { return fY; }
+
+    void set(GrScalar x, GrScalar y) {
+        fX = x;
+        fY = y;
+    }
+    
+    void setAsMidPoint(const GrPoint& a, const GrPoint& b) {
+        fX = GrScalarAve(a.fX, b.fX);
+        fY = GrScalarAve(a.fY, b.fY);
+    }
+
+    void offset(GrScalar dx, GrScalar dy) {
+        fX += dx;
+        fY += dy;
+    }
+
+    GrScalar distanceToSqd(const GrPoint& p) const {
+        GrScalar dx = (p.fX - fX);
+        GrScalar dy = (p.fY - fY);
+        return GrMul(dx, dx) + GrMul(dy, dy);
+    }
+    
+    GrScalar distanceTo(const GrPoint& p) const {
+        // TODO: fixed point sqrt
+        return GrFloatToScalar(sqrtf(GrScalarToFloat(distanceToSqd(p))));
+    }
+    
+    GrScalar distanceToOriginSqd() const {
+        return GrMul(fX, fX) + GrMul(fY, fY);
+    }
+
+    GrScalar distanceToOrigin() const {
+        return GrFloatToScalar(sqrtf(GrScalarToFloat(distanceToOriginSqd())));
+    }
+    
+    inline GrScalar distanceToLineBetweenSqd(const GrPoint& a, 
+                                             const GrPoint& b) const;
+
+    inline GrScalar distanceToLineBetween(const GrPoint& a, 
+                                          const GrPoint& b) const;
+    
+    inline GrScalar distanceToLineSegmentBetweenSqd(const GrPoint& a, 
+                                                    const GrPoint& b) const;
+    
+    inline GrScalar distanceToLineSegmentBetween(const GrPoint& a, 
+                                                 const GrPoint& b) const;
+    
+    // counter-clockwise fan
+    void setRectFan(GrScalar l, GrScalar t, GrScalar r, GrScalar b) {
+        GrPoint* v = this;
+        v[0].set(l, t);
+        v[1].set(l, b);
+        v[2].set(r, b);
+        v[3].set(r, t);
+    }
+    
+    void setRectFan(GrScalar l, GrScalar t, GrScalar r, GrScalar b, size_t stride) {
+        GrAssert(stride >= sizeof(GrPoint));
+        ((GrPoint*)((intptr_t)this + 0 * stride))->set(l, t);
+        ((GrPoint*)((intptr_t)this + 1 * stride))->set(l, b);
+        ((GrPoint*)((intptr_t)this + 2 * stride))->set(r, b);
+        ((GrPoint*)((intptr_t)this + 3 * stride))->set(r, t);
+    }
+    
+    // counter-clockwise fan
+    void setIRectFan(int l, int t, int r, int b) {
+        GrPoint* v = this;
+        v[0].set(GrIntToScalar(l), GrIntToScalar(t));
+        v[1].set(GrIntToScalar(l), GrIntToScalar(b));
+        v[2].set(GrIntToScalar(r), GrIntToScalar(b));
+        v[3].set(GrIntToScalar(r), GrIntToScalar(t));
+    }
+    
+    void setIRectFan(int l, int t, int r, int b, size_t stride) {
+        GrAssert(stride >= sizeof(GrPoint));
+        ((GrPoint*)((intptr_t)this + 0 * stride))->set(GrIntToScalar(l), 
+                                                      GrIntToScalar(t));
+        ((GrPoint*)((intptr_t)this + 1 * stride))->set(GrIntToScalar(l), 
+                                                      GrIntToScalar(b));
+        ((GrPoint*)((intptr_t)this + 2 * stride))->set(GrIntToScalar(r), 
+                                                      GrIntToScalar(b));
+        ((GrPoint*)((intptr_t)this + 3 * stride))->set(GrIntToScalar(r), 
+                                                      GrIntToScalar(t));
+    }
+    
+    bool operator ==(const GrPoint& p) const {
+        return fX == p.fX && fY == p.fY;
+    }
+    
+    bool operator !=(const GrPoint& p) const {
+        return fX != p.fX || fY != p.fY;
+    }
+};
+
+struct GrIPoint16 {
+    int16_t fX, fY;
+    
+    void set(intptr_t x, intptr_t y) {
+        fX = GrToS16(x);
+        fY = GrToS16(y);
+    }
+};
+
+struct GrVec {
+public:
+    GrScalar fX, fY;
+    
+    GrVec() {}
+    GrVec(GrScalar x, GrScalar y) { fX = x; fY = y; }
+    
+    GrScalar x() const { return fX; }
+    GrScalar y() const { return fY; }
+    
+    /**
+     * set x and y length of the vector.
+     */
+    void set(GrScalar x, GrScalar y) {
+        fX = x;
+        fY = y;
+    }
+    
+    /**
+     * set vector to point from a to b.
+     */
+    void setBetween(const GrPoint& a, const GrPoint& b) {
+        fX = b.fX - a.fX;
+        fY = b.fY - a.fY;
+    }
+      
+    /**
+     * length of the vector squared.
+     */
+    GrScalar lengthSqd() const {
+        return GrMul(fX, fX) + GrMul(fY, fY);
+    }
+    
+    /**
+     * length of the vector.
+     */
+    GrScalar length() const {
+        // TODO: fixed point sqrt
+        return GrFloatToScalar(sqrtf(GrScalarToFloat(lengthSqd())));
+    }
+    
+    /**
+     * normalizes the vector if it's length is not 0.
+     * @return true if normalized, otherwise false.
+     */
+    bool normalize() {
+        GrScalar l = lengthSqd();
+        if (l) {
+            // TODO: fixed point sqrt and invert
+            l = 1 / sqrtf(l);
+            fX *= l;
+            fY *= l;
+            return true;
+        }
+        return false;
+    }
+    
+    /**
+     * Dot product of this with vec.
+     */
+    GrScalar dot(const GrVec& vec) const {
+        return GrMul(vec.fX, fX) + GrMul(vec.fY, fY);
+    }
+   
+    /**
+     * z-value of this cross vec.
+     */
+    GrScalar cross(const GrVec& vec) const {
+        return GrMul(fX, vec.fY) - GrMul(fY, vec.fX);
+    }
+    
+    bool operator ==(const GrPoint& p) const {
+        return fX == p.fX && fY == p.fY;
+    }
+    
+    bool operator !=(const GrPoint& p) const {
+        return fX != p.fX || fY != p.fY;
+    }
+};
+
+GrScalar GrPoint::distanceToLineBetweenSqd(const GrPoint& a, 
+                                           const GrPoint& b) const {
+    // Let d be the distance between c (this) and line ab.
+    // The area of the triangle defined by a, b, and c is 
+    // A = |b-a|*d/2. Let u = b-a and v = c-a. The cross product of
+    // u and v is aligned with the z axis and its magnitude is 2A. 
+    // So d = |u x v| / |u|.
+    GrVec u, v;
+    u.setBetween(a,b);
+    v.setBetween(a,*this);
+    
+    GrScalar det = u.cross(v);
+    return (GrMul(det, det)) / u.lengthSqd();
+}
+
+GrScalar GrPoint::distanceToLineBetween(const GrPoint& a, 
+                                        const GrPoint& b) const {
+    GrVec u, v;
+    u.setBetween(a,b);
+    v.setBetween(a,*this);
+    
+    GrScalar det = u.cross(v);
+    return (GrScalarAbs(det)) / u.length();
+}
+
+GrScalar GrPoint::distanceToLineSegmentBetweenSqd(const GrPoint& a, 
+                                                  const GrPoint& 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|.
+    
+    GrVec u, v;
+    u.setBetween(a,b);
+    v.setBetween(a,*this);
+    
+    GrScalar uLengthSqd = u.lengthSqd();
+    GrScalar uDotV = u.dot(v);
+    
+    if (uDotV <= 0) {
+        return v.lengthSqd();
+    } else if (uDotV > uLengthSqd) {
+        return b.distanceToSqd(*this);
+    } else {
+        GrScalar det = u.cross(v);
+        return (GrMul(det, det)) / uLengthSqd;
+    }
+}
+
+GrScalar GrPoint::distanceToLineSegmentBetween(const GrPoint& a, 
+                                               const GrPoint& b) const {
+    // TODO: fixed point sqrt
+    return GrFloatToScalar(sqrtf(GrScalarToFloat(distanceToLineSegmentBetweenSqd(a,b))));
+}
+
+
+#endif
+