121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com/*
221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com * Copyright 2012 Google Inc.
321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com *
421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com * Use of this source code is governed by a BSD-style license that can be
521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com * found in the LICENSE file.
621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com */
721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com#ifndef SkPathOpsTypes_DEFINED
821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com#define SkPathOpsTypes_DEFINED
921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
1021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com#include <float.h>  // for FLT_EPSILON
1121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com#include <math.h>   // for fabs, sqrt
1221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
1321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com#include "SkFloatingPoint.h"
146cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com#include "SkPath.h"
1521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com#include "SkPathOps.h"
1621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com#include "SkPathOpsDebug.h"
1721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com#include "SkScalar.h"
1821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
1921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comenum SkPathOpsMask {
2021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    kWinding_PathOpsMask = -1,
2121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    kNo_PathOpsMask = 0,
2221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    kEvenOdd_PathOpsMask = 1
2321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com};
2421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
25289863b9e9abab20aec012de77343b61c7dc2566caryclark@google.com// Use Almost Equal when comparing coordinates. Use epsilon to compare T values.
261a4d09d786e54862a38f367490a7e4769f7e73adcaryclark@google.combool AlmostEqualUlps(float a, float b);
271a4d09d786e54862a38f367490a7e4769f7e73adcaryclark@google.cominline bool AlmostEqualUlps(double a, double b) {
281a4d09d786e54862a38f367490a7e4769f7e73adcaryclark@google.com    return AlmostEqualUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
2921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
3021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
311a4d09d786e54862a38f367490a7e4769f7e73adcaryclark@google.combool RoughlyEqualUlps(float a, float b);
321a4d09d786e54862a38f367490a7e4769f7e73adcaryclark@google.cominline bool RoughlyEqualUlps(double a, double b) {
331a4d09d786e54862a38f367490a7e4769f7e73adcaryclark@google.com    return RoughlyEqualUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
3446e3086c1837da6ab13b48f852bd7bfbab3dc44fcaryclark@google.com}
3546e3086c1837da6ab13b48f852bd7bfbab3dc44fcaryclark@google.com
362607e2e5a8f13275d86e2242f9906f2106a2fa79caryclark@google.combool AlmostBetweenUlps(float a, float b, float c);
371a4d09d786e54862a38f367490a7e4769f7e73adcaryclark@google.cominline bool AlmostBetweenUlps(double a, double b, double c) {
381a4d09d786e54862a38f367490a7e4769f7e73adcaryclark@google.com    return AlmostBetweenUlps(SkDoubleToScalar(a), SkDoubleToScalar(b), SkDoubleToScalar(c));
391a4d09d786e54862a38f367490a7e4769f7e73adcaryclark@google.com}
401a4d09d786e54862a38f367490a7e4769f7e73adcaryclark@google.com
411a4d09d786e54862a38f367490a7e4769f7e73adcaryclark@google.comint UlpsDistance(float a, float b);
421a4d09d786e54862a38f367490a7e4769f7e73adcaryclark@google.cominline int UlpsDistance(double a, double b) {
431a4d09d786e54862a38f367490a7e4769f7e73adcaryclark@google.com    return UlpsDistance(SkDoubleToScalar(a), SkDoubleToScalar(b));
442607e2e5a8f13275d86e2242f9906f2106a2fa79caryclark@google.com}
452607e2e5a8f13275d86e2242f9906f2106a2fa79caryclark@google.com
4621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com// FLT_EPSILON == 1.19209290E-07 == 1 / (2 ^ 23)
4721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com// DBL_EPSILON == 2.22045e-16
4821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comconst double FLT_EPSILON_CUBED = FLT_EPSILON * FLT_EPSILON * FLT_EPSILON;
4921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comconst double FLT_EPSILON_HALF = FLT_EPSILON / 2;
503bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.comconst double FLT_EPSILON_DOUBLE = FLT_EPSILON * 2;
5121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comconst double FLT_EPSILON_SQUARED = FLT_EPSILON * FLT_EPSILON;
5221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comconst double FLT_EPSILON_SQRT = sqrt(FLT_EPSILON);
5321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comconst double FLT_EPSILON_INVERSE = 1 / FLT_EPSILON;
5421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comconst double DBL_EPSILON_ERR = DBL_EPSILON * 4;  // FIXME: tune -- allow a few bits of error
553bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.comconst double DBL_EPSILON_SUBDIVIDE_ERR = DBL_EPSILON * 16;
5621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comconst double ROUGH_EPSILON = FLT_EPSILON * 64;
5721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comconst double MORE_ROUGH_EPSILON = FLT_EPSILON * 256;
5821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
5921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_zero(double x) {
6021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return fabs(x) < FLT_EPSILON;
6121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
6221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
6321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool precisely_zero(double x) {
6421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return fabs(x) < DBL_EPSILON_ERR;
6521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
6621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
673bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.cominline bool precisely_subdivide_zero(double x) {
683bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.com    return fabs(x) < DBL_EPSILON_SUBDIVIDE_ERR;
693bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.com}
703bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.com
7121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_zero(float x) {
7221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return fabs(x) < FLT_EPSILON;
7321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
7421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
7521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_zero_cubed(double x) {
7621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return fabs(x) < FLT_EPSILON_CUBED;
7721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
7821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
7921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_zero_half(double x) {
8021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return fabs(x) < FLT_EPSILON_HALF;
8121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
8221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
833bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.cominline bool approximately_zero_double(double x) {
843bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.com    return fabs(x) < FLT_EPSILON_DOUBLE;
853bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.com}
863bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.com
8721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_zero_squared(double x) {
8821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return fabs(x) < FLT_EPSILON_SQUARED;
8921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
9021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
9121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_zero_sqrt(double x) {
9221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return fabs(x) < FLT_EPSILON_SQRT;
9321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
9421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
953bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.cominline bool roughly_zero(double x) {
963bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.com    return fabs(x) < ROUGH_EPSILON;
973bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.com}
983bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.com
9921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_zero_inverse(double x) {
10021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return fabs(x) > FLT_EPSILON_INVERSE;
10121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
10221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
10321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com// OPTIMIZATION: if called multiple times with the same denom, we want to pass 1/y instead
10421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_zero_when_compared_to(double x, double y) {
10521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return x == 0 || fabs(x / y) < FLT_EPSILON;
10621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
10721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
10821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com// Use this for comparing Ts in the range of 0 to 1. For general numbers (larger and smaller) use
10921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com// AlmostEqualUlps instead.
11021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_equal(double x, double y) {
11121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return approximately_zero(x - y);
11221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
11321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
11421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool precisely_equal(double x, double y) {
11521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return precisely_zero(x - y);
11621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
11721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
1183bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.cominline bool precisely_subdivide_equal(double x, double y) {
1193bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.com    return precisely_subdivide_zero(x - y);
1203bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.com}
1213bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.com
12221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_equal_half(double x, double y) {
12321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return approximately_zero_half(x - y);
12421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
12521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
1263bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.cominline bool approximately_equal_double(double x, double y) {
1273bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.com    return approximately_zero_double(x - y);
1283bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.com}
1293bdb9d9ce8ef9f8b297f65af3c8de018e97459c0caryclark@google.com
13021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_equal_squared(double x, double y) {
13121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return approximately_equal(x, y);
13221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
13321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
13421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_greater(double x, double y) {
13521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return x - FLT_EPSILON >= y;
13621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
13721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
13821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_greater_or_equal(double x, double y) {
13921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return x + FLT_EPSILON > y;
14021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
14121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
14221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_lesser(double x, double y) {
14321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return x + FLT_EPSILON <= y;
14421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
14521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
14621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_lesser_or_equal(double x, double y) {
14721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return x - FLT_EPSILON < y;
14821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
14921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
15021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_greater_than_one(double x) {
15121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return x > 1 - FLT_EPSILON;
15221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
15321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
15421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool precisely_greater_than_one(double x) {
15521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return x > 1 - DBL_EPSILON_ERR;
15621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
15721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
15821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_less_than_zero(double x) {
15921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return x < FLT_EPSILON;
16021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
16121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
16221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool precisely_less_than_zero(double x) {
16321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return x < DBL_EPSILON_ERR;
16421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
16521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
16621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_negative(double x) {
16721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return x < FLT_EPSILON;
16821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
16921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
17021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool precisely_negative(double x) {
17121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return x < DBL_EPSILON_ERR;
17221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
17321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
17421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_one_or_less(double x) {
17521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return x < 1 + FLT_EPSILON;
17621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
17721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
17821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_positive(double x) {
17921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return x > -FLT_EPSILON;
18021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
18121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
18221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_positive_squared(double x) {
18321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return x > -(FLT_EPSILON_SQUARED);
18421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
18521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
18621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_zero_or_more(double x) {
18721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return x > -FLT_EPSILON;
18821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
18921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
19021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool approximately_between(double a, double b, double c) {
19121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return a <= c ? approximately_negative(a - b) && approximately_negative(b - c)
19221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com            : approximately_negative(b - a) && approximately_negative(c - b);
19321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
194e708cc064c5cac2061855c874ea20622322183c4caryclark@google.com
195e708cc064c5cac2061855c874ea20622322183c4caryclark@google.cominline bool precisely_between(double a, double b, double c) {
196e708cc064c5cac2061855c874ea20622322183c4caryclark@google.com    return a <= c ? precisely_negative(a - b) && precisely_negative(b - c)
197e708cc064c5cac2061855c874ea20622322183c4caryclark@google.com            : precisely_negative(b - a) && precisely_negative(c - b);
198e708cc064c5cac2061855c874ea20622322183c4caryclark@google.com}
19921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
20021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com// returns true if (a <= b <= c) || (a >= b >= c)
20121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool between(double a, double b, double c) {
20221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0));
20321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return (a - b) * (c - b) <= 0;
20421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
20521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
20621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool more_roughly_equal(double x, double y) {
20721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return fabs(x - y) < MORE_ROUGH_EPSILON;
20821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
20921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
21021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline bool roughly_equal(double x, double y) {
21121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return fabs(x - y) < ROUGH_EPSILON;
21221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
21321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
21421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comstruct SkDPoint;
21521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comstruct SkDVector;
21621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comstruct SkDLine;
21721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comstruct SkDQuad;
21821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comstruct SkDTriangle;
21921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comstruct SkDCubic;
22021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comstruct SkDRect;
22121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
2226cae19e7539368fe697eb353d7e6197f027bc8dareed@google.cominline SkPath::Verb SkPathOpsPointsToVerb(int points) {
2236cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com    int verb = (1 << points) >> 1;
2246cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com#ifdef SK_DEBUG
2256cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com    switch (points) {
2266cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com        case 0: SkASSERT(SkPath::kMove_Verb == verb); break;
2276cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com        case 1: SkASSERT(SkPath::kLine_Verb == verb); break;
2286cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com        case 2: SkASSERT(SkPath::kQuad_Verb == verb); break;
2296cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com        case 3: SkASSERT(SkPath::kCubic_Verb == verb); break;
2306cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com        default: SkASSERT(!"should not be here");
2316cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com    }
2326cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com#endif
2336cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com    return (SkPath::Verb)verb;
2346cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com}
2356cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com
2366cae19e7539368fe697eb353d7e6197f027bc8dareed@google.cominline int SkPathOpsVerbToPoints(SkPath::Verb verb) {
2376cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com    int points = (int) verb - ((int) verb >> 2);
2386cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com#ifdef SK_DEBUG
2396cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com    switch (verb) {
2406cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com        case SkPath::kLine_Verb: SkASSERT(1 == points); break;
2416cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com        case SkPath::kQuad_Verb: SkASSERT(2 == points); break;
2426cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com        case SkPath::kCubic_Verb: SkASSERT(3 == points); break;
2436cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com        default: SkASSERT(!"should not get here");
2446cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com    }
2456cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com#endif
2466cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com    return points;
2476cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com}
2486cae19e7539368fe697eb353d7e6197f027bc8dareed@google.com
24921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline double SkDInterp(double A, double B, double t) {
25021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return A + (B - A) * t;
25121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
25221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
25321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.comdouble SkDCubeRoot(double x);
25421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
25521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com/* Returns -1 if negative, 0 if zero, 1 if positive
25621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com*/
25721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline int SkDSign(double x) {
25821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return (x > 0) - (x < 0);
25921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
26021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
26121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com/* Returns 0 if negative, 1 if zero, 2 if positive
26221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com*/
26321c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline int SKDSide(double x) {
26421c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return (x > 0) + (x >= 0);
26521c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
26621c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
26721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com/* Returns 1 if negative, 2 if zero, 4 if positive
26821c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com*/
26921c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.cominline int SkDSideBit(double x) {
27021c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com    return 1 << SKDSide(x);
27121c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com}
27221c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com
2732607e2e5a8f13275d86e2242f9906f2106a2fa79caryclark@google.cominline double SkPinT(double t) {
2742607e2e5a8f13275d86e2242f9906f2106a2fa79caryclark@google.com    return precisely_less_than_zero(t) ? 0 : precisely_greater_than_one(t) ? 1 : t;
2752607e2e5a8f13275d86e2242f9906f2106a2fa79caryclark@google.com}
2762607e2e5a8f13275d86e2242f9906f2106a2fa79caryclark@google.com
27721c2924b178f0d4c298d6631e568401473ed8d16caryclark@google.com#endif
278