SkPathOpsTypes.h revision b669300a9753893ef900207c38aeff2d467764e5
107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com/*
207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com * Copyright 2012 Google Inc.
307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com *
407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com * Use of this source code is governed by a BSD-style license that can be
507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com * found in the LICENSE file.
607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com */
707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#ifndef SkPathOpsTypes_DEFINED
807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#define SkPathOpsTypes_DEFINED
907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
1007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include <float.h>  // for FLT_EPSILON
1107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include <math.h>   // for fabs, sqrt
1207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
1307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include "SkFloatingPoint.h"
14277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com#include "SkPath.h"
1507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include "SkPathOps.h"
1607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include "SkPathOpsDebug.h"
1707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include "SkScalar.h"
1807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
1907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comenum SkPathOpsMask {
2007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    kWinding_PathOpsMask = -1,
2107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    kNo_PathOpsMask = 0,
2207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    kEvenOdd_PathOpsMask = 1
2307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com};
2407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
2554359294a7c9dc54802d512a5d891a35c1663392caryclarkclass SkOpCoincidence;
2654359294a7c9dc54802d512a5d891a35c1663392caryclarkclass SkOpContour;
27624637cc8ec22c000409704d0b403ac1b81ad4b0caryclarkclass SkOpContourHead;
2826ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclarkclass SkIntersections;
2926ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclarkclass SkIntersectionHelper;
3054359294a7c9dc54802d512a5d891a35c1663392caryclark
3154359294a7c9dc54802d512a5d891a35c1663392caryclarkclass SkOpGlobalState {
3254359294a7c9dc54802d512a5d891a35c1663392caryclarkpublic:
33d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark    SkOpGlobalState(SkOpCoincidence* coincidence, SkOpContourHead* head
34d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark                    SkDEBUGPARAMS(const char* testName));
3554359294a7c9dc54802d512a5d891a35c1663392caryclark
3654359294a7c9dc54802d512a5d891a35c1663392caryclark    enum Phase {
3754359294a7c9dc54802d512a5d891a35c1663392caryclark        kIntersecting,
385b5ddd73b4baf22752924bf20d097e96236c36f8caryclark        kWalking,
395b5ddd73b4baf22752924bf20d097e96236c36f8caryclark        kFixWinding,
4054359294a7c9dc54802d512a5d891a35c1663392caryclark    };
4154359294a7c9dc54802d512a5d891a35c1663392caryclark
42624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark    enum {
43624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark        kMaxWindingTries = 10
44624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark    };
45624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark
4626ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    bool angleCoincidence() const {
4754359294a7c9dc54802d512a5d891a35c1663392caryclark        return fAngleCoincidence;
4854359294a7c9dc54802d512a5d891a35c1663392caryclark    }
4954359294a7c9dc54802d512a5d891a35c1663392caryclark
504e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark    void bumpNested() {
514e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark        ++fNested;
524e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark    }
534e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark
544e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark    void clearNested() {
554e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark        fNested = 0;
564e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark    }
574e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark
5854359294a7c9dc54802d512a5d891a35c1663392caryclark    SkOpCoincidence* coincidence() {
5954359294a7c9dc54802d512a5d891a35c1663392caryclark        return fCoincidence;
6054359294a7c9dc54802d512a5d891a35c1663392caryclark    }
6154359294a7c9dc54802d512a5d891a35c1663392caryclark
62624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark    SkOpContourHead* contourHead() {
63624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark        return fContourHead;
64624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark    }
65624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark
6654359294a7c9dc54802d512a5d891a35c1663392caryclark#ifdef SK_DEBUG
6754359294a7c9dc54802d512a5d891a35c1663392caryclark    const struct SkOpAngle* debugAngle(int id) const;
6854359294a7c9dc54802d512a5d891a35c1663392caryclark    SkOpContour* debugContour(int id);
6954359294a7c9dc54802d512a5d891a35c1663392caryclark    const class SkOpPtT* debugPtT(int id) const;
7027c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark    bool debugRunFail() const;
7154359294a7c9dc54802d512a5d891a35c1663392caryclark    const class SkOpSegment* debugSegment(int id) const;
7254359294a7c9dc54802d512a5d891a35c1663392caryclark    const class SkOpSpanBase* debugSpan(int id) const;
73d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark    const char* debugTestName() const { return fDebugTestName; }
744e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark#endif
754e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark
7626ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark#if DEBUG_T_SECT_LOOP_COUNT
7726ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    void debugAddLoopCount(SkIntersections* , const SkIntersectionHelper& ,
7826ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark        const SkIntersectionHelper& );
7926ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    void debugDoYourWorst(SkOpGlobalState* );
8026ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    void debugLoopReport();
8126ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    void debugResetLoopCounts();
8226ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark#endif
8326ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark
844e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark    int nested() const {
854e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark        return fNested;
864e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark    }
8754359294a7c9dc54802d512a5d891a35c1663392caryclark
884e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark#ifdef SK_DEBUG
8954359294a7c9dc54802d512a5d891a35c1663392caryclark    int nextAngleID() {
9054359294a7c9dc54802d512a5d891a35c1663392caryclark        return ++fAngleID;
9154359294a7c9dc54802d512a5d891a35c1663392caryclark    }
9254359294a7c9dc54802d512a5d891a35c1663392caryclark
9326ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    int nextCoinID() {
9426ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark        return ++fCoinID;
9526ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    }
9626ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark
9754359294a7c9dc54802d512a5d891a35c1663392caryclark    int nextContourID() {
9854359294a7c9dc54802d512a5d891a35c1663392caryclark        return ++fContourID;
9954359294a7c9dc54802d512a5d891a35c1663392caryclark    }
10026ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark
10154359294a7c9dc54802d512a5d891a35c1663392caryclark    int nextPtTID() {
10254359294a7c9dc54802d512a5d891a35c1663392caryclark        return ++fPtTID;
10354359294a7c9dc54802d512a5d891a35c1663392caryclark    }
10454359294a7c9dc54802d512a5d891a35c1663392caryclark
10554359294a7c9dc54802d512a5d891a35c1663392caryclark    int nextSegmentID() {
10654359294a7c9dc54802d512a5d891a35c1663392caryclark        return ++fSegmentID;
10754359294a7c9dc54802d512a5d891a35c1663392caryclark    }
10854359294a7c9dc54802d512a5d891a35c1663392caryclark
10954359294a7c9dc54802d512a5d891a35c1663392caryclark    int nextSpanID() {
11054359294a7c9dc54802d512a5d891a35c1663392caryclark        return ++fSpanID;
11154359294a7c9dc54802d512a5d891a35c1663392caryclark    }
11254359294a7c9dc54802d512a5d891a35c1663392caryclark#endif
11354359294a7c9dc54802d512a5d891a35c1663392caryclark
11454359294a7c9dc54802d512a5d891a35c1663392caryclark    Phase phase() const {
11554359294a7c9dc54802d512a5d891a35c1663392caryclark        return fPhase;
11654359294a7c9dc54802d512a5d891a35c1663392caryclark    }
11754359294a7c9dc54802d512a5d891a35c1663392caryclark
11854359294a7c9dc54802d512a5d891a35c1663392caryclark    void setAngleCoincidence() {
11954359294a7c9dc54802d512a5d891a35c1663392caryclark        fAngleCoincidence = true;
12054359294a7c9dc54802d512a5d891a35c1663392caryclark    }
12154359294a7c9dc54802d512a5d891a35c1663392caryclark
122624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark    void setContourHead(SkOpContourHead* contourHead) {
123624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark        fContourHead = contourHead;
124624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark    }
125624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark
12654359294a7c9dc54802d512a5d891a35c1663392caryclark    void setPhase(Phase phase) {
12754359294a7c9dc54802d512a5d891a35c1663392caryclark        SkASSERT(fPhase != phase);
12854359294a7c9dc54802d512a5d891a35c1663392caryclark        fPhase = phase;
12954359294a7c9dc54802d512a5d891a35c1663392caryclark    }
13054359294a7c9dc54802d512a5d891a35c1663392caryclark
13154359294a7c9dc54802d512a5d891a35c1663392caryclark    // called in very rare cases where angles are sorted incorrectly -- signfies op will fail
13254359294a7c9dc54802d512a5d891a35c1663392caryclark    void setWindingFailed() {
13354359294a7c9dc54802d512a5d891a35c1663392caryclark        fWindingFailed = true;
13454359294a7c9dc54802d512a5d891a35c1663392caryclark    }
13554359294a7c9dc54802d512a5d891a35c1663392caryclark
13654359294a7c9dc54802d512a5d891a35c1663392caryclark    bool windingFailed() const {
13754359294a7c9dc54802d512a5d891a35c1663392caryclark        return fWindingFailed;
13854359294a7c9dc54802d512a5d891a35c1663392caryclark    }
13954359294a7c9dc54802d512a5d891a35c1663392caryclark
14054359294a7c9dc54802d512a5d891a35c1663392caryclarkprivate:
14154359294a7c9dc54802d512a5d891a35c1663392caryclark    SkOpCoincidence* fCoincidence;
142624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark    SkOpContourHead* fContourHead;
1434e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark    int fNested;
14454359294a7c9dc54802d512a5d891a35c1663392caryclark    bool fWindingFailed;
14554359294a7c9dc54802d512a5d891a35c1663392caryclark    bool fAngleCoincidence;
14654359294a7c9dc54802d512a5d891a35c1663392caryclark    Phase fPhase;
14754359294a7c9dc54802d512a5d891a35c1663392caryclark#ifdef SK_DEBUG
148d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark    const char* fDebugTestName;
14954359294a7c9dc54802d512a5d891a35c1663392caryclark    int fAngleID;
15026ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    int fCoinID;
15154359294a7c9dc54802d512a5d891a35c1663392caryclark    int fContourID;
15254359294a7c9dc54802d512a5d891a35c1663392caryclark    int fPtTID;
15354359294a7c9dc54802d512a5d891a35c1663392caryclark    int fSegmentID;
15454359294a7c9dc54802d512a5d891a35c1663392caryclark    int fSpanID;
15554359294a7c9dc54802d512a5d891a35c1663392caryclark#endif
15626ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark#if DEBUG_T_SECT_LOOP_COUNT
15726ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    int fDebugLoopCount[3];
15826ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    SkPath::Verb fDebugWorstVerb[6];
15926ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    SkPoint fDebugWorstPts[24];
16026ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    float fDebugWorstWeight[6];
16126ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark#endif
16254359294a7c9dc54802d512a5d891a35c1663392caryclark};
16354359294a7c9dc54802d512a5d891a35c1663392caryclark
164c3f63570c35a1e2bc84b33906c6401d6f3062bf2caryclark@google.com// Use Almost Equal when comparing coordinates. Use epsilon to compare T values.
1654fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.combool AlmostEqualUlps(float a, float b);
1664fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.cominline bool AlmostEqualUlps(double a, double b) {
1674fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.com    return AlmostEqualUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
16807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
16907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
170b669300a9753893ef900207c38aeff2d467764e5caryclarkbool AlmostEqualUlps_Pin(float a, float b);
171b669300a9753893ef900207c38aeff2d467764e5caryclarkinline bool AlmostEqualUlps_Pin(double a, double b) {
172b669300a9753893ef900207c38aeff2d467764e5caryclark    return AlmostEqualUlps_Pin(SkDoubleToScalar(a), SkDoubleToScalar(b));
173b669300a9753893ef900207c38aeff2d467764e5caryclark}
174b669300a9753893ef900207c38aeff2d467764e5caryclark
1757eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com// Use Almost Dequal when comparing should not special case denormalized values.
1767eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.combool AlmostDequalUlps(float a, float b);
1772db7fe7d3b7ee875e1099a22f0af17520696f5d7commit-bot@chromium.orgbool AlmostDequalUlps(double a, double b);
1787eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com
179570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.combool NotAlmostEqualUlps(float a, float b);
180570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.cominline bool NotAlmostEqualUlps(double a, double b) {
181570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com    return NotAlmostEqualUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
182570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com}
183570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com
184b669300a9753893ef900207c38aeff2d467764e5caryclarkbool NotAlmostEqualUlps_Pin(float a, float b);
185b669300a9753893ef900207c38aeff2d467764e5caryclarkinline bool NotAlmostEqualUlps_Pin(double a, double b) {
186b669300a9753893ef900207c38aeff2d467764e5caryclark    return NotAlmostEqualUlps_Pin(SkDoubleToScalar(a), SkDoubleToScalar(b));
187b669300a9753893ef900207c38aeff2d467764e5caryclark}
188b669300a9753893ef900207c38aeff2d467764e5caryclark
1897eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.combool NotAlmostDequalUlps(float a, float b);
1907eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.cominline bool NotAlmostDequalUlps(double a, double b) {
1917eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com    return NotAlmostDequalUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
1927eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com}
1937eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com
194570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com// Use Almost Bequal when comparing coordinates in conjunction with between.
195570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.combool AlmostBequalUlps(float a, float b);
196570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.cominline bool AlmostBequalUlps(double a, double b) {
197570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com    return AlmostBequalUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
198570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com}
199570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com
200a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.combool AlmostPequalUlps(float a, float b);
201a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.cominline bool AlmostPequalUlps(double a, double b) {
202a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    return AlmostPequalUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
203a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com}
204a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
2054fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.combool RoughlyEqualUlps(float a, float b);
2064fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.cominline bool RoughlyEqualUlps(double a, double b) {
2074fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.com    return RoughlyEqualUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
20807e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com}
20907e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com
210570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.combool AlmostLessUlps(float a, float b);
211570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.cominline bool AlmostLessUlps(double a, double b) {
212570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com    return AlmostLessUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
213570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com}
214570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com
215570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.combool AlmostLessOrEqualUlps(float a, float b);
216570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.cominline bool AlmostLessOrEqualUlps(double a, double b) {
217570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com    return AlmostLessOrEqualUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
218570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com}
219570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com
220fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.combool AlmostBetweenUlps(float a, float b, float c);
2214fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.cominline bool AlmostBetweenUlps(double a, double b, double c) {
2224fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.com    return AlmostBetweenUlps(SkDoubleToScalar(a), SkDoubleToScalar(b), SkDoubleToScalar(c));
2234fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.com}
2244fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.com
2254fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.comint UlpsDistance(float a, float b);
2264fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.cominline int UlpsDistance(double a, double b) {
2274fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.com    return UlpsDistance(SkDoubleToScalar(a), SkDoubleToScalar(b));
228fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com}
229fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com
23007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// FLT_EPSILON == 1.19209290E-07 == 1 / (2 ^ 23)
23107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// DBL_EPSILON == 2.22045e-16
23207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double FLT_EPSILON_CUBED = FLT_EPSILON * FLT_EPSILON * FLT_EPSILON;
23307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double FLT_EPSILON_HALF = FLT_EPSILON / 2;
234cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.comconst double FLT_EPSILON_DOUBLE = FLT_EPSILON * 2;
2354431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgconst double FLT_EPSILON_ORDERABLE_ERR = FLT_EPSILON * 16;
23607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double FLT_EPSILON_SQUARED = FLT_EPSILON * FLT_EPSILON;
23707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double FLT_EPSILON_SQRT = sqrt(FLT_EPSILON);
23807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double FLT_EPSILON_INVERSE = 1 / FLT_EPSILON;
23907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double DBL_EPSILON_ERR = DBL_EPSILON * 4;  // FIXME: tune -- allow a few bits of error
240cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.comconst double DBL_EPSILON_SUBDIVIDE_ERR = DBL_EPSILON * 16;
24107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double ROUGH_EPSILON = FLT_EPSILON * 64;
24207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double MORE_ROUGH_EPSILON = FLT_EPSILON * 256;
243dac1d17027dcaa5596885a9f333979418b35001ccaryclarkconst double WAY_ROUGH_EPSILON = FLT_EPSILON * 2048;
24454359294a7c9dc54802d512a5d891a35c1663392caryclarkconst double BUMP_EPSILON = FLT_EPSILON * 4096;
245dac1d17027dcaa5596885a9f333979418b35001ccaryclark
246dac1d17027dcaa5596885a9f333979418b35001ccaryclarkinline bool zero_or_one(double x) {
247dac1d17027dcaa5596885a9f333979418b35001ccaryclark    return x == 0 || x == 1;
248dac1d17027dcaa5596885a9f333979418b35001ccaryclark}
24907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
25007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero(double x) {
25107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) < FLT_EPSILON;
25207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
25307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
25407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool precisely_zero(double x) {
25507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) < DBL_EPSILON_ERR;
25607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
25707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
258cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.cominline bool precisely_subdivide_zero(double x) {
259cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    return fabs(x) < DBL_EPSILON_SUBDIVIDE_ERR;
260cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com}
261cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com
26207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero(float x) {
26307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) < FLT_EPSILON;
26407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
26507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
26607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero_cubed(double x) {
26707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) < FLT_EPSILON_CUBED;
26807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
26907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
27007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero_half(double x) {
27107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) < FLT_EPSILON_HALF;
27207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
27307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
274cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.cominline bool approximately_zero_double(double x) {
275cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    return fabs(x) < FLT_EPSILON_DOUBLE;
276cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com}
277cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com
2784431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_zero_orderable(double x) {
2794431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return fabs(x) < FLT_EPSILON_ORDERABLE_ERR;
2804431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
2814431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
28207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero_squared(double x) {
28307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) < FLT_EPSILON_SQUARED;
28407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
28507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
28607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero_sqrt(double x) {
28707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) < FLT_EPSILON_SQRT;
28807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
28907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
290cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.cominline bool roughly_zero(double x) {
291cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    return fabs(x) < ROUGH_EPSILON;
292cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com}
293cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com
29407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero_inverse(double x) {
29507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) > FLT_EPSILON_INVERSE;
29607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
29707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
29807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// OPTIMIZATION: if called multiple times with the same denom, we want to pass 1/y instead
29907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero_when_compared_to(double x, double y) {
3004431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x == 0 || fabs(x) < fabs(y * FLT_EPSILON);
30107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
30207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
30354359294a7c9dc54802d512a5d891a35c1663392caryclarkinline bool precisely_zero_when_compared_to(double x, double y) {
30454359294a7c9dc54802d512a5d891a35c1663392caryclark    return x == 0 || fabs(x) < fabs(y * DBL_EPSILON);
30554359294a7c9dc54802d512a5d891a35c1663392caryclark}
30654359294a7c9dc54802d512a5d891a35c1663392caryclark
30707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// Use this for comparing Ts in the range of 0 to 1. For general numbers (larger and smaller) use
30807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// AlmostEqualUlps instead.
30907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_equal(double x, double y) {
31007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return approximately_zero(x - y);
31107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
31207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
31307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool precisely_equal(double x, double y) {
31407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return precisely_zero(x - y);
31507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
31607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
317cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.cominline bool precisely_subdivide_equal(double x, double y) {
318cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    return precisely_subdivide_zero(x - y);
319cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com}
320cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com
32107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_equal_half(double x, double y) {
32207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return approximately_zero_half(x - y);
32307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
32407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
325cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.cominline bool approximately_equal_double(double x, double y) {
326cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    return approximately_zero_double(x - y);
327cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com}
328cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com
3294431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_equal_orderable(double x, double y) {
3304431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return approximately_zero_orderable(x - y);
3314431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
3324431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
33307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_equal_squared(double x, double y) {
33407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return approximately_equal(x, y);
33507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
33607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
33707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_greater(double x, double y) {
33807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x - FLT_EPSILON >= y;
33907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
34007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
3414431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_greater_double(double x, double y) {
3424431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x - FLT_EPSILON_DOUBLE >= y;
3434431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
3444431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
3454431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_greater_orderable(double x, double y) {
3464431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x - FLT_EPSILON_ORDERABLE_ERR >= y;
3474431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
3484431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
34907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_greater_or_equal(double x, double y) {
35007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x + FLT_EPSILON > y;
35107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
35207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
3534431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_greater_or_equal_double(double x, double y) {
3544431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x + FLT_EPSILON_DOUBLE > y;
3554431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
3564431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
3574431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_greater_or_equal_orderable(double x, double y) {
3584431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x + FLT_EPSILON_ORDERABLE_ERR > y;
3594431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
3604431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
36107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_lesser(double x, double y) {
36207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x + FLT_EPSILON <= y;
36307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
36407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
3654431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_lesser_double(double x, double y) {
3664431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x + FLT_EPSILON_DOUBLE <= y;
3674431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
3684431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
3694431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_lesser_orderable(double x, double y) {
3704431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x + FLT_EPSILON_ORDERABLE_ERR <= y;
3714431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
3724431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
37307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_lesser_or_equal(double x, double y) {
37407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x - FLT_EPSILON < y;
37507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
37607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
3774431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_lesser_or_equal_double(double x, double y) {
3784431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x - FLT_EPSILON_DOUBLE < y;
3794431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
3804431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
3814431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_lesser_or_equal_orderable(double x, double y) {
3824431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x - FLT_EPSILON_ORDERABLE_ERR < y;
3834431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
3844431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
38507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_greater_than_one(double x) {
38607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x > 1 - FLT_EPSILON;
38707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
38807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
38907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool precisely_greater_than_one(double x) {
39007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x > 1 - DBL_EPSILON_ERR;
39107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
39207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
39307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_less_than_zero(double x) {
39407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x < FLT_EPSILON;
39507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
39607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
39707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool precisely_less_than_zero(double x) {
39807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x < DBL_EPSILON_ERR;
39907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
40007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
40107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_negative(double x) {
40207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x < FLT_EPSILON;
40307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
40407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
4054431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_negative_orderable(double x) {
4064431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x < FLT_EPSILON_ORDERABLE_ERR;
4074431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
4084431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
40907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool precisely_negative(double x) {
41007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x < DBL_EPSILON_ERR;
41107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
41207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
41307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_one_or_less(double x) {
41407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x < 1 + FLT_EPSILON;
41507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
41607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
4174431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_one_or_less_double(double x) {
4184431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x < 1 + FLT_EPSILON_DOUBLE;
4194431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
4204431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
42107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_positive(double x) {
42207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x > -FLT_EPSILON;
42307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
42407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
42507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_positive_squared(double x) {
42607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x > -(FLT_EPSILON_SQUARED);
42707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
42807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
42907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero_or_more(double x) {
43007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x > -FLT_EPSILON;
43107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
43207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
4334431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_zero_or_more_double(double x) {
4344431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x > -FLT_EPSILON_DOUBLE;
4354431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
4364431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
4374431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_between_orderable(double a, double b, double c) {
4384431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return a <= c
4394431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            ? approximately_negative_orderable(a - b) && approximately_negative_orderable(b - c)
4404431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            : approximately_negative_orderable(b - a) && approximately_negative_orderable(c - b);
4414431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
4424431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
44307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_between(double a, double b, double c) {
44407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return a <= c ? approximately_negative(a - b) && approximately_negative(b - c)
44507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            : approximately_negative(b - a) && approximately_negative(c - b);
44607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
4470361032c0b53401030a720bc8b4930c3ec59f19ecaryclark@google.com
4480361032c0b53401030a720bc8b4930c3ec59f19ecaryclark@google.cominline bool precisely_between(double a, double b, double c) {
4490361032c0b53401030a720bc8b4930c3ec59f19ecaryclark@google.com    return a <= c ? precisely_negative(a - b) && precisely_negative(b - c)
4500361032c0b53401030a720bc8b4930c3ec59f19ecaryclark@google.com            : precisely_negative(b - a) && precisely_negative(c - b);
4510361032c0b53401030a720bc8b4930c3ec59f19ecaryclark@google.com}
45207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
45307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// returns true if (a <= b <= c) || (a >= b >= c)
45407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool between(double a, double b, double c) {
45554359294a7c9dc54802d512a5d891a35c1663392caryclark    SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0)
45654359294a7c9dc54802d512a5d891a35c1663392caryclark            || (precisely_zero(a) && precisely_zero(b) && precisely_zero(c)));
45707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return (a - b) * (c - b) <= 0;
45807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
45907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
460dac1d17027dcaa5596885a9f333979418b35001ccaryclarkinline bool roughly_equal(double x, double y) {
461dac1d17027dcaa5596885a9f333979418b35001ccaryclark    return fabs(x - y) < ROUGH_EPSILON;
462dac1d17027dcaa5596885a9f333979418b35001ccaryclark}
463dac1d17027dcaa5596885a9f333979418b35001ccaryclark
46454359294a7c9dc54802d512a5d891a35c1663392caryclarkinline bool roughly_negative(double x) {
46554359294a7c9dc54802d512a5d891a35c1663392caryclark    return x < ROUGH_EPSILON;
46654359294a7c9dc54802d512a5d891a35c1663392caryclark}
46754359294a7c9dc54802d512a5d891a35c1663392caryclark
46854359294a7c9dc54802d512a5d891a35c1663392caryclarkinline bool roughly_between(double a, double b, double c) {
46954359294a7c9dc54802d512a5d891a35c1663392caryclark    return a <= c ? roughly_negative(a - b) && roughly_negative(b - c)
47054359294a7c9dc54802d512a5d891a35c1663392caryclark            : roughly_negative(b - a) && roughly_negative(c - b);
47154359294a7c9dc54802d512a5d891a35c1663392caryclark}
47254359294a7c9dc54802d512a5d891a35c1663392caryclark
47307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool more_roughly_equal(double x, double y) {
47407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x - y) < MORE_ROUGH_EPSILON;
47507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
47607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
477dac1d17027dcaa5596885a9f333979418b35001ccaryclarkinline bool way_roughly_equal(double x, double y) {
478dac1d17027dcaa5596885a9f333979418b35001ccaryclark    return fabs(x - y) < WAY_ROUGH_EPSILON;
47907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
48007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
48107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstruct SkDPoint;
48207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstruct SkDVector;
48307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstruct SkDLine;
48407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstruct SkDQuad;
4851049f1246e7be4ccb68001361efceb8933e6f81ccaryclarkstruct SkDConic;
48607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstruct SkDCubic;
48707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstruct SkDRect;
48807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
489277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.cominline SkPath::Verb SkPathOpsPointsToVerb(int points) {
490277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com    int verb = (1 << points) >> 1;
491277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com#ifdef SK_DEBUG
492277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com    switch (points) {
493277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com        case 0: SkASSERT(SkPath::kMove_Verb == verb); break;
494277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com        case 1: SkASSERT(SkPath::kLine_Verb == verb); break;
495277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com        case 2: SkASSERT(SkPath::kQuad_Verb == verb); break;
496277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com        case 3: SkASSERT(SkPath::kCubic_Verb == verb); break;
497330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com        default: SkDEBUGFAIL("should not be here");
498277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com    }
499277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com#endif
500277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com    return (SkPath::Verb)verb;
501277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com}
502277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com
503277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.cominline int SkPathOpsVerbToPoints(SkPath::Verb verb) {
5041049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    int points = (int) verb - (((int) verb + 1) >> 2);
505277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com#ifdef SK_DEBUG
506277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com    switch (verb) {
507277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com        case SkPath::kLine_Verb: SkASSERT(1 == points); break;
508277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com        case SkPath::kQuad_Verb: SkASSERT(2 == points); break;
5091049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        case SkPath::kConic_Verb: SkASSERT(2 == points); break;
510277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com        case SkPath::kCubic_Verb: SkASSERT(3 == points); break;
511330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com        default: SkDEBUGFAIL("should not get here");
512277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com    }
513277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com#endif
514277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com    return points;
515277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com}
516277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com
51707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline double SkDInterp(double A, double B, double t) {
51807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return A + (B - A) * t;
51907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
52007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
52107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comdouble SkDCubeRoot(double x);
52207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
52307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com/* Returns -1 if negative, 0 if zero, 1 if positive
52407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com*/
52507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline int SkDSign(double x) {
52607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return (x > 0) - (x < 0);
52707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
52807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
52907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com/* Returns 0 if negative, 1 if zero, 2 if positive
53007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com*/
53107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline int SKDSide(double x) {
53207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return (x > 0) + (x >= 0);
53307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
53407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
53507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com/* Returns 1 if negative, 2 if zero, 4 if positive
53607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com*/
53707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline int SkDSideBit(double x) {
53807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return 1 << SKDSide(x);
53907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
54007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
541fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.cominline double SkPinT(double t) {
542fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com    return precisely_less_than_zero(t) ? 0 : precisely_greater_than_one(t) ? 1 : t;
543fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com}
544fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com
54507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#endif
546