gfx/skia/trunk/src/pathops/SkIntersections.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/pathops/SkIntersections.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,288 @@
     1.4 +/*
     1.5 + * Copyright 2012 Google Inc.
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +#ifndef SkIntersections_DEFINE
    1.11 +#define SkIntersections_DEFINE
    1.12 +
    1.13 +#include "SkPathOpsCubic.h"
    1.14 +#include "SkPathOpsLine.h"
    1.15 +#include "SkPathOpsPoint.h"
    1.16 +#include "SkPathOpsQuad.h"
    1.17 +
    1.18 +class SkIntersections {
    1.19 +public:
    1.20 +    SkIntersections()
    1.21 +        : fSwap(0)
    1.22 +#ifdef SK_DEBUG
    1.23 +        , fDepth(0)
    1.24 +#endif
    1.25 +    {
    1.26 +        sk_bzero(fPt, sizeof(fPt));
    1.27 +        sk_bzero(fT, sizeof(fT));
    1.28 +        sk_bzero(fIsCoincident, sizeof(fIsCoincident));
    1.29 +        reset();
    1.30 +        fMax = 0;  // require that the caller set the max
    1.31 +    }
    1.32 +
    1.33 +    class TArray {
    1.34 +    public:
    1.35 +        explicit TArray(const double ts[9]) : fTArray(ts) {}
    1.36 +        double operator[](int n) const {
    1.37 +            return fTArray[n];
    1.38 +        }
    1.39 +        const double* fTArray;
    1.40 +    };
    1.41 +    TArray operator[](int n) const { return TArray(fT[n]); }
    1.42 +
    1.43 +    void set(const SkIntersections& i) {
    1.44 +        memcpy(fPt, i.fPt, sizeof(fPt));
    1.45 +        memcpy(fT, i.fT, sizeof(fT));
    1.46 +        memcpy(fIsCoincident, i.fIsCoincident, sizeof(fIsCoincident));
    1.47 +        fUsed = i.fUsed;
    1.48 +        fMax = i.fMax;
    1.49 +        fSwap = i.fSwap;
    1.50 +        SkDEBUGCODE(fDepth = i.fDepth);
    1.51 +    }
    1.52 +
    1.53 +    void allowNear(bool nearAllowed) {
    1.54 +        fAllowNear = nearAllowed;
    1.55 +    }
    1.56 +
    1.57 +    int cubic(const SkPoint a[4]) {
    1.58 +        SkDCubic cubic;
    1.59 +        cubic.set(a);
    1.60 +        fMax = 1;  // self intersect
    1.61 +        return intersect(cubic);
    1.62 +    }
    1.63 +
    1.64 +    int cubicCubic(const SkPoint a[4], const SkPoint b[4]) {
    1.65 +        SkDCubic aCubic;
    1.66 +        aCubic.set(a);
    1.67 +        SkDCubic bCubic;
    1.68 +        bCubic.set(b);
    1.69 +        fMax = 9;
    1.70 +        return intersect(aCubic, bCubic);
    1.71 +    }
    1.72 +
    1.73 +    int cubicHorizontal(const SkPoint a[4], SkScalar left, SkScalar right, SkScalar y,
    1.74 +                        bool flipped) {
    1.75 +        SkDCubic cubic;
    1.76 +        cubic.set(a);
    1.77 +        fMax = 3;
    1.78 +        return horizontal(cubic, left, right, y, flipped);
    1.79 +    }
    1.80 +
    1.81 +    int cubicVertical(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
    1.82 +        SkDCubic cubic;
    1.83 +        cubic.set(a);
    1.84 +        fMax = 3;
    1.85 +        return vertical(cubic, top, bottom, x, flipped);
    1.86 +    }
    1.87 +
    1.88 +    int cubicLine(const SkPoint a[4], const SkPoint b[2]) {
    1.89 +        SkDCubic cubic;
    1.90 +        cubic.set(a);
    1.91 +        SkDLine line;
    1.92 +        line.set(b);
    1.93 +        fMax = 3;
    1.94 +        return intersect(cubic, line);
    1.95 +    }
    1.96 +
    1.97 +    int cubicQuad(const SkPoint a[4], const SkPoint b[3]) {
    1.98 +        SkDCubic cubic;
    1.99 +        cubic.set(a);
   1.100 +        SkDQuad quad;
   1.101 +        quad.set(b);
   1.102 +        fMax = 6;
   1.103 +        return intersect(cubic, quad);
   1.104 +    }
   1.105 +
   1.106 +    bool hasT(double t) const {
   1.107 +        SkASSERT(t == 0 || t == 1);
   1.108 +        return fUsed > 0 && (t == 0 ? fT[0][0] == 0 : fT[0][fUsed - 1] == 1);
   1.109 +    }
   1.110 +
   1.111 +    int insertSwap(double one, double two, const SkDPoint& pt) {
   1.112 +        if (fSwap) {
   1.113 +            return insert(two, one, pt);
   1.114 +        } else {
   1.115 +            return insert(one, two, pt);
   1.116 +        }
   1.117 +    }
   1.118 +
   1.119 +    bool isCoincident(int index) {
   1.120 +        return (fIsCoincident[0] & 1 << index) != 0;
   1.121 +    }
   1.122 +
   1.123 +    int lineHorizontal(const SkPoint a[2], SkScalar left, SkScalar right, SkScalar y,
   1.124 +                       bool flipped) {
   1.125 +        SkDLine line;
   1.126 +        line.set(a);
   1.127 +        fMax = 2;
   1.128 +        return horizontal(line, left, right, y, flipped);
   1.129 +    }
   1.130 +
   1.131 +    int lineVertical(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
   1.132 +        SkDLine line;
   1.133 +        line.set(a);
   1.134 +        fMax = 2;
   1.135 +        return vertical(line, top, bottom, x, flipped);
   1.136 +    }
   1.137 +
   1.138 +    int lineLine(const SkPoint a[2], const SkPoint b[2]) {
   1.139 +        SkDLine aLine, bLine;
   1.140 +        aLine.set(a);
   1.141 +        bLine.set(b);
   1.142 +        fMax = 2;
   1.143 +        return intersect(aLine, bLine);
   1.144 +    }
   1.145 +
   1.146 +    const SkDPoint& pt(int index) const {
   1.147 +        return fPt[index];
   1.148 +    }
   1.149 +
   1.150 +    int quadHorizontal(const SkPoint a[3], SkScalar left, SkScalar right, SkScalar y,
   1.151 +                       bool flipped) {
   1.152 +        SkDQuad quad;
   1.153 +        quad.set(a);
   1.154 +        fMax = 2;
   1.155 +        return horizontal(quad, left, right, y, flipped);
   1.156 +    }
   1.157 +
   1.158 +    int quadVertical(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
   1.159 +        SkDQuad quad;
   1.160 +        quad.set(a);
   1.161 +        fMax = 2;
   1.162 +        return vertical(quad, top, bottom, x, flipped);
   1.163 +    }
   1.164 +
   1.165 +    int quadLine(const SkPoint a[3], const SkPoint b[2]) {
   1.166 +        SkDQuad quad;
   1.167 +        quad.set(a);
   1.168 +        SkDLine line;
   1.169 +        line.set(b);
   1.170 +        fMax = 2;
   1.171 +        return intersect(quad, line);
   1.172 +    }
   1.173 +
   1.174 +    int quadQuad(const SkPoint a[3], const SkPoint b[3]) {
   1.175 +        SkDQuad aQuad;
   1.176 +        aQuad.set(a);
   1.177 +        SkDQuad bQuad;
   1.178 +        bQuad.set(b);
   1.179 +        fMax = 4;
   1.180 +        return intersect(aQuad, bQuad);
   1.181 +    }
   1.182 +
   1.183 +    // leaves flip, swap, max alone
   1.184 +    void reset() {
   1.185 +        fAllowNear = true;
   1.186 +        fUsed = 0;
   1.187 +    }
   1.188 +
   1.189 +    void setMax(int max) {
   1.190 +        fMax = max;
   1.191 +    }
   1.192 +
   1.193 +    void swap() {
   1.194 +        fSwap ^= true;
   1.195 +    }
   1.196 +
   1.197 +    void swapPts();
   1.198 +
   1.199 +    bool swapped() const {
   1.200 +        return fSwap;
   1.201 +    }
   1.202 +
   1.203 +    int used() const {
   1.204 +        return fUsed;
   1.205 +    }
   1.206 +
   1.207 +    void downDepth() {
   1.208 +        SkASSERT(--fDepth >= 0);
   1.209 +    }
   1.210 +
   1.211 +    void upDepth() {
   1.212 +        SkASSERT(++fDepth < 16);
   1.213 +    }
   1.214 +
   1.215 +    void append(const SkIntersections& );
   1.216 +    static double Axial(const SkDQuad& , const SkDPoint& , bool vertical);
   1.217 +    void cleanUpCoincidence();
   1.218 +    int coincidentUsed() const;
   1.219 +    int cubicRay(const SkPoint pts[4], const SkDLine& line);
   1.220 +    void flip();
   1.221 +    int horizontal(const SkDLine&, double y);
   1.222 +    int horizontal(const SkDLine&, double left, double right, double y, bool flipped);
   1.223 +    int horizontal(const SkDQuad&, double left, double right, double y, bool flipped);
   1.224 +    int horizontal(const SkDQuad&, double left, double right, double y, double tRange[2]);
   1.225 +    int horizontal(const SkDCubic&, double y, double tRange[3]);
   1.226 +    int horizontal(const SkDCubic&, double left, double right, double y, bool flipped);
   1.227 +    int horizontal(const SkDCubic&, double left, double right, double y, double tRange[3]);
   1.228 +    // FIXME : does not respect swap
   1.229 +    int insert(double one, double two, const SkDPoint& pt);
   1.230 +    void insertNear(double one, double two, const SkDPoint& pt);
   1.231 +    // start if index == 0 : end if index == 1
   1.232 +    void insertCoincident(double one, double two, const SkDPoint& pt);
   1.233 +    int intersect(const SkDLine&, const SkDLine&);
   1.234 +    int intersect(const SkDQuad&, const SkDLine&);
   1.235 +    int intersect(const SkDQuad&, const SkDQuad&);
   1.236 +    int intersect(const SkDCubic&);  // return true if cubic self-intersects
   1.237 +    int intersect(const SkDCubic&, const SkDLine&);
   1.238 +    int intersect(const SkDCubic&, const SkDQuad&);
   1.239 +    int intersect(const SkDCubic&, const SkDCubic&);
   1.240 +    int intersectRay(const SkDLine&, const SkDLine&);
   1.241 +    int intersectRay(const SkDQuad&, const SkDLine&);
   1.242 +    int intersectRay(const SkDCubic&, const SkDLine&);
   1.243 +    static SkDPoint Line(const SkDLine&, const SkDLine&);
   1.244 +    int lineRay(const SkPoint pts[2], const SkDLine& line);
   1.245 +    void offset(int base, double start, double end);
   1.246 +    void quickRemoveOne(int index, int replace);
   1.247 +    int quadRay(const SkPoint pts[3], const SkDLine& line);
   1.248 +    void removeOne(int index);
   1.249 +    static bool Test(const SkDLine& , const SkDLine&);
   1.250 +    int vertical(const SkDLine&, double x);
   1.251 +    int vertical(const SkDLine&, double top, double bottom, double x, bool flipped);
   1.252 +    int vertical(const SkDQuad&, double top, double bottom, double x, bool flipped);
   1.253 +    int vertical(const SkDCubic&, double top, double bottom, double x, bool flipped);
   1.254 +    int verticalCubic(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
   1.255 +    int verticalLine(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
   1.256 +    int verticalQuad(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
   1.257 +
   1.258 +    int depth() const {
   1.259 +#ifdef SK_DEBUG
   1.260 +        return fDepth;
   1.261 +#else
   1.262 +        return 0;
   1.263 +#endif
   1.264 +    }
   1.265 +
   1.266 +private:
   1.267 +    bool cubicCheckCoincidence(const SkDCubic& c1, const SkDCubic& c2);
   1.268 +    bool cubicExactEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2);
   1.269 +    void cubicNearEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2, const SkDRect& );
   1.270 +    void cleanUpParallelLines(bool parallel);
   1.271 +    void computePoints(const SkDLine& line, int used);
   1.272 +    // used by addCoincident to remove ordinary intersections in range
   1.273 + //   void remove(double one, double two, const SkDPoint& startPt, const SkDPoint& endPt);
   1.274 +
   1.275 +    SkDPoint fPt[9];  // FIXME: since scans store points as SkPoint, this should also
   1.276 +    double fT[2][9];
   1.277 +    uint16_t fIsCoincident[2];  // bit set for each curve's coincident T
   1.278 +    unsigned char fUsed;
   1.279 +    unsigned char fMax;
   1.280 +    bool fAllowNear;
   1.281 +    bool fSwap;
   1.282 +#ifdef SK_DEBUG
   1.283 +    int fDepth;
   1.284 +#endif
   1.285 +};
   1.286 +
   1.287 +extern int (SkIntersections::*CurveRay[])(const SkPoint[], const SkDLine& );
   1.288 +extern int (SkIntersections::*CurveVertical[])(const SkPoint[], SkScalar top, SkScalar bottom,
   1.289 +            SkScalar x, bool flipped);
   1.290 +
   1.291 +#endif

mercurial