Home | History | Annotate | Download | only in pathops
      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 #include "SkOpContour.h"
      8 #include "SkPath.h"
      9 
     10 class SkIntersectionHelper {
     11 public:
     12     enum SegmentType {
     13         kHorizontalLine_Segment = -1,
     14         kVerticalLine_Segment = 0,
     15         kLine_Segment = SkPath::kLine_Verb,
     16         kQuad_Segment = SkPath::kQuad_Verb,
     17         kCubic_Segment = SkPath::kCubic_Verb,
     18     };
     19 
     20     void addCoincident(SkIntersectionHelper& other, const SkIntersections& ts, bool swap) {
     21         fContour->addCoincident(fIndex, other.fContour, other.fIndex, ts, swap);
     22     }
     23 
     24     // FIXME: does it make sense to write otherIndex now if we're going to
     25     // fix it up later?
     26     void addOtherT(int index, double otherT, int otherIndex) {
     27         fContour->addOtherT(fIndex, index, otherT, otherIndex);
     28     }
     29 
     30     // Avoid collapsing t values that are close to the same since
     31     // we walk ts to describe consecutive intersections. Since a pair of ts can
     32     // be nearly equal, any problems caused by this should be taken care
     33     // of later.
     34     // On the edge or out of range values are negative; add 2 to get end
     35     int addT(const SkIntersectionHelper& other, const SkPoint& pt, double newT) {
     36         return fContour->addT(fIndex, other.fContour, other.fIndex, pt, newT);
     37     }
     38 
     39     int addSelfT(const SkIntersectionHelper& other, const SkPoint& pt, double newT) {
     40         return fContour->addSelfT(fIndex, other.fContour, other.fIndex, pt, newT);
     41     }
     42 
     43     int addUnsortableT(const SkIntersectionHelper& other, bool start, const SkPoint& pt,
     44                        double newT) {
     45         return fContour->addUnsortableT(fIndex, other.fContour, other.fIndex, start, pt, newT);
     46     }
     47 
     48     bool advance() {
     49         return ++fIndex < fLast;
     50     }
     51 
     52     SkScalar bottom() const {
     53         return bounds().fBottom;
     54     }
     55 
     56     const SkPathOpsBounds& bounds() const {
     57         return fContour->segments()[fIndex].bounds();
     58     }
     59 
     60     void init(SkOpContour* contour) {
     61         fContour = contour;
     62         fIndex = 0;
     63         fLast = contour->segments().count();
     64     }
     65 
     66     bool isAdjacent(const SkIntersectionHelper& next) {
     67         return fContour == next.fContour && fIndex + 1 == next.fIndex;
     68     }
     69 
     70     bool isFirstLast(const SkIntersectionHelper& next) {
     71         return fContour == next.fContour && fIndex == 0
     72                 && next.fIndex == fLast - 1;
     73     }
     74 
     75     SkScalar left() const {
     76         return bounds().fLeft;
     77     }
     78 
     79     const SkPoint* pts() const {
     80         return fContour->segments()[fIndex].pts();
     81     }
     82 
     83     SkScalar right() const {
     84         return bounds().fRight;
     85     }
     86 
     87     SegmentType segmentType() const {
     88         const SkOpSegment& segment = fContour->segments()[fIndex];
     89         SegmentType type = (SegmentType) segment.verb();
     90         if (type != kLine_Segment) {
     91             return type;
     92         }
     93         if (segment.isHorizontal()) {
     94             return kHorizontalLine_Segment;
     95         }
     96         if (segment.isVertical()) {
     97             return kVerticalLine_Segment;
     98         }
     99         return kLine_Segment;
    100     }
    101 
    102     bool startAfter(const SkIntersectionHelper& after) {
    103         fIndex = after.fIndex;
    104         return advance();
    105     }
    106 
    107     SkScalar top() const {
    108         return bounds().fTop;
    109     }
    110 
    111     SkPath::Verb verb() const {
    112         return fContour->segments()[fIndex].verb();
    113     }
    114 
    115     SkScalar x() const {
    116         return bounds().fLeft;
    117     }
    118 
    119     bool xFlipped() const {
    120         return x() != pts()[0].fX;
    121     }
    122 
    123     SkScalar y() const {
    124         return bounds().fTop;
    125     }
    126 
    127     bool yFlipped() const {
    128         return y() != pts()[0].fY;
    129     }
    130 
    131 private:
    132     SkOpContour* fContour;
    133     int fIndex;
    134     int fLast;
    135 };
    136