SkPathOpsTypes.h revision e25a4f6cbeaccfdc34cf031103f0fbc3e53a3ee5
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
2555888e44171ffd48b591d19256884a969fe4da17caryclarkclass SkChunkAlloc;
2654359294a7c9dc54802d512a5d891a35c1663392caryclarkclass SkOpCoincidence;
2754359294a7c9dc54802d512a5d891a35c1663392caryclarkclass SkOpContour;
28624637cc8ec22c000409704d0b403ac1b81ad4b0caryclarkclass SkOpContourHead;
2926ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclarkclass SkIntersections;
3026ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclarkclass SkIntersectionHelper;
3154359294a7c9dc54802d512a5d891a35c1663392caryclark
3254359294a7c9dc54802d512a5d891a35c1663392caryclarkclass SkOpGlobalState {
3354359294a7c9dc54802d512a5d891a35c1663392caryclarkpublic:
3455888e44171ffd48b591d19256884a969fe4da17caryclark    SkOpGlobalState(SkOpContourHead* head,
3555888e44171ffd48b591d19256884a969fe4da17caryclark                    SkChunkAlloc* allocator  SkDEBUGPARAMS(bool debugSkipAssert)
36d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark                    SkDEBUGPARAMS(const char* testName));
3754359294a7c9dc54802d512a5d891a35c1663392caryclark
3854359294a7c9dc54802d512a5d891a35c1663392caryclark    enum Phase {
3954359294a7c9dc54802d512a5d891a35c1663392caryclark        kIntersecting,
405b5ddd73b4baf22752924bf20d097e96236c36f8caryclark        kWalking,
415b5ddd73b4baf22752924bf20d097e96236c36f8caryclark        kFixWinding,
4254359294a7c9dc54802d512a5d891a35c1663392caryclark    };
4354359294a7c9dc54802d512a5d891a35c1663392caryclark
44624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark    enum {
45624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark        kMaxWindingTries = 10
46624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark    };
47624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark
4855888e44171ffd48b591d19256884a969fe4da17caryclark    SkChunkAlloc* allocator() {
4955888e44171ffd48b591d19256884a969fe4da17caryclark        return fAllocator;
5055888e44171ffd48b591d19256884a969fe4da17caryclark    }
5155888e44171ffd48b591d19256884a969fe4da17caryclark
5226ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    bool angleCoincidence() const {
5354359294a7c9dc54802d512a5d891a35c1663392caryclark        return fAngleCoincidence;
5454359294a7c9dc54802d512a5d891a35c1663392caryclark    }
5554359294a7c9dc54802d512a5d891a35c1663392caryclark
564e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark    void bumpNested() {
574e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark        ++fNested;
584e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark    }
594e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark
604e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark    void clearNested() {
614e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark        fNested = 0;
624e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark    }
634e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark
6454359294a7c9dc54802d512a5d891a35c1663392caryclark    SkOpCoincidence* coincidence() {
6554359294a7c9dc54802d512a5d891a35c1663392caryclark        return fCoincidence;
6654359294a7c9dc54802d512a5d891a35c1663392caryclark    }
6754359294a7c9dc54802d512a5d891a35c1663392caryclark
68624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark    SkOpContourHead* contourHead() {
69624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark        return fContourHead;
70624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark    }
71624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark
7254359294a7c9dc54802d512a5d891a35c1663392caryclark#ifdef SK_DEBUG
7355888e44171ffd48b591d19256884a969fe4da17caryclark    const class SkOpAngle* debugAngle(int id) const;
7455888e44171ffd48b591d19256884a969fe4da17caryclark    const SkOpCoincidence* debugCoincidence() const;
7554359294a7c9dc54802d512a5d891a35c1663392caryclark    SkOpContour* debugContour(int id);
7654359294a7c9dc54802d512a5d891a35c1663392caryclark    const class SkOpPtT* debugPtT(int id) const;
7727c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark    bool debugRunFail() const;
7854359294a7c9dc54802d512a5d891a35c1663392caryclark    const class SkOpSegment* debugSegment(int id) const;
79dae6b97705fde08958b1a36fa6ce685d28fc692ccaryclark    bool debugSkipAssert() const { return fDebugSkipAssert; }
8054359294a7c9dc54802d512a5d891a35c1663392caryclark    const class SkOpSpanBase* debugSpan(int id) const;
81d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark    const char* debugTestName() const { return fDebugTestName; }
824e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark#endif
834e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark
8426ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark#if DEBUG_T_SECT_LOOP_COUNT
8526ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    void debugAddLoopCount(SkIntersections* , const SkIntersectionHelper& ,
8626ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark        const SkIntersectionHelper& );
8726ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    void debugDoYourWorst(SkOpGlobalState* );
8826ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    void debugLoopReport();
8926ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    void debugResetLoopCounts();
9026ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark#endif
9126ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark
9255888e44171ffd48b591d19256884a969fe4da17caryclark#if DEBUG_COINCIDENCE
9355888e44171ffd48b591d19256884a969fe4da17caryclark    void debugSetCheckHealth(bool check) { fDebugCheckHealth = check; }
9455888e44171ffd48b591d19256884a969fe4da17caryclark    bool debugCheckHealth() const { return fDebugCheckHealth; }
9555888e44171ffd48b591d19256884a969fe4da17caryclark#endif
9655888e44171ffd48b591d19256884a969fe4da17caryclark
974e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark    int nested() const {
984e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark        return fNested;
994e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark    }
10054359294a7c9dc54802d512a5d891a35c1663392caryclark
1014e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark#ifdef SK_DEBUG
10254359294a7c9dc54802d512a5d891a35c1663392caryclark    int nextAngleID() {
10354359294a7c9dc54802d512a5d891a35c1663392caryclark        return ++fAngleID;
10454359294a7c9dc54802d512a5d891a35c1663392caryclark    }
10554359294a7c9dc54802d512a5d891a35c1663392caryclark
10626ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    int nextCoinID() {
10726ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark        return ++fCoinID;
10826ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    }
10926ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark
11054359294a7c9dc54802d512a5d891a35c1663392caryclark    int nextContourID() {
11154359294a7c9dc54802d512a5d891a35c1663392caryclark        return ++fContourID;
11254359294a7c9dc54802d512a5d891a35c1663392caryclark    }
11326ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark
11454359294a7c9dc54802d512a5d891a35c1663392caryclark    int nextPtTID() {
11554359294a7c9dc54802d512a5d891a35c1663392caryclark        return ++fPtTID;
11654359294a7c9dc54802d512a5d891a35c1663392caryclark    }
11754359294a7c9dc54802d512a5d891a35c1663392caryclark
11854359294a7c9dc54802d512a5d891a35c1663392caryclark    int nextSegmentID() {
11954359294a7c9dc54802d512a5d891a35c1663392caryclark        return ++fSegmentID;
12054359294a7c9dc54802d512a5d891a35c1663392caryclark    }
12154359294a7c9dc54802d512a5d891a35c1663392caryclark
12254359294a7c9dc54802d512a5d891a35c1663392caryclark    int nextSpanID() {
12354359294a7c9dc54802d512a5d891a35c1663392caryclark        return ++fSpanID;
12454359294a7c9dc54802d512a5d891a35c1663392caryclark    }
12554359294a7c9dc54802d512a5d891a35c1663392caryclark#endif
12654359294a7c9dc54802d512a5d891a35c1663392caryclark
12754359294a7c9dc54802d512a5d891a35c1663392caryclark    Phase phase() const {
12854359294a7c9dc54802d512a5d891a35c1663392caryclark        return fPhase;
12954359294a7c9dc54802d512a5d891a35c1663392caryclark    }
13054359294a7c9dc54802d512a5d891a35c1663392caryclark
13154359294a7c9dc54802d512a5d891a35c1663392caryclark    void setAngleCoincidence() {
13254359294a7c9dc54802d512a5d891a35c1663392caryclark        fAngleCoincidence = true;
13354359294a7c9dc54802d512a5d891a35c1663392caryclark    }
13455888e44171ffd48b591d19256884a969fe4da17caryclark
13555888e44171ffd48b591d19256884a969fe4da17caryclark    void setCoincidence(SkOpCoincidence* coincidence) {
13655888e44171ffd48b591d19256884a969fe4da17caryclark        fCoincidence = coincidence;
13755888e44171ffd48b591d19256884a969fe4da17caryclark    }
13854359294a7c9dc54802d512a5d891a35c1663392caryclark
139624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark    void setContourHead(SkOpContourHead* contourHead) {
140624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark        fContourHead = contourHead;
141624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark    }
142624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark
14354359294a7c9dc54802d512a5d891a35c1663392caryclark    void setPhase(Phase phase) {
14454359294a7c9dc54802d512a5d891a35c1663392caryclark        SkASSERT(fPhase != phase);
14554359294a7c9dc54802d512a5d891a35c1663392caryclark        fPhase = phase;
14654359294a7c9dc54802d512a5d891a35c1663392caryclark    }
14754359294a7c9dc54802d512a5d891a35c1663392caryclark
14854359294a7c9dc54802d512a5d891a35c1663392caryclark    // called in very rare cases where angles are sorted incorrectly -- signfies op will fail
14954359294a7c9dc54802d512a5d891a35c1663392caryclark    void setWindingFailed() {
15054359294a7c9dc54802d512a5d891a35c1663392caryclark        fWindingFailed = true;
15154359294a7c9dc54802d512a5d891a35c1663392caryclark    }
15254359294a7c9dc54802d512a5d891a35c1663392caryclark
15354359294a7c9dc54802d512a5d891a35c1663392caryclark    bool windingFailed() const {
15454359294a7c9dc54802d512a5d891a35c1663392caryclark        return fWindingFailed;
15554359294a7c9dc54802d512a5d891a35c1663392caryclark    }
15654359294a7c9dc54802d512a5d891a35c1663392caryclark
15754359294a7c9dc54802d512a5d891a35c1663392caryclarkprivate:
15855888e44171ffd48b591d19256884a969fe4da17caryclark    SkChunkAlloc* fAllocator;
15954359294a7c9dc54802d512a5d891a35c1663392caryclark    SkOpCoincidence* fCoincidence;
160624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark    SkOpContourHead* fContourHead;
1614e1a4c9399b8bb0897218f3ec10c254d3bb97463caryclark    int fNested;
16254359294a7c9dc54802d512a5d891a35c1663392caryclark    bool fWindingFailed;
16354359294a7c9dc54802d512a5d891a35c1663392caryclark    bool fAngleCoincidence;
16454359294a7c9dc54802d512a5d891a35c1663392caryclark    Phase fPhase;
16554359294a7c9dc54802d512a5d891a35c1663392caryclark#ifdef SK_DEBUG
166d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark    const char* fDebugTestName;
16754359294a7c9dc54802d512a5d891a35c1663392caryclark    int fAngleID;
16826ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    int fCoinID;
16954359294a7c9dc54802d512a5d891a35c1663392caryclark    int fContourID;
17054359294a7c9dc54802d512a5d891a35c1663392caryclark    int fPtTID;
17154359294a7c9dc54802d512a5d891a35c1663392caryclark    int fSegmentID;
17254359294a7c9dc54802d512a5d891a35c1663392caryclark    int fSpanID;
173dae6b97705fde08958b1a36fa6ce685d28fc692ccaryclark    bool fDebugSkipAssert;
17454359294a7c9dc54802d512a5d891a35c1663392caryclark#endif
17526ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark#if DEBUG_T_SECT_LOOP_COUNT
17626ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    int fDebugLoopCount[3];
17726ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    SkPath::Verb fDebugWorstVerb[6];
17826ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    SkPoint fDebugWorstPts[24];
17926ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark    float fDebugWorstWeight[6];
18026ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark#endif
18155888e44171ffd48b591d19256884a969fe4da17caryclark#if DEBUG_COINCIDENCE
18255888e44171ffd48b591d19256884a969fe4da17caryclark    bool fDebugCheckHealth;
18355888e44171ffd48b591d19256884a969fe4da17caryclark#endif
18454359294a7c9dc54802d512a5d891a35c1663392caryclark};
18554359294a7c9dc54802d512a5d891a35c1663392caryclark
186cdeff81bdb2e5cde422b6850634c5d3977fcbae9caryclark#ifdef SK_DEBUG
187e25a4f6cbeaccfdc34cf031103f0fbc3e53a3ee5caryclark#define SkOPASSERT(cond) SkASSERT((this->globalState() && \
188e25a4f6cbeaccfdc34cf031103f0fbc3e53a3ee5caryclark        this->globalState()->debugSkipAssert()) || cond)
1891597628fa38d24f23ad505bfb40e70e7c8617457caryclark#define SkOPOBJASSERT(obj, cond) SkASSERT((obj->debugGlobalState() && \
1901597628fa38d24f23ad505bfb40e70e7c8617457caryclark        obj->debugGlobalState()->debugSkipAssert()) || cond)
191cdeff81bdb2e5cde422b6850634c5d3977fcbae9caryclark#else
192cdeff81bdb2e5cde422b6850634c5d3977fcbae9caryclark#define SkOPASSERT(cond)
193cdeff81bdb2e5cde422b6850634c5d3977fcbae9caryclark#define SkOPOBJASSERT(obj, cond)
194cdeff81bdb2e5cde422b6850634c5d3977fcbae9caryclark#endif
1951597628fa38d24f23ad505bfb40e70e7c8617457caryclark
196c3f63570c35a1e2bc84b33906c6401d6f3062bf2caryclark@google.com// Use Almost Equal when comparing coordinates. Use epsilon to compare T values.
1974fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.combool AlmostEqualUlps(float a, float b);
1984fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.cominline bool AlmostEqualUlps(double a, double b) {
1994fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.com    return AlmostEqualUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
20007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
20107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
20255888e44171ffd48b591d19256884a969fe4da17caryclarkbool AlmostEqualUlpsNoNormalCheck(float a, float b);
20355888e44171ffd48b591d19256884a969fe4da17caryclarkinline bool AlmostEqualUlpsNoNormalCheck(double a, double b) {
20455888e44171ffd48b591d19256884a969fe4da17caryclark    return AlmostEqualUlpsNoNormalCheck(SkDoubleToScalar(a), SkDoubleToScalar(b));
20555888e44171ffd48b591d19256884a969fe4da17caryclark}
20655888e44171ffd48b591d19256884a969fe4da17caryclark
207b669300a9753893ef900207c38aeff2d467764e5caryclarkbool AlmostEqualUlps_Pin(float a, float b);
208b669300a9753893ef900207c38aeff2d467764e5caryclarkinline bool AlmostEqualUlps_Pin(double a, double b) {
209b669300a9753893ef900207c38aeff2d467764e5caryclark    return AlmostEqualUlps_Pin(SkDoubleToScalar(a), SkDoubleToScalar(b));
210b669300a9753893ef900207c38aeff2d467764e5caryclark}
211b669300a9753893ef900207c38aeff2d467764e5caryclark
2127eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com// Use Almost Dequal when comparing should not special case denormalized values.
2137eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.combool AlmostDequalUlps(float a, float b);
2142db7fe7d3b7ee875e1099a22f0af17520696f5d7commit-bot@chromium.orgbool AlmostDequalUlps(double a, double b);
2157eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com
216570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.combool NotAlmostEqualUlps(float a, float b);
217570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.cominline bool NotAlmostEqualUlps(double a, double b) {
218570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com    return NotAlmostEqualUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
219570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com}
220570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com
221b669300a9753893ef900207c38aeff2d467764e5caryclarkbool NotAlmostEqualUlps_Pin(float a, float b);
222b669300a9753893ef900207c38aeff2d467764e5caryclarkinline bool NotAlmostEqualUlps_Pin(double a, double b) {
223b669300a9753893ef900207c38aeff2d467764e5caryclark    return NotAlmostEqualUlps_Pin(SkDoubleToScalar(a), SkDoubleToScalar(b));
224b669300a9753893ef900207c38aeff2d467764e5caryclark}
225b669300a9753893ef900207c38aeff2d467764e5caryclark
2267eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.combool NotAlmostDequalUlps(float a, float b);
2277eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.cominline bool NotAlmostDequalUlps(double a, double b) {
2287eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com    return NotAlmostDequalUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
2297eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com}
2307eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com
231570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com// Use Almost Bequal when comparing coordinates in conjunction with between.
232570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.combool AlmostBequalUlps(float a, float b);
233570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.cominline bool AlmostBequalUlps(double a, double b) {
234570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com    return AlmostBequalUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
235570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com}
236570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com
237a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.combool AlmostPequalUlps(float a, float b);
238a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.cominline bool AlmostPequalUlps(double a, double b) {
239a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    return AlmostPequalUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
240a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com}
241a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
2424fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.combool RoughlyEqualUlps(float a, float b);
2434fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.cominline bool RoughlyEqualUlps(double a, double b) {
2444fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.com    return RoughlyEqualUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
24507e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com}
24607e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com
247570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.combool AlmostLessUlps(float a, float b);
248570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.cominline bool AlmostLessUlps(double a, double b) {
249570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com    return AlmostLessUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
250570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com}
251570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com
252570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.combool AlmostLessOrEqualUlps(float a, float b);
253570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.cominline bool AlmostLessOrEqualUlps(double a, double b) {
254570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com    return AlmostLessOrEqualUlps(SkDoubleToScalar(a), SkDoubleToScalar(b));
255570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com}
256570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com
257fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.combool AlmostBetweenUlps(float a, float b, float c);
2584fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.cominline bool AlmostBetweenUlps(double a, double b, double c) {
2594fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.com    return AlmostBetweenUlps(SkDoubleToScalar(a), SkDoubleToScalar(b), SkDoubleToScalar(c));
2604fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.com}
2614fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.com
2624fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.comint UlpsDistance(float a, float b);
2634fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.cominline int UlpsDistance(double a, double b) {
2644fdbb229649caf74e5c1b55a1823926df903af34caryclark@google.com    return UlpsDistance(SkDoubleToScalar(a), SkDoubleToScalar(b));
265fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com}
266fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com
26707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// FLT_EPSILON == 1.19209290E-07 == 1 / (2 ^ 23)
26807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// DBL_EPSILON == 2.22045e-16
26907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double FLT_EPSILON_CUBED = FLT_EPSILON * FLT_EPSILON * FLT_EPSILON;
27007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double FLT_EPSILON_HALF = FLT_EPSILON / 2;
271cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.comconst double FLT_EPSILON_DOUBLE = FLT_EPSILON * 2;
2724431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgconst double FLT_EPSILON_ORDERABLE_ERR = FLT_EPSILON * 16;
27307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double FLT_EPSILON_SQUARED = FLT_EPSILON * FLT_EPSILON;
27407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double FLT_EPSILON_SQRT = sqrt(FLT_EPSILON);
27507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double FLT_EPSILON_INVERSE = 1 / FLT_EPSILON;
27607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double DBL_EPSILON_ERR = DBL_EPSILON * 4;  // FIXME: tune -- allow a few bits of error
277cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.comconst double DBL_EPSILON_SUBDIVIDE_ERR = DBL_EPSILON * 16;
27807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double ROUGH_EPSILON = FLT_EPSILON * 64;
27907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comconst double MORE_ROUGH_EPSILON = FLT_EPSILON * 256;
280dac1d17027dcaa5596885a9f333979418b35001ccaryclarkconst double WAY_ROUGH_EPSILON = FLT_EPSILON * 2048;
28154359294a7c9dc54802d512a5d891a35c1663392caryclarkconst double BUMP_EPSILON = FLT_EPSILON * 4096;
282dac1d17027dcaa5596885a9f333979418b35001ccaryclark
28355888e44171ffd48b591d19256884a969fe4da17caryclarkconst SkScalar INVERSE_NUMBER_RANGE = FLT_EPSILON_ORDERABLE_ERR;
28455888e44171ffd48b591d19256884a969fe4da17caryclark
285dac1d17027dcaa5596885a9f333979418b35001ccaryclarkinline bool zero_or_one(double x) {
286dac1d17027dcaa5596885a9f333979418b35001ccaryclark    return x == 0 || x == 1;
287dac1d17027dcaa5596885a9f333979418b35001ccaryclark}
28807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
28907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero(double x) {
29007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) < FLT_EPSILON;
29107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
29207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
29307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool precisely_zero(double x) {
29407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) < DBL_EPSILON_ERR;
29507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
29607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
297cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.cominline bool precisely_subdivide_zero(double x) {
298cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    return fabs(x) < DBL_EPSILON_SUBDIVIDE_ERR;
299cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com}
300cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com
30107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero(float x) {
30207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) < FLT_EPSILON;
30307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
30407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
30507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero_cubed(double x) {
30607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) < FLT_EPSILON_CUBED;
30707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
30807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
30907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero_half(double x) {
31007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) < FLT_EPSILON_HALF;
31107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
31207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
313cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.cominline bool approximately_zero_double(double x) {
314cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    return fabs(x) < FLT_EPSILON_DOUBLE;
315cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com}
316cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com
3174431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_zero_orderable(double x) {
3184431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return fabs(x) < FLT_EPSILON_ORDERABLE_ERR;
3194431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
3204431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
32107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero_squared(double x) {
32207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) < FLT_EPSILON_SQUARED;
32307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
32407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
32507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero_sqrt(double x) {
32607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) < FLT_EPSILON_SQRT;
32707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
32807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
329cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.cominline bool roughly_zero(double x) {
330cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    return fabs(x) < ROUGH_EPSILON;
331cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com}
332cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com
33307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero_inverse(double x) {
33407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x) > FLT_EPSILON_INVERSE;
33507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
33607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
33707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero_when_compared_to(double x, double y) {
3384431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x == 0 || fabs(x) < fabs(y * FLT_EPSILON);
33907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
34007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
34154359294a7c9dc54802d512a5d891a35c1663392caryclarkinline bool precisely_zero_when_compared_to(double x, double y) {
34254359294a7c9dc54802d512a5d891a35c1663392caryclark    return x == 0 || fabs(x) < fabs(y * DBL_EPSILON);
34354359294a7c9dc54802d512a5d891a35c1663392caryclark}
34454359294a7c9dc54802d512a5d891a35c1663392caryclark
34555888e44171ffd48b591d19256884a969fe4da17caryclarkinline bool roughly_zero_when_compared_to(double x, double y) {
34655888e44171ffd48b591d19256884a969fe4da17caryclark    return x == 0 || fabs(x) < fabs(y * ROUGH_EPSILON);
34755888e44171ffd48b591d19256884a969fe4da17caryclark}
34855888e44171ffd48b591d19256884a969fe4da17caryclark
34907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// Use this for comparing Ts in the range of 0 to 1. For general numbers (larger and smaller) use
35007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// AlmostEqualUlps instead.
35107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_equal(double x, double y) {
35207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return approximately_zero(x - y);
35307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
35407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
35507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool precisely_equal(double x, double y) {
35607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return precisely_zero(x - y);
35707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
35807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
359cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.cominline bool precisely_subdivide_equal(double x, double y) {
360cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    return precisely_subdivide_zero(x - y);
361cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com}
362cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com
36307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_equal_half(double x, double y) {
36407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return approximately_zero_half(x - y);
36507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
36607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
367cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.cominline bool approximately_equal_double(double x, double y) {
368cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    return approximately_zero_double(x - y);
369cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com}
370cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com
3714431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_equal_orderable(double x, double y) {
3724431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return approximately_zero_orderable(x - y);
3734431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
3744431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
37507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_equal_squared(double x, double y) {
37607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return approximately_equal(x, y);
37707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
37807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
37907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_greater(double x, double y) {
38007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x - FLT_EPSILON >= y;
38107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
38207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
3834431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_greater_double(double x, double y) {
3844431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x - FLT_EPSILON_DOUBLE >= y;
3854431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
3864431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
3874431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_greater_orderable(double x, double y) {
3884431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x - FLT_EPSILON_ORDERABLE_ERR >= y;
3894431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
3904431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
39107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_greater_or_equal(double x, double y) {
39207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x + FLT_EPSILON > y;
39307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
39407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
3954431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_greater_or_equal_double(double x, double y) {
3964431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x + FLT_EPSILON_DOUBLE > y;
3974431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
3984431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
3994431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_greater_or_equal_orderable(double x, double y) {
4004431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x + FLT_EPSILON_ORDERABLE_ERR > y;
4014431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
4024431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
40307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_lesser(double x, double y) {
40407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x + FLT_EPSILON <= y;
40507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
40607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
4074431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_lesser_double(double x, double y) {
4084431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x + FLT_EPSILON_DOUBLE <= y;
4094431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
4104431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
4114431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_lesser_orderable(double x, double y) {
4124431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x + FLT_EPSILON_ORDERABLE_ERR <= y;
4134431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
4144431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
41507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_lesser_or_equal(double x, double y) {
41607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x - FLT_EPSILON < y;
41707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
41807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
4194431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_lesser_or_equal_double(double x, double y) {
4204431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x - FLT_EPSILON_DOUBLE < y;
4214431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
4224431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
4234431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_lesser_or_equal_orderable(double x, double y) {
4244431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x - FLT_EPSILON_ORDERABLE_ERR < y;
4254431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
4264431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
42707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_greater_than_one(double x) {
42807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x > 1 - FLT_EPSILON;
42907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
43007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
43107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool precisely_greater_than_one(double x) {
43207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x > 1 - DBL_EPSILON_ERR;
43307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
43407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
43507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_less_than_zero(double x) {
43607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x < FLT_EPSILON;
43707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
43807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
43907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool precisely_less_than_zero(double x) {
44007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x < DBL_EPSILON_ERR;
44107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
44207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
44307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_negative(double x) {
44407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x < FLT_EPSILON;
44507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
44607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
4474431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_negative_orderable(double x) {
4484431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x < FLT_EPSILON_ORDERABLE_ERR;
4494431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
4504431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
45107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool precisely_negative(double x) {
45207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x < DBL_EPSILON_ERR;
45307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
45407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
45507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_one_or_less(double x) {
45607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x < 1 + FLT_EPSILON;
45707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
45807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
4594431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_one_or_less_double(double x) {
4604431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x < 1 + FLT_EPSILON_DOUBLE;
4614431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
4624431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
46307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_positive(double x) {
46407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x > -FLT_EPSILON;
46507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
46607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
46707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_positive_squared(double x) {
46807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x > -(FLT_EPSILON_SQUARED);
46907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
47007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
47107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_zero_or_more(double x) {
47207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return x > -FLT_EPSILON;
47307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
47407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
4754431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_zero_or_more_double(double x) {
4764431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return x > -FLT_EPSILON_DOUBLE;
4774431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
4784431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
4794431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orginline bool approximately_between_orderable(double a, double b, double c) {
4804431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return a <= c
4814431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            ? approximately_negative_orderable(a - b) && approximately_negative_orderable(b - c)
4824431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            : approximately_negative_orderable(b - a) && approximately_negative_orderable(c - b);
4834431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
4844431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
48507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool approximately_between(double a, double b, double c) {
48607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return a <= c ? approximately_negative(a - b) && approximately_negative(b - c)
48707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            : approximately_negative(b - a) && approximately_negative(c - b);
48807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
4890361032c0b53401030a720bc8b4930c3ec59f19ecaryclark@google.com
4900361032c0b53401030a720bc8b4930c3ec59f19ecaryclark@google.cominline bool precisely_between(double a, double b, double c) {
4910361032c0b53401030a720bc8b4930c3ec59f19ecaryclark@google.com    return a <= c ? precisely_negative(a - b) && precisely_negative(b - c)
4920361032c0b53401030a720bc8b4930c3ec59f19ecaryclark@google.com            : precisely_negative(b - a) && precisely_negative(c - b);
4930361032c0b53401030a720bc8b4930c3ec59f19ecaryclark@google.com}
49407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
49507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// returns true if (a <= b <= c) || (a >= b >= c)
49607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool between(double a, double b, double c) {
49754359294a7c9dc54802d512a5d891a35c1663392caryclark    SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0)
49854359294a7c9dc54802d512a5d891a35c1663392caryclark            || (precisely_zero(a) && precisely_zero(b) && precisely_zero(c)));
49907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return (a - b) * (c - b) <= 0;
50007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
50107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
502dac1d17027dcaa5596885a9f333979418b35001ccaryclarkinline bool roughly_equal(double x, double y) {
503dac1d17027dcaa5596885a9f333979418b35001ccaryclark    return fabs(x - y) < ROUGH_EPSILON;
504dac1d17027dcaa5596885a9f333979418b35001ccaryclark}
505dac1d17027dcaa5596885a9f333979418b35001ccaryclark
50654359294a7c9dc54802d512a5d891a35c1663392caryclarkinline bool roughly_negative(double x) {
50754359294a7c9dc54802d512a5d891a35c1663392caryclark    return x < ROUGH_EPSILON;
50854359294a7c9dc54802d512a5d891a35c1663392caryclark}
50954359294a7c9dc54802d512a5d891a35c1663392caryclark
51054359294a7c9dc54802d512a5d891a35c1663392caryclarkinline bool roughly_between(double a, double b, double c) {
51154359294a7c9dc54802d512a5d891a35c1663392caryclark    return a <= c ? roughly_negative(a - b) && roughly_negative(b - c)
51254359294a7c9dc54802d512a5d891a35c1663392caryclark            : roughly_negative(b - a) && roughly_negative(c - b);
51354359294a7c9dc54802d512a5d891a35c1663392caryclark}
51454359294a7c9dc54802d512a5d891a35c1663392caryclark
51507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline bool more_roughly_equal(double x, double y) {
51607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return fabs(x - y) < MORE_ROUGH_EPSILON;
51707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
51807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
519dac1d17027dcaa5596885a9f333979418b35001ccaryclarkinline bool way_roughly_equal(double x, double y) {
520dac1d17027dcaa5596885a9f333979418b35001ccaryclark    return fabs(x - y) < WAY_ROUGH_EPSILON;
52107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
52207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
52307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstruct SkDPoint;
52407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstruct SkDVector;
52507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstruct SkDLine;
52607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstruct SkDQuad;
5271049f1246e7be4ccb68001361efceb8933e6f81ccaryclarkstruct SkDConic;
52807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstruct SkDCubic;
52907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstruct SkDRect;
53007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
531277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.cominline SkPath::Verb SkPathOpsPointsToVerb(int points) {
532277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com    int verb = (1 << points) >> 1;
533277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com#ifdef SK_DEBUG
534277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com    switch (points) {
535277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com        case 0: SkASSERT(SkPath::kMove_Verb == verb); break;
536277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com        case 1: SkASSERT(SkPath::kLine_Verb == verb); break;
537277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com        case 2: SkASSERT(SkPath::kQuad_Verb == verb); break;
538277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com        case 3: SkASSERT(SkPath::kCubic_Verb == verb); break;
539330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com        default: SkDEBUGFAIL("should not be here");
540277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com    }
541277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com#endif
542277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com    return (SkPath::Verb)verb;
543277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com}
544277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com
545277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.cominline int SkPathOpsVerbToPoints(SkPath::Verb verb) {
5461049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    int points = (int) verb - (((int) verb + 1) >> 2);
547277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com#ifdef SK_DEBUG
548277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com    switch (verb) {
549277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com        case SkPath::kLine_Verb: SkASSERT(1 == points); break;
550277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com        case SkPath::kQuad_Verb: SkASSERT(2 == points); break;
5511049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        case SkPath::kConic_Verb: SkASSERT(2 == points); break;
552277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com        case SkPath::kCubic_Verb: SkASSERT(3 == points); break;
553330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com        default: SkDEBUGFAIL("should not get here");
554277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com    }
555277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com#endif
556277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com    return points;
557277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com}
558277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com
55907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline double SkDInterp(double A, double B, double t) {
56007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return A + (B - A) * t;
56107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
56207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
56307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comdouble SkDCubeRoot(double x);
56407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
56507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com/* Returns -1 if negative, 0 if zero, 1 if positive
56607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com*/
56707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline int SkDSign(double x) {
56807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return (x > 0) - (x < 0);
56907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
57007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
57107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com/* Returns 0 if negative, 1 if zero, 2 if positive
57207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com*/
57307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline int SKDSide(double x) {
57407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return (x > 0) + (x >= 0);
57507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
57607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
57707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com/* Returns 1 if negative, 2 if zero, 4 if positive
57807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com*/
57907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.cominline int SkDSideBit(double x) {
58007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return 1 << SKDSide(x);
58107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
58207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
583fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.cominline double SkPinT(double t) {
584fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com    return precisely_less_than_zero(t) ? 0 : precisely_greater_than_one(t) ? 1 : t;
585fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com}
586fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com
58707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#endif
588