1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2012 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SkIntersections_DEFINE 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define SkIntersections_DEFINE 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPathOpsConic.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPathOpsCubic.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPathOpsLine.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPathOpsPoint.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPathOpsQuad.h" 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkIntersections { 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntersections(SkDEBUGCODE(SkOpGlobalState* globalState = nullptr)) 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : fSwap(0) 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DEBUG 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGPARAMS(fDebugGlobalState(globalState)) 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fDepth(0) 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_bzero(fPt, sizeof(fPt)); 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_bzero(fPt2, sizeof(fPt2)); 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_bzero(fT, sizeof(fT)); 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_bzero(fNearlySame, sizeof(fNearlySame)); 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if DEBUG_T_SECT_LOOP_COUNT 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_bzero(fDebugLoopCount, sizeof(fDebugLoopCount)); 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot reset(); 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMax = 0; // require that the caller set the max 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot class TArray { 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot public: 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot explicit TArray(const double ts[10]) : fTArray(ts) {} 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot double operator[](int n) const { 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fTArray[n]; 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const double* fTArray; 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TArray operator[](int n) const { return TArray(fT[n]); } 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void allowNear(bool nearAllowed) { 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fAllowNear = nearAllowed; 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void clearCoincidence(int index) { 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(index >= 0); 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int bit = 1 << index; 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fIsCoincident[0] &= ~bit; 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fIsCoincident[1] &= ~bit; 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int conicHorizontal(const SkPoint a[3], SkScalar weight, SkScalar left, SkScalar right, 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar y, bool flipped) { 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDConic conic; 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot conic.set(a, weight); 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMax = 2; 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return horizontal(conic, left, right, y, flipped); 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int conicVertical(const SkPoint a[3], SkScalar weight, SkScalar top, SkScalar bottom, 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar x, bool flipped) { 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDConic conic; 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot conic.set(a, weight); 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMax = 2; 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return vertical(conic, top, bottom, x, flipped); 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int conicLine(const SkPoint a[3], SkScalar weight, const SkPoint b[2]) { 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDConic conic; 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot conic.set(a, weight); 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDLine line; 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot line.set(b); 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMax = 3; // 2; permit small coincident segment + non-coincident intersection 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return intersect(conic, line); 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int cubicHorizontal(const SkPoint a[4], SkScalar left, SkScalar right, SkScalar y, 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool flipped) { 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDCubic cubic; 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cubic.set(a); 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMax = 3; 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return horizontal(cubic, left, right, y, flipped); 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int cubicVertical(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) { 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDCubic cubic; 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cubic.set(a); 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMax = 3; 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return vertical(cubic, top, bottom, x, flipped); 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int cubicLine(const SkPoint a[4], const SkPoint b[2]) { 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDCubic cubic; 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cubic.set(a); 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDLine line; 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot line.set(b); 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMax = 3; 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return intersect(cubic, line); 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DEBUG 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkOpGlobalState* globalState() const { return fDebugGlobalState; } 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool hasT(double t) const { 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(t == 0 || t == 1); 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fUsed > 0 && (t == 0 ? fT[0][0] == 0 : fT[0][fUsed - 1] == 1); 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool hasOppT(double t) const { 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(t == 0 || t == 1); 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fUsed > 0 && (fT[1][0] == t || fT[1][fUsed - 1] == t); 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int insertSwap(double one, double two, const SkDPoint& pt) { 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fSwap) { 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return insert(two, one, pt); 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return insert(one, two, pt); 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool isCoincident(int index) { 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return (fIsCoincident[0] & 1 << index) != 0; 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int lineHorizontal(const SkPoint a[2], SkScalar left, SkScalar right, SkScalar y, 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool flipped) { 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDLine line; 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot line.set(a); 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMax = 2; 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return horizontal(line, left, right, y, flipped); 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int lineVertical(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) { 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDLine line; 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot line.set(a); 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMax = 2; 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return vertical(line, top, bottom, x, flipped); 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int lineLine(const SkPoint a[2], const SkPoint b[2]) { 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDLine aLine, bLine; 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot aLine.set(a); 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bLine.set(b); 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMax = 2; 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return intersect(aLine, bLine); 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool nearlySame(int index) const { 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(index == 0 || index == 1); 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fNearlySame[index]; 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkDPoint& pt(int index) const { 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fPt[index]; 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkDPoint& pt2(int index) const { 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fPt2[index]; 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int quadHorizontal(const SkPoint a[3], SkScalar left, SkScalar right, SkScalar y, 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool flipped) { 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDQuad quad; 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot quad.set(a); 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMax = 2; 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return horizontal(quad, left, right, y, flipped); 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int quadVertical(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) { 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDQuad quad; 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot quad.set(a); 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMax = 2; 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return vertical(quad, top, bottom, x, flipped); 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int quadLine(const SkPoint a[3], const SkPoint b[2]) { 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDQuad quad; 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot quad.set(a); 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDLine line; 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot line.set(b); 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return intersect(quad, line); 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // leaves swap, max alone 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void reset() { 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fAllowNear = true; 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fUsed = 0; 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_bzero(fIsCoincident, sizeof(fIsCoincident)); 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void set(bool swap, int tIndex, double t) { 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fT[(int) swap][tIndex] = t; 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void setMax(int max) { 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(max <= (int) SK_ARRAY_COUNT(fPt)); 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMax = max; 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void swap() { 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fSwap ^= true; 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool swapped() const { 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fSwap; 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int used() const { 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fUsed; 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void downDepth() { 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(--fDepth >= 0); 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool unBumpT(int index) { 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fUsed == 1); 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fT[0][index] = fT[0][index] * (1 + BUMP_EPSILON * 2) - BUMP_EPSILON; 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!between(0, fT[0][index], 1)) { 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fUsed = 0; 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void upDepth() { 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(++fDepth < 16); 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void alignQuadPts(const SkPoint a[3], const SkPoint b[3]); 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int cleanUpCoincidence(); 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int closestTo(double rangeStart, double rangeEnd, const SkDPoint& testPt, double* dist) const; 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void cubicInsert(double one, double two, const SkDPoint& pt, const SkDCubic& c1, 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkDCubic& c2); 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void flip(); 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int horizontal(const SkDLine&, double left, double right, double y, bool flipped); 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int horizontal(const SkDQuad&, double left, double right, double y, bool flipped); 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int horizontal(const SkDQuad&, double left, double right, double y, double tRange[2]); 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int horizontal(const SkDCubic&, double y, double tRange[3]); 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int horizontal(const SkDConic&, double left, double right, double y, bool flipped); 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int horizontal(const SkDCubic&, double left, double right, double y, bool flipped); 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int horizontal(const SkDCubic&, double left, double right, double y, double tRange[3]); 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static double HorizontalIntercept(const SkDLine& line, double y); 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static int HorizontalIntercept(const SkDQuad& quad, SkScalar y, double* roots); 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static int HorizontalIntercept(const SkDConic& conic, SkScalar y, double* roots); 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // FIXME : does not respect swap 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int insert(double one, double two, const SkDPoint& pt); 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void insertNear(double one, double two, const SkDPoint& pt1, const SkDPoint& pt2); 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // start if index == 0 : end if index == 1 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int insertCoincident(double one, double two, const SkDPoint& pt); 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int intersect(const SkDLine&, const SkDLine&); 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int intersect(const SkDQuad&, const SkDLine&); 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int intersect(const SkDQuad&, const SkDQuad&); 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int intersect(const SkDConic&, const SkDLine&); 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int intersect(const SkDConic&, const SkDQuad&); 263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int intersect(const SkDConic&, const SkDConic&); 264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int intersect(const SkDCubic&, const SkDLine&); 265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int intersect(const SkDCubic&, const SkDQuad&); 266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int intersect(const SkDCubic&, const SkDConic&); 267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int intersect(const SkDCubic&, const SkDCubic&); 268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int intersectRay(const SkDLine&, const SkDLine&); 269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int intersectRay(const SkDQuad&, const SkDLine&); 270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int intersectRay(const SkDConic&, const SkDLine&); 271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int intersectRay(const SkDCubic&, const SkDLine&); 272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void merge(const SkIntersections& , int , const SkIntersections& , int ); 273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int mostOutside(double rangeStart, double rangeEnd, const SkDPoint& origin) const; 274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void removeOne(int index); 275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void setCoincident(int index); 276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int vertical(const SkDLine&, double top, double bottom, double x, bool flipped); 277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int vertical(const SkDQuad&, double top, double bottom, double x, bool flipped); 278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int vertical(const SkDConic&, double top, double bottom, double x, bool flipped); 279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int vertical(const SkDCubic&, double top, double bottom, double x, bool flipped); 280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static double VerticalIntercept(const SkDLine& line, double x); 281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static int VerticalIntercept(const SkDQuad& quad, SkScalar x, double* roots); 282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static int VerticalIntercept(const SkDConic& conic, SkScalar x, double* roots); 283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int depth() const { 285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DEBUG 286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fDepth; 287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#else 288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return 0; 289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot enum DebugLoop { 293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kIterations_DebugLoop, 294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kCoinCheck_DebugLoop, 295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kComputePerp_DebugLoop, 296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void debugBumpLoopCount(DebugLoop ); 299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int debugCoincidentUsed() const; 300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int debugLoopCount(DebugLoop ) const; 301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void debugResetLoopCount(); 302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void dump() const; // implemented for testing only 303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool cubicCheckCoincidence(const SkDCubic& c1, const SkDCubic& c2); 306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool cubicExactEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2); 307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void cubicNearEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2, const SkDRect& ); 308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void cleanUpParallelLines(bool parallel); 309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void computePoints(const SkDLine& line, int used); 310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDPoint fPt[13]; // FIXME: since scans store points as SkPoint, this should also 312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDPoint fPt2[2]; // used by nearly same to store alternate intersection point 313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot double fT[2][13]; 314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint16_t fIsCoincident[2]; // bit set for each curve's coincident T 315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool fNearlySame[2]; // true if end points nearly match 316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned char fUsed; 317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned char fMax; 318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool fAllowNear; 319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool fSwap; 320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DEBUG 321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkOpGlobalState* fDebugGlobalState; 322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int fDepth; 323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if DEBUG_T_SECT_LOOP_COUNT 325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int fDebugLoopCount[3]; 326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 330