Home | History | Annotate | Download | only in Intersection
      1 /*
      2  * Copyright 2012 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 #ifndef Intersections_DEFINE
      8 #define Intersections_DEFINE
      9 
     10 class Intersections {
     11 public:
     12     Intersections()
     13         : fFlip(0)
     14 #ifdef SK_DEBUG
     15         , fDepth(0)
     16 #endif
     17         , fSwap(0)
     18     {
     19 #ifdef SK_DEBUG
     20         bzero(fPt, sizeof(fPt));
     21         bzero(fT, sizeof(fT));
     22         bzero(fIsCoincident, sizeof(fIsCoincident));
     23 #endif
     24         reset();
     25     }
     26 
     27     int coincidentUsed() const {
     28         if (!fIsCoincident[0]) {
     29             SkASSERT(!fIsCoincident[0]);
     30             return 0;
     31         }
     32         int count = 0;
     33         SkDEBUGCODE(int count2 = 0;)
     34         for (int index = 0; index < fUsed; ++index) {
     35             if (fIsCoincident[0] & (1 << index)) {
     36                 ++count;
     37             }
     38     #ifdef SK_DEBUG
     39             if (fIsCoincident[1] & (1 << index)) {
     40                 ++count2;
     41             }
     42     #endif
     43         }
     44         SkASSERT(count == count2);
     45         return count;
     46     }
     47 
     48     void offset(int base, double start, double end) {
     49         for (int index = base; index < fUsed; ++index) {
     50             double val = fT[fSwap][index];
     51             val *= end - start;
     52             val += start;
     53             fT[fSwap][index] = val;
     54         }
     55     }
     56 
     57     // FIXME : does not respect swap
     58     int insert(double one, double two, const _Point& pt);
     59 
     60     // start if index == 0 : end if index == 1
     61     void insertCoincident(double one, double two, const _Point& pt) {
     62         int index = insertSwap(one, two, pt);
     63         int bit = 1 << index;
     64         fIsCoincident[0] |= bit;
     65         fIsCoincident[1] |= bit;
     66     }
     67 
     68     void insertCoincidentPair(double s1, double e1, double s2, double e2,
     69             const _Point& startPt, const _Point& endPt);
     70 
     71     int insertSwap(double one, double two, const _Point& pt) {
     72         if (fSwap) {
     73             return insert(two, one, pt);
     74         } else {
     75             return insert(one, two, pt);
     76         }
     77     }
     78 
     79     bool intersected() const {
     80         return fUsed > 0;
     81     }
     82 
     83     void removeOne(int index);
     84 
     85     // leaves flip, swap alone
     86     void reset() {
     87         fUsed = 0;
     88         fUnsortable = false;
     89     }
     90 
     91     void swap() {
     92         fSwap ^= true;
     93     }
     94 
     95     void swapPts() {
     96         int index;
     97         for (index = 0; index < fUsed; ++index) {
     98             SkTSwap(fT[0][index], fT[1][index]);
     99         }
    100     }
    101 
    102     bool swapped() const {
    103         return fSwap;
    104     }
    105 
    106     bool unsortable() const {
    107         return fUnsortable;
    108     }
    109 
    110     int used() const {
    111         return fUsed;
    112     }
    113 
    114     void downDepth() {
    115         SkASSERT(--fDepth >= 0);
    116     }
    117 
    118     void upDepth() {
    119         SkASSERT(++fDepth < 16);
    120     }
    121 
    122 #ifdef SK_DEBUG
    123     int depth() const {
    124         return fDepth;
    125     }
    126 #endif
    127 
    128     _Point fPt[9];
    129     double fT[2][9];
    130     unsigned short fIsCoincident[2]; // bit arrays, one bit set for each coincident T
    131     unsigned char fUsed;
    132     bool fFlip;
    133     bool fUnsortable;
    134 #ifdef SK_DEBUG
    135     int fDepth;
    136 #endif
    137 protected:
    138     // used by addCoincident to remove ordinary intersections in range
    139     void remove(double one, double two, const _Point& startPt, const _Point& endPt);
    140 private:
    141     bool fSwap;
    142 };
    143 
    144 #endif
    145