blob: d1e0f9bdb24f5f7ca68ef95520ee72743ec52485 [file] [log] [blame]
caryclark@google.com235f56a2012-09-14 14:19:30 +00001/*
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 */
skia.committer@gmail.com055c7c22012-09-15 02:01:41 +00007
caryclark@google.com235f56a2012-09-14 14:19:30 +00008#include "DataTypes.h"
9#include "Intersections.h"
10
caryclark@google.com73ca6242013-01-17 21:02:47 +000011void Intersections::addCoincident(double s1, double e1, double s2, double e2) {
12 assert((fCoincidentUsed & 1) != 1);
13 for (int index = 0; index < fCoincidentUsed; index += 2) {
14 double cs1 = fCoincidentT[fSwap][index];
15 double ce1 = fCoincidentT[fSwap][index + 1];
16 bool s1in = approximately_between(cs1, s1, ce1);
17 bool e1in = approximately_between(cs1, e1, ce1);
18 double cs2 = fCoincidentT[fSwap ^ 1][index];
19 double ce2 = fCoincidentT[fSwap ^ 1][index + 1];
20 bool s2in = approximately_between(cs2, s2, ce2);
21 bool e2in = approximately_between(cs2, e2, ce2);
22 if ((s1in | e1in) & (s2in | e2in)) {
23 double lesser1 = std::min(cs1, ce1);
24 index += cs1 > ce1;
25 if (s1in < lesser1) {
26 fCoincidentT[fSwap][index] = s1in;
27 } else if (e1in < lesser1) {
28 fCoincidentT[fSwap][index] = e1in;
29 }
30 index ^= 1;
31 double greater1 = fCoincidentT[fSwap][index];
32 if (s1in > greater1) {
33 fCoincidentT[fSwap][index] = s1in;
34 } else if (e1in > greater1) {
35 fCoincidentT[fSwap][index] = e1in;
36 }
37 index &= ~1;
38 double lesser2 = std::min(cs2, ce2);
39 index += cs2 > ce2;
40 if (s2in < lesser2) {
41 fCoincidentT[fSwap ^ 1][index] = s2in;
42 } else if (e2in < lesser2) {
43 fCoincidentT[fSwap ^ 1][index] = e2in;
44 }
45 index ^= 1;
46 double greater2 = fCoincidentT[fSwap ^ 1][index];
47 if (s2in > greater2) {
48 fCoincidentT[fSwap ^ 1][index] = s2in;
49 } else if (e2in > greater2) {
50 fCoincidentT[fSwap ^ 1][index] = e2in;
51 }
52 return;
53 }
54 }
55 assert(fCoincidentUsed < 9);
56 fCoincidentT[fSwap][fCoincidentUsed] = s1;
57 fCoincidentT[fSwap ^ 1][fCoincidentUsed] = s2;
58 ++fCoincidentUsed;
59 fCoincidentT[fSwap][fCoincidentUsed] = e1;
60 fCoincidentT[fSwap ^ 1][fCoincidentUsed] = e2;
61 ++fCoincidentUsed;
62}
63
caryclark@google.com235f56a2012-09-14 14:19:30 +000064void Intersections::cleanUp() {
65 assert(fCoincidentUsed);
66 assert(fUsed);
67 // find any entries in fT that could be part of the coincident range
skia.committer@gmail.com055c7c22012-09-15 02:01:41 +000068
caryclark@google.com235f56a2012-09-14 14:19:30 +000069}
caryclark@google.com73ca6242013-01-17 21:02:47 +000070
71void Intersections::insert(double one, double two) {
72 assert(fUsed <= 1 || fT[0][0] < fT[0][1]);
73 int index;
74 for (index = 0; index < fUsed; ++index) {
75 if (approximately_equal(fT[0][index], one)
76 && approximately_equal(fT[1][index], two)) {
77 return;
78 }
79 if (fT[0][index] > one) {
80 break;
81 }
82 }
83 assert(fUsed < 9);
84 int remaining = fUsed - index;
85 if (remaining > 0) {
86 memmove(&fT[0][index + 1], &fT[0][index], sizeof(fT[0][0]) * remaining);
87 memmove(&fT[1][index + 1], &fT[1][index], sizeof(fT[1][0]) * remaining);
88 }
89 fT[0][index] = one;
90 fT[1][index] = two;
91 ++fUsed;
92}
93
94// FIXME: all callers should be moved to regular insert. Failures are likely
95// if two separate callers differ on whether ts are equal or not
96void Intersections::insertOne(double t, int side) {
97 int used = side ? fUsed2 : fUsed;
98 assert(used <= 1 || fT[side][0] < fT[side][1]);
99 int index;
100 for (index = 0; index < used; ++index) {
101 if (approximately_equal(fT[side][index], t)) {
102 return;
103 }
104 if (fT[side][index] > t) {
105 break;
106 }
107 }
108 assert(used < 9);
109 int remaining = used - index;
110 if (remaining > 0) {
111 memmove(&fT[side][index + 1], &fT[side][index], sizeof(fT[side][0]) * remaining);
112 }
113 fT[side][index] = t;
114 side ? ++fUsed2 : ++fUsed;
115}