17839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/*
27839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Copyright 2012 Google Inc.
37839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger *
47839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be
57839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * found in the LICENSE file.
67839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */
77839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#ifndef SkPathOpsPoint_DEFINED
87839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#define SkPathOpsPoint_DEFINED
97839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkPathOpsTypes.h"
117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkPoint.h"
127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerinline bool AlmostEqualUlps(const SkPoint& pt1, const SkPoint& pt2) {
147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return AlmostEqualUlps(pt1.fX, pt2.fX) && AlmostEqualUlps(pt1.fY, pt2.fY);
157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstruct SkDVector {
187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    double fX, fY;
197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    friend SkDPoint operator+(const SkDPoint& a, const SkDVector& b);
217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void operator+=(const SkDVector& v) {
237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fX += v.fX;
247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fY += v.fY;
257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void operator-=(const SkDVector& v) {
287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fX -= v.fX;
297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fY -= v.fY;
307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void operator/=(const double s) {
337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fX /= s;
347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fY /= s;
357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void operator*=(const double s) {
387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fX *= s;
397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fY *= s;
407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkVector asSkVector() const {
437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkVector v = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)};
447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return v;
457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    double cross(const SkDVector& a) const {
487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fX * a.fY - fY * a.fX;
497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    double dot(const SkDVector& a) const {
527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fX * a.fX + fY * a.fY;
537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    double length() const {
567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return sqrt(lengthSquared());
577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    double lengthSquared() const {
607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fX * fX + fY * fY;
617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstruct SkDPoint {
657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    double fX;
667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    double fY;
677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void set(const SkPoint& pt) {
697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fX = pt.fX;
707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fY = pt.fY;
717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    friend SkDVector operator-(const SkDPoint& a, const SkDPoint& b);
747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    friend bool operator==(const SkDPoint& a, const SkDPoint& b) {
767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return a.fX == b.fX && a.fY == b.fY;
777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    friend bool operator!=(const SkDPoint& a, const SkDPoint& b) {
807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return a.fX != b.fX || a.fY != b.fY;
817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void operator=(const SkPoint& pt) {
847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fX = pt.fX;
857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fY = pt.fY;
867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void operator+=(const SkDVector& v) {
907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fX += v.fX;
917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fY += v.fY;
927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void operator-=(const SkDVector& v) {
957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fX -= v.fX;
967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fY -= v.fY;
977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // note: this can not be implemented with
1007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // return approximately_equal(a.fY, fY) && approximately_equal(a.fX, fX);
1010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // because that will not take the magnitude of the values into account
1027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool approximatelyEqual(const SkDPoint& a) const {
1030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (approximately_equal(fX, a.fX) && approximately_equal(fY, a.fY)) {
1047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            return true;
1057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (!RoughlyEqualUlps(fX, a.fX) || !RoughlyEqualUlps(fY, a.fY)) {
1070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return false;
1080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
1090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        double dist = distance(a);  // OPTIMIZATION: can we compare against distSq instead ?
1100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        double tiniest = SkTMin(SkTMin(SkTMin(fX, a.fX), fY), a.fY);
1110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        double largest = SkTMax(SkTMax(SkTMax(fX, a.fX), fY), a.fY);
1120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        largest = SkTMax(largest, -tiniest);
1130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return AlmostBequalUlps(largest, largest + dist); // is the dist within ULPS tolerance?
1147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool approximatelyEqual(const SkPoint& a) const {
1170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDPoint dA;
1180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        dA.set(a);
1190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return approximatelyEqual(dA);
1207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    static bool ApproximatelyEqual(const SkPoint& a, const SkPoint& b) {
1230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (approximately_equal(a.fX, b.fX) && approximately_equal(a.fY, b.fY)) {
1240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return true;
1250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
1260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (!RoughlyEqualUlps(a.fX, b.fX) || !RoughlyEqualUlps(a.fY, b.fY)) {
1270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return false;
1280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
1290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDPoint dA, dB;
1300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        dA.set(a);
1310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        dB.set(b);
1320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        double dist = dA.distance(dB);  // OPTIMIZATION: can we compare against distSq instead ?
1330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        float tiniest = SkTMin(SkTMin(SkTMin(a.fX, b.fX), a.fY), b.fY);
1340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        float largest = SkTMax(SkTMax(SkTMax(a.fX, b.fX), a.fY), b.fY);
1350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        largest = SkTMax(largest, -tiniest);
1360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return AlmostBequalUlps((double) largest, largest + dist); // is dist within ULPS tolerance?
1370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
1380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool approximatelyPEqual(const SkDPoint& a) const {
1400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (approximately_equal(fX, a.fX) && approximately_equal(fY, a.fY)) {
1417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            return true;
1427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (!RoughlyEqualUlps(fX, a.fX) || !RoughlyEqualUlps(fY, a.fY)) {
1440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return false;
1450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
1460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        double dist = distance(a);  // OPTIMIZATION: can we compare against distSq instead ?
1470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        double tiniest = SkTMin(SkTMin(SkTMin(fX, a.fX), fY), a.fY);
1480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        double largest = SkTMax(SkTMax(SkTMax(fX, a.fX), fY), a.fY);
1490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        largest = SkTMax(largest, -tiniest);
1500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return AlmostPequalUlps(largest, largest + dist); // is the dist within ULPS tolerance?
1517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool approximatelyZero() const {
1547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return approximately_zero(fX) && approximately_zero(fY);
1557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPoint asSkPoint() const {
1587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkPoint pt = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)};
1597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return pt;
1607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    double distance(const SkDPoint& a) const {
1637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkDVector temp = *this - a;
1647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return temp.length();
1657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    double distanceSquared(const SkDPoint& a) const {
1687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkDVector temp = *this - a;
1697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return temp.lengthSquared();
1707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
17258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    static SkDPoint Mid(const SkDPoint& a, const SkDPoint& b) {
17358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkDPoint result;
17458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        result.fX = (a.fX + b.fX) / 2;
17558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        result.fY = (a.fY + b.fY) / 2;
17658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return result;
17758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
17858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
1790a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool moreRoughlyEqual(const SkDPoint& a) const {
1800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (roughly_equal(fX, a.fX) && roughly_equal(fY, a.fY)) {
1810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return true;
1820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
1830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        double dist = distance(a);  // OPTIMIZATION: can we compare against distSq instead ?
1840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        double tiniest = SkTMin(SkTMin(SkTMin(fX, a.fX), fY), a.fY);
1850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        double largest = SkTMax(SkTMax(SkTMax(fX, a.fX), fY), a.fY);
1860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        largest = SkTMax(largest, -tiniest);
1870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return RoughlyEqualUlps(largest, largest + dist); // is the dist within ULPS tolerance?
1887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool roughlyEqual(const SkDPoint& a) const {
1917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return roughly_equal(a.fY, fY) && roughly_equal(a.fX, fX);
1927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    #ifdef SK_DEBUG
1950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void dump() {
1960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDebugf("{");
1970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        DebugDumpDouble(fX);
1980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDebugf(", ");
1990a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        DebugDumpDouble(fY);
2000a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDebugf("}");
2010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
2020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
2030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    static void dump(const SkPoint& pt) {
2040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDebugf("{");
2050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        DebugDumpFloat(pt.fX);
2060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDebugf(", ");
2070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        DebugDumpFloat(pt.fY);
2080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDebugf("}");
2090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
2100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger   #endif
2117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
2127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
214