2012-09-14 14:19:30 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2012 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
2012-09-15 02:01:41 +00:00
|
|
|
|
2012-09-14 14:19:30 +00:00
|
|
|
#include "DataTypes.h"
|
|
|
|
#include "Intersections.h"
|
|
|
|
|
2013-01-17 21:02:47 +00:00
|
|
|
void Intersections::addCoincident(double s1, double e1, double s2, double e2) {
|
2013-01-29 20:28:49 +00:00
|
|
|
SkASSERT((fCoincidentUsed & 1) != 1);
|
2013-01-17 21:02:47 +00:00
|
|
|
for (int index = 0; index < fCoincidentUsed; index += 2) {
|
|
|
|
double cs1 = fCoincidentT[fSwap][index];
|
|
|
|
double ce1 = fCoincidentT[fSwap][index + 1];
|
|
|
|
bool s1in = approximately_between(cs1, s1, ce1);
|
|
|
|
bool e1in = approximately_between(cs1, e1, ce1);
|
|
|
|
double cs2 = fCoincidentT[fSwap ^ 1][index];
|
|
|
|
double ce2 = fCoincidentT[fSwap ^ 1][index + 1];
|
|
|
|
bool s2in = approximately_between(cs2, s2, ce2);
|
|
|
|
bool e2in = approximately_between(cs2, e2, ce2);
|
|
|
|
if ((s1in | e1in) & (s2in | e2in)) {
|
2013-01-29 20:28:49 +00:00
|
|
|
double lesser1 = SkTMin(cs1, ce1);
|
2013-01-17 21:02:47 +00:00
|
|
|
index += cs1 > ce1;
|
2013-02-07 13:13:41 +00:00
|
|
|
if (s1 < lesser1) {
|
|
|
|
fCoincidentT[fSwap][index] = s1;
|
|
|
|
} else if (e1 < lesser1) {
|
|
|
|
fCoincidentT[fSwap][index] = e1;
|
2013-01-17 21:02:47 +00:00
|
|
|
}
|
|
|
|
index ^= 1;
|
|
|
|
double greater1 = fCoincidentT[fSwap][index];
|
2013-02-07 13:13:41 +00:00
|
|
|
if (s1 > greater1) {
|
|
|
|
fCoincidentT[fSwap][index] = s1;
|
|
|
|
} else if (e1 > greater1) {
|
|
|
|
fCoincidentT[fSwap][index] = e1;
|
2013-01-17 21:02:47 +00:00
|
|
|
}
|
|
|
|
index &= ~1;
|
2013-01-29 20:28:49 +00:00
|
|
|
double lesser2 = SkTMin(cs2, ce2);
|
2013-01-17 21:02:47 +00:00
|
|
|
index += cs2 > ce2;
|
2013-02-07 13:13:41 +00:00
|
|
|
if (s2 < lesser2) {
|
|
|
|
fCoincidentT[fSwap ^ 1][index] = s2;
|
|
|
|
} else if (e2 < lesser2) {
|
|
|
|
fCoincidentT[fSwap ^ 1][index] = e2;
|
2013-01-17 21:02:47 +00:00
|
|
|
}
|
|
|
|
index ^= 1;
|
|
|
|
double greater2 = fCoincidentT[fSwap ^ 1][index];
|
2013-02-07 13:13:41 +00:00
|
|
|
if (s2 > greater2) {
|
|
|
|
fCoincidentT[fSwap ^ 1][index] = s2;
|
|
|
|
} else if (e2 > greater2) {
|
|
|
|
fCoincidentT[fSwap ^ 1][index] = e2;
|
2013-01-17 21:02:47 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2013-01-29 20:28:49 +00:00
|
|
|
SkASSERT(fCoincidentUsed < 9);
|
2013-01-17 21:02:47 +00:00
|
|
|
fCoincidentT[fSwap][fCoincidentUsed] = s1;
|
|
|
|
fCoincidentT[fSwap ^ 1][fCoincidentUsed] = s2;
|
|
|
|
++fCoincidentUsed;
|
|
|
|
fCoincidentT[fSwap][fCoincidentUsed] = e1;
|
|
|
|
fCoincidentT[fSwap ^ 1][fCoincidentUsed] = e2;
|
|
|
|
++fCoincidentUsed;
|
2013-02-07 13:13:41 +00:00
|
|
|
// FIXME: assert that no entries in normal range lie between s and e
|
|
|
|
remove(s1, e1);
|
|
|
|
remove(s2, e2);
|
2013-01-17 21:02:47 +00:00
|
|
|
}
|
|
|
|
|
2012-09-14 14:19:30 +00:00
|
|
|
void Intersections::cleanUp() {
|
2013-01-29 20:28:49 +00:00
|
|
|
SkASSERT(fCoincidentUsed);
|
|
|
|
SkASSERT(fUsed);
|
2012-09-14 14:19:30 +00:00
|
|
|
// find any entries in fT that could be part of the coincident range
|
2012-09-15 02:01:41 +00:00
|
|
|
|
2012-09-14 14:19:30 +00:00
|
|
|
}
|
2013-01-17 21:02:47 +00:00
|
|
|
|
2013-01-19 13:22:39 +00:00
|
|
|
// FIXME: this doesn't respect swap, but add coincident does -- seems inconsistent
|
2013-01-17 21:02:47 +00:00
|
|
|
void Intersections::insert(double one, double two) {
|
2013-01-29 20:28:49 +00:00
|
|
|
SkASSERT(fUsed <= 1 || fT[0][0] < fT[0][1]);
|
2013-01-17 21:02:47 +00:00
|
|
|
int index;
|
2013-02-07 13:13:41 +00:00
|
|
|
for (index = 0; index < fCoincidentUsed; ++index ) {
|
|
|
|
if (approximately_equal(fCoincidentT[0][index], one)
|
|
|
|
&& approximately_equal(fCoincidentT[1][index], two)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2013-01-17 21:02:47 +00:00
|
|
|
for (index = 0; index < fUsed; ++index) {
|
|
|
|
if (approximately_equal(fT[0][index], one)
|
|
|
|
&& approximately_equal(fT[1][index], two)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (fT[0][index] > one) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-01-29 20:28:49 +00:00
|
|
|
SkASSERT(fUsed < 9);
|
2013-01-17 21:02:47 +00:00
|
|
|
int remaining = fUsed - index;
|
|
|
|
if (remaining > 0) {
|
|
|
|
memmove(&fT[0][index + 1], &fT[0][index], sizeof(fT[0][0]) * remaining);
|
|
|
|
memmove(&fT[1][index + 1], &fT[1][index], sizeof(fT[1][0]) * remaining);
|
|
|
|
}
|
|
|
|
fT[0][index] = one;
|
|
|
|
fT[1][index] = two;
|
|
|
|
++fUsed;
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: all callers should be moved to regular insert. Failures are likely
|
|
|
|
// if two separate callers differ on whether ts are equal or not
|
|
|
|
void Intersections::insertOne(double t, int side) {
|
|
|
|
int used = side ? fUsed2 : fUsed;
|
2013-01-29 20:28:49 +00:00
|
|
|
SkASSERT(used <= 1 || fT[side][0] < fT[side][1]);
|
2013-01-17 21:02:47 +00:00
|
|
|
int index;
|
|
|
|
for (index = 0; index < used; ++index) {
|
|
|
|
if (approximately_equal(fT[side][index], t)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (fT[side][index] > t) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-01-29 20:28:49 +00:00
|
|
|
SkASSERT(used < 9);
|
2013-01-17 21:02:47 +00:00
|
|
|
int remaining = used - index;
|
|
|
|
if (remaining > 0) {
|
|
|
|
memmove(&fT[side][index + 1], &fT[side][index], sizeof(fT[side][0]) * remaining);
|
|
|
|
}
|
|
|
|
fT[side][index] = t;
|
|
|
|
side ? ++fUsed2 : ++fUsed;
|
|
|
|
}
|
2013-02-07 13:13:41 +00:00
|
|
|
|
|
|
|
void Intersections::remove(double one, double two) {
|
|
|
|
int index;
|
|
|
|
for (index = 0; index < fUsed; ++index) {
|
|
|
|
if (approximately_equal(fT[0][index], one)
|
|
|
|
&& approximately_equal(fT[1][index], two)) {
|
|
|
|
goto foundIt;
|
|
|
|
}
|
|
|
|
if (fT[0][index] > one) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
foundIt:
|
|
|
|
SkASSERT(fUsed > 0);
|
|
|
|
int remaining = fUsed - index;
|
|
|
|
if (remaining > 0) {
|
|
|
|
memmove(&fT[0][index], &fT[0][index - 1], sizeof(fT[0][0]) * remaining);
|
|
|
|
memmove(&fT[1][index], &fT[1][index - 1], sizeof(fT[1][0]) * remaining);
|
|
|
|
}
|
|
|
|
--fUsed;
|
|
|
|
}
|