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