shape ops work in progress
git-svn-id: http://skia.googlecode.com/svn/trunk@7453 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
81d3ce0b63
commit
aa35831d1d
@ -146,17 +146,17 @@ static int rotate_to_hull(const Cubic& cubic, char order[4], size_t idx, size_t
|
||||
int zeroes;
|
||||
zeroes = -1;
|
||||
bzero(sides, sizeof(sides));
|
||||
if (debug_rotate_to_hull) printf("%s [%d,%d] [o=%d,i=%d] src=(%g,%g) rot=", __FUNCTION__,
|
||||
if (debug_rotate_to_hull) SkDebugf("%s [%d,%d] [o=%d,i=%d] src=(%g,%g) rot=", __FUNCTION__,
|
||||
(int)idx, (int)inr, (int)outer, (int)inner,
|
||||
cubic[inner].x, cubic[inner].y);
|
||||
for (int index = 0; index < 4; ++index) {
|
||||
if (debug_rotate_to_hull) printf("(%g,%g) ", rotPath[index].x, rotPath[index].y);
|
||||
if (debug_rotate_to_hull) SkDebugf("(%g,%g) ", rotPath[index].x, rotPath[index].y);
|
||||
sides[side(rotPath[index].y - rotPath[inner].y)]++;
|
||||
if (index != outer && index != inner
|
||||
&& side(rotPath[index].y - rotPath[inner].y) == 1)
|
||||
zeroes = index;
|
||||
}
|
||||
if (debug_rotate_to_hull) printf("sides=(%d,%d,%d)\n", sides[0], sides[1], sides[2]);
|
||||
if (debug_rotate_to_hull) SkDebugf("sides=(%d,%d,%d)\n", sides[0], sides[1], sides[2]);
|
||||
if (sides[0] && sides[2]) {
|
||||
continue;
|
||||
}
|
||||
@ -165,25 +165,25 @@ static int rotate_to_hull(const Cubic& cubic, char order[4], size_t idx, size_t
|
||||
// if either of remaining two equals outer or equal, pick lower
|
||||
if (rotPath[zeroes].approximatelyEqual(rotPath[inner])
|
||||
&& zeroes < inner) {
|
||||
if (debug_rotate_to_hull) printf("%s [%d,%d] [o=%d,i=%d] zeroes < inner\n",
|
||||
if (debug_rotate_to_hull) SkDebugf("%s [%d,%d] [o=%d,i=%d] zeroes < inner\n",
|
||||
__FUNCTION__, (int)idx, (int)inr, (int)outer, (int)inner);
|
||||
continue;
|
||||
}
|
||||
if (rotPath[zeroes].approximatelyEqual(rotPath[outer])
|
||||
&& zeroes < outer) {
|
||||
if (debug_rotate_to_hull) printf("%s [%d,%d] [o=%d,i=%d] zeroes < outer\n",
|
||||
if (debug_rotate_to_hull) SkDebugf("%s [%d,%d] [o=%d,i=%d] zeroes < outer\n",
|
||||
__FUNCTION__, (int)idx, (int)inr, (int)outer, (int)inner);
|
||||
continue;
|
||||
}
|
||||
if (rotPath[zeroes].x < rotPath[inner].x
|
||||
&& rotPath[zeroes].x < rotPath[outer].x) {
|
||||
if (debug_rotate_to_hull) printf("%s [%d,%d] [o=%d,i=%d] zeroes < inner && outer\n",
|
||||
if (debug_rotate_to_hull) SkDebugf("%s [%d,%d] [o=%d,i=%d] zeroes < inner && outer\n",
|
||||
__FUNCTION__, (int)idx, (int)inr, (int)outer, (int)inner);
|
||||
continue;
|
||||
}
|
||||
if (rotPath[zeroes].x > rotPath[inner].x
|
||||
&& rotPath[zeroes].x > rotPath[outer].x) {
|
||||
if (debug_rotate_to_hull) printf("%s [%d,%d] [o=%d,i=%d] zeroes > inner && outer\n",
|
||||
if (debug_rotate_to_hull) SkDebugf("%s [%d,%d] [o=%d,i=%d] zeroes > inner && outer\n",
|
||||
__FUNCTION__, (int)idx, (int)inr, (int)outer, (int)inner);
|
||||
continue;
|
||||
}
|
||||
@ -192,7 +192,7 @@ static int rotate_to_hull(const Cubic& cubic, char order[4], size_t idx, size_t
|
||||
outsidePtSet[outer] = inner;
|
||||
} else {
|
||||
if (outsidePtSet[inner] > 0) {
|
||||
if (debug_rotate_to_hull) printf("%s [%d,%d] [o=%d,i=%d] too many rays from one point\n",
|
||||
if (debug_rotate_to_hull) SkDebugf("%s [%d,%d] [o=%d,i=%d] too many rays from one point\n",
|
||||
__FUNCTION__, (int)idx, (int)inr, (int)outer, (int)inner);
|
||||
}
|
||||
outsidePtSet[inner] = outer;
|
||||
@ -237,7 +237,7 @@ void ConvexHull_Test() {
|
||||
}
|
||||
int result = convex_hull(cubic, order);
|
||||
if (cmp != result) {
|
||||
printf("%s [%d,%d] result=%d cmp=%d\n", __FUNCTION__,
|
||||
SkDebugf("%s [%d,%d] result=%d cmp=%d\n", __FUNCTION__,
|
||||
(int)index, (int)inner, result, cmp);
|
||||
continue;
|
||||
}
|
||||
@ -247,23 +247,23 @@ void ConvexHull_Test() {
|
||||
int pt, bit;
|
||||
for (pt = 0; pt < cmp; ++pt) {
|
||||
if (pts & 1 << order[pt]) {
|
||||
printf("%s [%d,%d] duplicate index in order: %d,%d,%d",
|
||||
SkDebugf("%s [%d,%d] duplicate index in order: %d,%d,%d",
|
||||
__FUNCTION__, (int)index, (int)inner,
|
||||
order[0], order[1], order[2]);
|
||||
if (cmp == 4) {
|
||||
printf(",%d", order[3]);
|
||||
SkDebugf(",%d", order[3]);
|
||||
}
|
||||
printf("\n");
|
||||
SkDebugf("\n");
|
||||
goto next;
|
||||
}
|
||||
if (cmpPts & 1 << cmpOrder[pt]) {
|
||||
printf("%s [%d,%d] duplicate index in order: %d,%d,%d",
|
||||
SkDebugf("%s [%d,%d] duplicate index in order: %d,%d,%d",
|
||||
__FUNCTION__, (int)index, (int)inner,
|
||||
cmpOrder[0], cmpOrder[1], cmpOrder[2]);
|
||||
if (cmp == 4) {
|
||||
printf(",%d", cmpOrder[3]);
|
||||
SkDebugf(",%d", cmpOrder[3]);
|
||||
}
|
||||
printf("\n");
|
||||
SkDebugf("\n");
|
||||
goto next;
|
||||
}
|
||||
pts |= 1 << order[pt];
|
||||
@ -296,17 +296,17 @@ void ConvexHull_Test() {
|
||||
}
|
||||
}
|
||||
if (pts != cmpPts) {
|
||||
printf("%s [%d,%d] mismatch indices: order=%d,%d,%d",
|
||||
SkDebugf("%s [%d,%d] mismatch indices: order=%d,%d,%d",
|
||||
__FUNCTION__, (int)index, (int)inner,
|
||||
order[0], order[1], order[2]);
|
||||
if (cmp == 4) {
|
||||
printf(",%d", order[3]);
|
||||
SkDebugf(",%d", order[3]);
|
||||
}
|
||||
printf(" cmpOrder=%d,%d,%d", cmpOrder[0], cmpOrder[1], cmpOrder[2]);
|
||||
SkDebugf(" cmpOrder=%d,%d,%d", cmpOrder[0], cmpOrder[1], cmpOrder[2]);
|
||||
if (cmp == 4) {
|
||||
printf(",%d", cmpOrder[3]);
|
||||
SkDebugf(",%d", cmpOrder[3]);
|
||||
}
|
||||
printf("\n");
|
||||
SkDebugf("\n");
|
||||
continue;
|
||||
}
|
||||
if (cmp == 4) { // check for bow ties
|
||||
@ -315,7 +315,7 @@ void ConvexHull_Test() {
|
||||
++match;
|
||||
}
|
||||
if (cmpOrder[match ^ 2] != order[2]) {
|
||||
printf("%s [%d,%d] bowtie mismatch: order=%d,%d,%d,%d"
|
||||
SkDebugf("%s [%d,%d] bowtie mismatch: order=%d,%d,%d,%d"
|
||||
" cmpOrder=%d,%d,%d,%d\n",
|
||||
__FUNCTION__, (int)index, (int)inner,
|
||||
order[0], order[1], order[2], order[3],
|
||||
@ -365,12 +365,12 @@ void ConvexHull_X_Test() {
|
||||
if (connectTo0[idx] >= 1 && connectTo0[idx] < 4) {
|
||||
continue;
|
||||
} else {
|
||||
printf("%s connectTo0[idx]=%d", __FUNCTION__, connectTo0[idx]);
|
||||
SkDebugf("%s connectTo0[idx]=%d", __FUNCTION__, connectTo0[idx]);
|
||||
}
|
||||
if (connectTo3[idx] >= 0 && connectTo3[idx] < 3) {
|
||||
continue;
|
||||
} else {
|
||||
printf("%s connectTo3[idx]=%d", __FUNCTION__, connectTo3[idx]);
|
||||
SkDebugf("%s connectTo3[idx]=%d", __FUNCTION__, connectTo3[idx]);
|
||||
}
|
||||
goto nextTest;
|
||||
}
|
||||
@ -398,7 +398,7 @@ void ConvexHull_X_Test() {
|
||||
}
|
||||
if (connectTo0[0] != connectTo0[1]) {
|
||||
if (rOrder[0] == rOrder[1]) {
|
||||
printf("%s [%d] (1) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
SkDebugf("%s [%d] (1) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
__FUNCTION__, (int)index, connectTo0[0], connectTo0[1],
|
||||
connectTo3[0], connectTo3[1],
|
||||
rOrder[0], rOrder[1], rOrder[2], rOrder[3]);
|
||||
@ -407,7 +407,7 @@ void ConvexHull_X_Test() {
|
||||
int unused = 6 - connectTo0[0] - connectTo0[1];
|
||||
int rUnused = 6 - rOrder[0] - rOrder[1];
|
||||
if (unused != rUnused) {
|
||||
printf("%s [%d] (2) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
SkDebugf("%s [%d] (2) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
__FUNCTION__, (int)index, connectTo0[0], connectTo0[1],
|
||||
connectTo3[0], connectTo3[1],
|
||||
rOrder[0], rOrder[1], rOrder[2], rOrder[3]);
|
||||
@ -415,14 +415,14 @@ void ConvexHull_X_Test() {
|
||||
}
|
||||
} else {
|
||||
if (rOrder[0] != rOrder[1]) {
|
||||
printf("%s [%d] (3) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
SkDebugf("%s [%d] (3) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
__FUNCTION__, (int)index, connectTo0[0], connectTo0[1],
|
||||
connectTo3[0], connectTo3[1],
|
||||
rOrder[0], rOrder[1], rOrder[2], rOrder[3]);
|
||||
continue;
|
||||
}
|
||||
if (connectTo0[0] != rOrder[0]) {
|
||||
printf("%s [%d] (4) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
SkDebugf("%s [%d] (4) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
__FUNCTION__, (int)index, connectTo0[0], connectTo0[1],
|
||||
connectTo3[0], connectTo3[1],
|
||||
rOrder[0], rOrder[1], rOrder[2], rOrder[3]);
|
||||
@ -431,7 +431,7 @@ void ConvexHull_X_Test() {
|
||||
}
|
||||
if (connectTo3[0] != connectTo3[1]) {
|
||||
if (rOrder[2] == rOrder[3]) {
|
||||
printf("%s [%d] (5) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
SkDebugf("%s [%d] (5) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
__FUNCTION__, (int)index, connectTo0[0], connectTo0[1],
|
||||
connectTo3[0], connectTo3[1],
|
||||
rOrder[0], rOrder[1], rOrder[2], rOrder[3]);
|
||||
@ -440,7 +440,7 @@ void ConvexHull_X_Test() {
|
||||
int unused = 6 - connectTo3[0] - connectTo3[1];
|
||||
int rUnused = 6 - rOrder[2] - rOrder[3];
|
||||
if (unused != rUnused) {
|
||||
printf("%s [%d] (6) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
SkDebugf("%s [%d] (6) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
__FUNCTION__, (int)index, connectTo0[0], connectTo0[1],
|
||||
connectTo3[0], connectTo3[1],
|
||||
rOrder[0], rOrder[1], rOrder[2], rOrder[3]);
|
||||
@ -448,14 +448,14 @@ void ConvexHull_X_Test() {
|
||||
}
|
||||
} else {
|
||||
if (rOrder[2] != rOrder[3]) {
|
||||
printf("%s [%d] (7) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
SkDebugf("%s [%d] (7) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
__FUNCTION__, (int)index, connectTo0[0], connectTo0[1],
|
||||
connectTo3[0], connectTo3[1],
|
||||
rOrder[0], rOrder[1], rOrder[2], rOrder[3]);
|
||||
continue;
|
||||
}
|
||||
if (connectTo3[1] != rOrder[3]) {
|
||||
printf("%s [%d] (8) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
SkDebugf("%s [%d] (8) order=(%d,%d,%d,%d) r_order=(%d,%d,%d,%d)\n",
|
||||
__FUNCTION__, (int)index, connectTo0[0], connectTo0[1],
|
||||
connectTo3[0], connectTo3[1],
|
||||
rOrder[0], rOrder[1], rOrder[2], rOrder[3]);
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "CurveIntersection.h"
|
||||
#include "CurveUtilities.h"
|
||||
#include "LineParameters.h"
|
||||
#include <algorithm> // used for std::swap
|
||||
|
||||
// return false if unable to clip (e.g., unable to create implicit line)
|
||||
// caller should subdivide, or create degenerate if the values are too small
|
||||
@ -33,7 +32,7 @@ bool bezier_clip(const Cubic& cubic1, const Cubic& cubic2, double& minT, double&
|
||||
double top = distance[0];
|
||||
double bottom = distance[1];
|
||||
if (top > bottom) {
|
||||
std::swap(top, bottom);
|
||||
SkTSwap(top, bottom);
|
||||
}
|
||||
if (top * bottom >= 0) {
|
||||
const double scale = 3/4.0; // http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf (13)
|
||||
|
@ -16,10 +16,10 @@ void CubicBezierClip_Test() {
|
||||
int order1 = reduceOrder(cubic1, reduce1, kReduceOrder_NoQuadraticsAllowed);
|
||||
int order2 = reduceOrder(cubic2, reduce2, kReduceOrder_NoQuadraticsAllowed);
|
||||
if (order1 < 4) {
|
||||
printf("%s [%d] cubic1 order=%d\n", __FUNCTION__, (int) index, order1);
|
||||
SkDebugf("%s [%d] cubic1 order=%d\n", __FUNCTION__, (int) index, order1);
|
||||
}
|
||||
if (order2 < 4) {
|
||||
printf("%s [%d] cubic2 order=%d\n", __FUNCTION__, (int) index, order2);
|
||||
SkDebugf("%s [%d] cubic2 order=%d\n", __FUNCTION__, (int) index, order2);
|
||||
}
|
||||
if (order1 == 4 && order2 == 4) {
|
||||
double minT = 0;
|
||||
|
@ -287,7 +287,7 @@ static bool intersect2(const Cubic& cubic1, double t1s, double t1e, const Cubic&
|
||||
}
|
||||
#if SK_DEBUG
|
||||
++debugDepth;
|
||||
assert(debugDepth < 10);
|
||||
SkASSERT(debugDepth < 10);
|
||||
#endif
|
||||
i.swap();
|
||||
intersect2(cubic2, SkTMax(to2 - dt2, 0.), SkTMin(to2 + dt2, 1.),
|
||||
@ -340,12 +340,12 @@ static bool intersectEnd(const Cubic& cubic1, bool start, const Cubic& cubic2, c
|
||||
double tMin, tMax;
|
||||
tMin = tMax = local1.fT[0][0];
|
||||
for (int index = 1; index < local1.fUsed; ++index) {
|
||||
tMin = std::min(tMin, local1.fT[0][index]);
|
||||
tMax = std::max(tMax, local1.fT[0][index]);
|
||||
tMin = SkTMin(tMin, local1.fT[0][index]);
|
||||
tMax = SkTMax(tMax, local1.fT[0][index]);
|
||||
}
|
||||
for (int index = 1; index < local2.fUsed; ++index) {
|
||||
tMin = std::min(tMin, local2.fT[0][index]);
|
||||
tMax = std::max(tMax, local2.fT[0][index]);
|
||||
tMin = SkTMin(tMin, local2.fT[0][index]);
|
||||
tMax = SkTMax(tMax, local2.fT[0][index]);
|
||||
}
|
||||
#if SK_DEBUG
|
||||
debugDepth = 0;
|
||||
|
@ -93,11 +93,14 @@ static void oneOff(const Cubic& cubic1, const Cubic& cubic2) {
|
||||
SkDebugf("%s t1=%1.9g (%1.9g, %1.9g) (%1.9g, %1.9g) t2=%1.9g\n", __FUNCTION__,
|
||||
tt1, xy1.x, xy1.y, xy2.x, xy2.y, tt2);
|
||||
#endif
|
||||
assert(xy1.approximatelyEqual(xy2));
|
||||
SkASSERT(xy1.approximatelyEqual(xy2));
|
||||
}
|
||||
}
|
||||
|
||||
static const Cubic testSet[] = {
|
||||
{{0, 1}, {0, 2}, {1, 0}, {1, 0}},
|
||||
{{0, 1}, {0, 1}, {1, 0}, {2, 0}},
|
||||
|
||||
{{0, 0}, {0, 1}, {1, 1}, {1, 0}},
|
||||
{{1, 0}, {0, 0}, {0, 1}, {1, 1}},
|
||||
|
||||
@ -250,12 +253,12 @@ void CubicIntersection_RandTestOld() {
|
||||
SkDebugf("%s %d unexpected intersection boundsIntersect=%d oldIntersects=%d"
|
||||
" newIntersects=%d\n%s %s\n", __FUNCTION__, test, boundsIntersect,
|
||||
oldIntersects, newIntersects, __FUNCTION__, str);
|
||||
assert(0);
|
||||
SkASSERT(0);
|
||||
}
|
||||
if (oldIntersects && !newIntersects) {
|
||||
SkDebugf("%s %d missing intersection oldIntersects=%d newIntersects=%d\n%s %s\n",
|
||||
__FUNCTION__, test, oldIntersects, newIntersects, __FUNCTION__, str);
|
||||
assert(0);
|
||||
SkASSERT(0);
|
||||
}
|
||||
if (!oldIntersects && !newIntersects) {
|
||||
continue;
|
||||
@ -336,7 +339,7 @@ void CubicIntersection_RandTest() {
|
||||
SkDebugf("%s %d unexpected intersection boundsIntersect=%d "
|
||||
" newIntersects=%d\n%s %s\n", __FUNCTION__, test, boundsIntersect,
|
||||
newIntersects, __FUNCTION__, str);
|
||||
assert(0);
|
||||
SkASSERT(0);
|
||||
}
|
||||
for (int pt = 0; pt < intersections2.used(); ++pt) {
|
||||
double tt1 = intersections2.fT[0][pt];
|
||||
@ -349,7 +352,7 @@ void CubicIntersection_RandTest() {
|
||||
SkDebugf("%s t1=%1.9g (%1.9g, %1.9g) (%1.9g, %1.9g) t2=%1.9g\n", __FUNCTION__,
|
||||
tt1, xy1.x, xy1.y, xy2.x, xy2.y, tt2);
|
||||
#endif
|
||||
assert(xy1.approximatelyEqual(xy2));
|
||||
SkASSERT(xy1.approximatelyEqual(xy2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@
|
||||
*/
|
||||
#include "CubicLineSegments.h"
|
||||
#include "QuadraticLineSegments.h"
|
||||
#include <algorithm> // used for std::max
|
||||
|
||||
// http://cagd.cs.byu.edu/~557/text/cagd.pdf 2.7
|
||||
// A hodograph is the first derivative curve
|
||||
@ -31,8 +30,8 @@ void secondHodograph(const Cubic& cubic, _Line& hodo2) {
|
||||
double subDivisions(const Cubic& cubic) {
|
||||
_Line hodo2;
|
||||
secondHodograph(cubic, hodo2);
|
||||
double maxX = std::max(hodo2[1].x, hodo2[1].x);
|
||||
double maxY = std::max(hodo2[1].y, hodo2[1].y);
|
||||
double maxX = SkTMax(hodo2[1].x, hodo2[1].x);
|
||||
double maxY = SkTMax(hodo2[1].y, hodo2[1].y);
|
||||
double dist = sqrt(maxX * maxX + maxY * maxY);
|
||||
double segments = sqrt(dist / (8 * FLT_EPSILON));
|
||||
return segments;
|
||||
|
@ -34,19 +34,19 @@ void CubicCoincidence_Test() {
|
||||
quad_to_cubic(split.second(), second);
|
||||
quad_to_cubic(midThird, mid);
|
||||
if (!implicit_matches(whole, first)) {
|
||||
printf("%s-1 %d\n", __FUNCTION__, (int)index);
|
||||
SkDebugf("%s-1 %d\n", __FUNCTION__, (int)index);
|
||||
}
|
||||
if (!implicit_matches(whole, second)) {
|
||||
printf("%s-2 %d\n", __FUNCTION__, (int)index);
|
||||
SkDebugf("%s-2 %d\n", __FUNCTION__, (int)index);
|
||||
}
|
||||
if (!implicit_matches(mid, first)) {
|
||||
printf("%s-3 %d\n", __FUNCTION__, (int)index);
|
||||
SkDebugf("%s-3 %d\n", __FUNCTION__, (int)index);
|
||||
}
|
||||
if (!implicit_matches(mid, second)) {
|
||||
printf("%s-4 %d\n", __FUNCTION__, (int)index);
|
||||
SkDebugf("%s-4 %d\n", __FUNCTION__, (int)index);
|
||||
}
|
||||
if (!implicit_matches(first, second)) {
|
||||
printf("%s-5 %d\n", __FUNCTION__, (int)index);
|
||||
SkDebugf("%s-5 %d\n", __FUNCTION__, (int)index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -98,16 +98,16 @@ void CubicParameterization_Test() {
|
||||
for (size_t index = firstCubicParameterizationTest; index < cubics_count; ++index) {
|
||||
for (size_t inner = 0; inner < 4; inner += 3) {
|
||||
if (!point_on_parameterized_curve(cubics[index], cubics[index][inner])) {
|
||||
printf("%s [%zu,%zu] 1 parameterization failed\n",
|
||||
SkDebugf("%s [%zu,%zu] 1 parameterization failed\n",
|
||||
__FUNCTION__, index, inner);
|
||||
}
|
||||
if (!point_on_parameterized_curve(cubics[index], cubics[index ^ 1][inner])) {
|
||||
printf("%s [%zu,%zu] 2 parameterization failed\n",
|
||||
SkDebugf("%s [%zu,%zu] 2 parameterization failed\n",
|
||||
__FUNCTION__, index, inner);
|
||||
}
|
||||
}
|
||||
if (!implicit_matches(cubics[index], cubics[index ^ 1])) {
|
||||
printf("%s %d\n", __FUNCTION__, (int)index);
|
||||
SkDebugf("%s %d\n", __FUNCTION__, (int)index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ static int check_linear(const Cubic& cubic, Cubic& reduction,
|
||||
--endIndex;
|
||||
if (endIndex == 0) {
|
||||
printf("%s shouldn't get here if all four points are about equal\n", __FUNCTION__);
|
||||
assert(0);
|
||||
SkASSERT(0);
|
||||
}
|
||||
}
|
||||
if (!isLinear(cubic, startIndex, endIndex)) {
|
||||
|
@ -33,64 +33,64 @@ void CubicReduceOrder_Test() {
|
||||
run = RunComputedLines;
|
||||
firstTestIndex = 18;
|
||||
#endif
|
||||
int firstPointDegeneratesTest = run == RunAll ? 0 : run == RunPointDegenerates ? firstTestIndex : INT_MAX;
|
||||
int firstNotPointDegeneratesTest = run == RunAll ? 0 : run == RunNotPointDegenerates ? firstTestIndex : INT_MAX;
|
||||
int firstLinesTest = run == RunAll ? 0 : run == RunLines ? firstTestIndex : INT_MAX;
|
||||
int firstNotLinesTest = run == RunAll ? 0 : run == RunNotLines ? firstTestIndex : INT_MAX;
|
||||
int firstModEpsilonTest = run == RunAll ? 0 : run == RunModEpsilonLines ? firstTestIndex : INT_MAX;
|
||||
int firstLessEpsilonTest = run == RunAll ? 0 : run == RunLessEpsilonLines ? firstTestIndex : INT_MAX;
|
||||
int firstNegEpsilonTest = run == RunAll ? 0 : run == RunNegEpsilonLines ? firstTestIndex : INT_MAX;
|
||||
int firstQuadraticLineTest = run == RunAll ? 0 : run == RunQuadraticLines ? firstTestIndex : INT_MAX;
|
||||
int firstQuadraticModLineTest = run == RunAll ? 0 : run == RunQuadraticModLines ? firstTestIndex : INT_MAX;
|
||||
int firstComputedLinesTest = run == RunAll ? 0 : run == RunComputedLines ? firstTestIndex : INT_MAX;
|
||||
int firstPointDegeneratesTest = run == RunAll ? 0 : run == RunPointDegenerates ? firstTestIndex : SK_MaxS32;
|
||||
int firstNotPointDegeneratesTest = run == RunAll ? 0 : run == RunNotPointDegenerates ? firstTestIndex : SK_MaxS32;
|
||||
int firstLinesTest = run == RunAll ? 0 : run == RunLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstNotLinesTest = run == RunAll ? 0 : run == RunNotLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstModEpsilonTest = run == RunAll ? 0 : run == RunModEpsilonLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstLessEpsilonTest = run == RunAll ? 0 : run == RunLessEpsilonLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstNegEpsilonTest = run == RunAll ? 0 : run == RunNegEpsilonLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstQuadraticLineTest = run == RunAll ? 0 : run == RunQuadraticLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstQuadraticModLineTest = run == RunAll ? 0 : run == RunQuadraticModLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstComputedLinesTest = run == RunAll ? 0 : run == RunComputedLines ? firstTestIndex : SK_MaxS32;
|
||||
|
||||
for (index = firstPointDegeneratesTest; index < pointDegenerates_count; ++index) {
|
||||
const Cubic& cubic = pointDegenerates[index];
|
||||
order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
|
||||
if (order != 1) {
|
||||
printf("[%d] pointDegenerates order=%d\n", (int) index, order);
|
||||
SkDebugf("[%d] pointDegenerates order=%d\n", (int) index, order);
|
||||
}
|
||||
}
|
||||
for (index = firstNotPointDegeneratesTest; index < notPointDegenerates_count; ++index) {
|
||||
const Cubic& cubic = notPointDegenerates[index];
|
||||
order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
|
||||
if (order == 1) {
|
||||
printf("[%d] notPointDegenerates order=%d\n", (int) index, order);
|
||||
SkDebugf("[%d] notPointDegenerates order=%d\n", (int) index, order);
|
||||
}
|
||||
}
|
||||
for (index = firstLinesTest; index < lines_count; ++index) {
|
||||
const Cubic& cubic = lines[index];
|
||||
order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
|
||||
if (order != 2) {
|
||||
printf("[%d] lines order=%d\n", (int) index, order);
|
||||
SkDebugf("[%d] lines order=%d\n", (int) index, order);
|
||||
}
|
||||
}
|
||||
for (index = firstNotLinesTest; index < notLines_count; ++index) {
|
||||
const Cubic& cubic = notLines[index];
|
||||
order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
|
||||
if (order == 2) {
|
||||
printf("[%d] notLines order=%d\n", (int) index, order);
|
||||
SkDebugf("[%d] notLines order=%d\n", (int) index, order);
|
||||
}
|
||||
}
|
||||
for (index = firstModEpsilonTest; index < modEpsilonLines_count; ++index) {
|
||||
const Cubic& cubic = modEpsilonLines[index];
|
||||
order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
|
||||
if (order == 2) {
|
||||
printf("[%d] line mod by epsilon order=%d\n", (int) index, order);
|
||||
SkDebugf("[%d] line mod by epsilon order=%d\n", (int) index, order);
|
||||
}
|
||||
}
|
||||
for (index = firstLessEpsilonTest; index < lessEpsilonLines_count; ++index) {
|
||||
const Cubic& cubic = lessEpsilonLines[index];
|
||||
order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
|
||||
if (order != 2) {
|
||||
printf("[%d] line less by epsilon/2 order=%d\n", (int) index, order);
|
||||
SkDebugf("[%d] line less by epsilon/2 order=%d\n", (int) index, order);
|
||||
}
|
||||
}
|
||||
for (index = firstNegEpsilonTest; index < negEpsilonLines_count; ++index) {
|
||||
const Cubic& cubic = negEpsilonLines[index];
|
||||
order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
|
||||
if (order != 2) {
|
||||
printf("[%d] line neg by epsilon/2 order=%d\n", (int) index, order);
|
||||
SkDebugf("[%d] line neg by epsilon/2 order=%d\n", (int) index, order);
|
||||
}
|
||||
}
|
||||
for (index = firstQuadraticLineTest; index < quadraticLines_count; ++index) {
|
||||
@ -99,7 +99,7 @@ void CubicReduceOrder_Test() {
|
||||
quad_to_cubic(quad, cubic);
|
||||
order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
|
||||
if (order != 2) {
|
||||
printf("[%d] line quad order=%d\n", (int) index, order);
|
||||
SkDebugf("[%d] line quad order=%d\n", (int) index, order);
|
||||
}
|
||||
}
|
||||
for (index = firstQuadraticModLineTest; index < quadraticModEpsilonLines_count; ++index) {
|
||||
@ -108,7 +108,7 @@ void CubicReduceOrder_Test() {
|
||||
quad_to_cubic(quad, cubic);
|
||||
order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
|
||||
if (order != 3) {
|
||||
printf("[%d] line mod quad order=%d\n", (int) index, order);
|
||||
SkDebugf("[%d] line mod quad order=%d\n", (int) index, order);
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,14 +118,14 @@ void CubicReduceOrder_Test() {
|
||||
bool controlsInside = controls_inside(cubic);
|
||||
order = reduceOrder(cubic, reduce, kReduceOrder_QuadraticsAllowed);
|
||||
if (reduce[0].x == reduce[1].x && reduce[0].y == reduce[1].y) {
|
||||
printf("[%d] line computed ends match order=%d\n", (int) index, order);
|
||||
SkDebugf("[%d] line computed ends match order=%d\n", (int) index, order);
|
||||
}
|
||||
if (controlsInside) {
|
||||
if ( (reduce[0].x != cubic[0].x && reduce[0].x != cubic[3].x)
|
||||
|| (reduce[0].y != cubic[0].y && reduce[0].y != cubic[3].y)
|
||||
|| (reduce[1].x != cubic[0].x && reduce[1].x != cubic[3].x)
|
||||
|| (reduce[1].y != cubic[0].y && reduce[1].y != cubic[3].y)) {
|
||||
printf("[%d] line computed ends order=%d\n", (int) index, order);
|
||||
SkDebugf("[%d] line computed ends order=%d\n", (int) index, order);
|
||||
}
|
||||
} else {
|
||||
// binary search for extrema, compare against actual results
|
||||
@ -136,7 +136,7 @@ void CubicReduceOrder_Test() {
|
||||
|| (!AlmostEqualUlps(reduce[0].y, bounds.top) && !AlmostEqualUlps(reduce[0].y, bounds.bottom))
|
||||
|| (!AlmostEqualUlps(reduce[1].x, bounds.left) && !AlmostEqualUlps(reduce[1].x, bounds.right))
|
||||
|| (!AlmostEqualUlps(reduce[1].y, bounds.top) && !AlmostEqualUlps(reduce[1].y, bounds.bottom))) {
|
||||
printf("[%d] line computed tight bounds order=%d\n", (int) index, order);
|
||||
SkDebugf("[%d] line computed tight bounds order=%d\n", (int) index, order);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ static void testC(const Cubic* cubics, const char* name, int firstTest, size_t t
|
||||
const Cubic& cubic = cubics[index];
|
||||
double precision = calcPrecision(cubic);
|
||||
int order = cubic_to_quadratics(cubic, precision, quads);
|
||||
assert(order != 4);
|
||||
SkASSERT(order != 4);
|
||||
if (order < 3) {
|
||||
continue;
|
||||
}
|
||||
@ -63,7 +63,7 @@ static void testC(const Cubic(* cubics)[2], const char* name, int firstTest, siz
|
||||
const Cubic& cubic = cubics[index][idx2];
|
||||
double precision = calcPrecision(cubic);
|
||||
int order = cubic_to_quadratics(cubic, precision, quads);
|
||||
assert(order != 4);
|
||||
SkASSERT(order != 4);
|
||||
if (order < 3) {
|
||||
continue;
|
||||
}
|
||||
@ -101,17 +101,17 @@ void CubicToQuadratics_Test() {
|
||||
run = RunComputedLines;
|
||||
firstTestIndex = 18;
|
||||
#endif
|
||||
int firstPointDegeneratesTest = run == RunAll ? 0 : run == RunPointDegenerates ? firstTestIndex : INT_MAX;
|
||||
int firstNotPointDegeneratesTest = run == RunAll ? 0 : run == RunNotPointDegenerates ? firstTestIndex : INT_MAX;
|
||||
int firstLinesTest = run == RunAll ? 0 : run == RunLines ? firstTestIndex : INT_MAX;
|
||||
int firstNotLinesTest = run == RunAll ? 0 : run == RunNotLines ? firstTestIndex : INT_MAX;
|
||||
int firstModEpsilonTest = run == RunAll ? 0 : run == RunModEpsilonLines ? firstTestIndex : INT_MAX;
|
||||
int firstLessEpsilonTest = run == RunAll ? 0 : run == RunLessEpsilonLines ? firstTestIndex : INT_MAX;
|
||||
int firstNegEpsilonTest = run == RunAll ? 0 : run == RunNegEpsilonLines ? firstTestIndex : INT_MAX;
|
||||
int firstQuadraticLineTest = run == RunAll ? 0 : run == RunQuadraticLines ? firstTestIndex : INT_MAX;
|
||||
int firstQuadraticModLineTest = run == RunAll ? 0 : run == RunQuadraticModLines ? firstTestIndex : INT_MAX;
|
||||
int firstComputedLinesTest = run == RunAll ? 0 : run == RunComputedLines ? firstTestIndex : INT_MAX;
|
||||
int firstComputedCubicsTest = run == RunAll ? 0 : run == RunComputedTests ? firstTestIndex : INT_MAX;
|
||||
int firstPointDegeneratesTest = run == RunAll ? 0 : run == RunPointDegenerates ? firstTestIndex : SK_MaxS32;
|
||||
int firstNotPointDegeneratesTest = run == RunAll ? 0 : run == RunNotPointDegenerates ? firstTestIndex : SK_MaxS32;
|
||||
int firstLinesTest = run == RunAll ? 0 : run == RunLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstNotLinesTest = run == RunAll ? 0 : run == RunNotLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstModEpsilonTest = run == RunAll ? 0 : run == RunModEpsilonLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstLessEpsilonTest = run == RunAll ? 0 : run == RunLessEpsilonLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstNegEpsilonTest = run == RunAll ? 0 : run == RunNegEpsilonLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstQuadraticLineTest = run == RunAll ? 0 : run == RunQuadraticLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstQuadraticModLineTest = run == RunAll ? 0 : run == RunQuadraticModLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstComputedLinesTest = run == RunAll ? 0 : run == RunComputedLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstComputedCubicsTest = run == RunAll ? 0 : run == RunComputedTests ? firstTestIndex : SK_MaxS32;
|
||||
|
||||
test(pointDegenerates, "pointDegenerates", firstPointDegeneratesTest, pointDegenerates_count);
|
||||
test(notPointDegenerates, "notPointDegenerates", firstNotPointDegeneratesTest, notPointDegenerates_count);
|
||||
@ -191,8 +191,8 @@ void CubicsToQuadratics_RandTest() {
|
||||
double precision = calcPrecision(cubic);
|
||||
(void) cubic_to_quadratics(cubic, precision, quads);
|
||||
int count = quads.count();
|
||||
assert(count > 0);
|
||||
assert(--count < arrayMax);
|
||||
SkASSERT(count > 0);
|
||||
SkASSERT(--count < arrayMax);
|
||||
quadDist[count]++;
|
||||
int sCount = sampleCount[count];
|
||||
if (sCount < sampleMax) {
|
||||
|
@ -7,16 +7,10 @@
|
||||
#ifndef __DataTypes_h__
|
||||
#define __DataTypes_h__
|
||||
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <sys/types.h>
|
||||
#include <float.h> // for FLT_EPSILON
|
||||
#include <math.h> // for fabs, sqrt
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
extern bool AlmostEqualUlps(float A, float B);
|
||||
inline bool AlmostEqualUlps(double A, double B) { return AlmostEqualUlps((float) A, (float) B); }
|
||||
@ -146,14 +140,14 @@ inline bool approximately_zero_or_more(double x) {
|
||||
}
|
||||
|
||||
inline bool approximately_between(double a, double b, double c) {
|
||||
assert(a <= c);
|
||||
SkASSERT(a <= c);
|
||||
return a <= c ? approximately_negative(a - b) && approximately_negative(b - c)
|
||||
: approximately_negative(b - a) && approximately_negative(c - b);
|
||||
}
|
||||
|
||||
// returns true if (a <= b <= c) || (a >= b >= c)
|
||||
inline bool between(double a, double b, double c) {
|
||||
assert(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0));
|
||||
SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0));
|
||||
return (a - b) * (c - b) <= 0;
|
||||
}
|
||||
|
||||
@ -252,10 +246,10 @@ struct _Rect {
|
||||
}
|
||||
|
||||
bool intersects(_Rect& r) const {
|
||||
assert(left <= right);
|
||||
assert(top <= bottom);
|
||||
assert(r.left <= r.right);
|
||||
assert(r.top <= r.bottom);
|
||||
SkASSERT(left <= right);
|
||||
SkASSERT(top <= bottom);
|
||||
SkASSERT(r.left <= r.right);
|
||||
SkASSERT(r.top <= r.bottom);
|
||||
return r.left <= right && left <= r.right && r.top <= bottom && top <= r.bottom;
|
||||
}
|
||||
|
||||
|
@ -150,6 +150,7 @@ static bool drawStars(SkCanvas* canvas, int step, bool useOld)
|
||||
return drawPaths(canvas, path, useOld);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void tryRoncoOnce(const SkPath& path, const SkRect& target, bool show) {
|
||||
// capture everything in a desired rectangle
|
||||
SkPath tiny;
|
||||
@ -226,7 +227,9 @@ static void tryRoncoOnce(const SkPath& path, const SkRect& target, bool show) {
|
||||
}
|
||||
testSimplifyx(tiny);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void tryRonco(const SkPath& path) {
|
||||
int divMax = 64;
|
||||
int divMin = 1;
|
||||
@ -261,6 +264,7 @@ static void tryRonco(const SkPath& path) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool drawLetters(SkCanvas* canvas, int step, bool useOld)
|
||||
{
|
||||
@ -329,7 +333,7 @@ static bool (*drawDemos[])(SkCanvas* , int , bool ) = {
|
||||
|
||||
static size_t drawDemosCount = sizeof(drawDemos) / sizeof(drawDemos[0]);
|
||||
|
||||
static bool (*firstTest)(SkCanvas* , int , bool) = drawLetters;
|
||||
static bool (*firstTest)(SkCanvas* , int , bool) = drawStars;
|
||||
|
||||
|
||||
bool DrawEdgeDemo(SkCanvas* canvas, int step, bool useOld) {
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "Intersection_Tests.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkCanvas.h"
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
static void* testSimplify4x4QuadraticsMain(void* data)
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "SkStream.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
@ -581,7 +580,11 @@ void outputToStream(const State4& state, const char* pathStr, const char* pathPr
|
||||
|
||||
outFile.writeText("static void ");
|
||||
writeTestName(nameSuffix, outFile);
|
||||
outFile.writeText("() {\n SkPath path;\n");
|
||||
outFile.writeText("() {\n SkPath path");
|
||||
if (!pathPrefix) {
|
||||
outFile.writeText(", pathB");
|
||||
}
|
||||
outFile.writeText(";\n");
|
||||
if (pathPrefix) {
|
||||
outFile.writeText(pathPrefix);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ static void assert_that(int x, int y, const char* s) {
|
||||
if (x == y) {
|
||||
return;
|
||||
}
|
||||
printf("result=%d expected=%d %s\n", x, y, s);
|
||||
SkDebugf("result=%d expected=%d %s\n", x, y, s);
|
||||
}
|
||||
|
||||
static void side_test() {
|
||||
@ -41,7 +41,7 @@ static void other_two_test() {
|
||||
if (all == 0x0F) {
|
||||
continue;
|
||||
}
|
||||
printf("[%d,%d] other_two failed mask=%d [%d,%d]\n",
|
||||
SkDebugf("[%d,%d] other_two failed mask=%d [%d,%d]\n",
|
||||
x, y, mask, x ^ mask, y ^ mask);
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@
|
||||
*/
|
||||
#include "CubicIntersection_TestData.h"
|
||||
#include "Intersection_Tests.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
void cubecode_test(int test);
|
||||
|
||||
@ -16,8 +15,9 @@ void Intersection_Tests() {
|
||||
int testsRun = 0;
|
||||
|
||||
SimplifyNew_Test();
|
||||
CubicToQuadratics_Test();
|
||||
CubicIntersection_OneOffTest();
|
||||
ShapeOps4x4CubicsThreaded_Test(testsRun);
|
||||
CubicToQuadratics_Test();
|
||||
QuadraticIntersection_Test();
|
||||
QuarticRoot_Test();
|
||||
CubicIntersection_RandTest();
|
||||
|
@ -41,6 +41,7 @@ void Simplify4x4QuadralateralsThreaded_Test(int& );
|
||||
void Simplify4x4QuadraticsThreaded_Test(int& );
|
||||
void Simplify4x4RectsThreaded_Test(int& );
|
||||
void SimplifyRectangularPaths_Test();
|
||||
void ShapeOps4x4CubicsThreaded_Test(int& );
|
||||
void ShapeOps4x4RectsThreaded_Test(int& );
|
||||
void QuadLineIntersectThreaded_Test(int& );
|
||||
void QuadraticBezierClip_Test();
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "Intersections.h"
|
||||
|
||||
void Intersections::addCoincident(double s1, double e1, double s2, double e2) {
|
||||
assert((fCoincidentUsed & 1) != 1);
|
||||
SkASSERT((fCoincidentUsed & 1) != 1);
|
||||
for (int index = 0; index < fCoincidentUsed; index += 2) {
|
||||
double cs1 = fCoincidentT[fSwap][index];
|
||||
double ce1 = fCoincidentT[fSwap][index + 1];
|
||||
@ -20,7 +20,7 @@ void Intersections::addCoincident(double s1, double e1, double s2, double e2) {
|
||||
bool s2in = approximately_between(cs2, s2, ce2);
|
||||
bool e2in = approximately_between(cs2, e2, ce2);
|
||||
if ((s1in | e1in) & (s2in | e2in)) {
|
||||
double lesser1 = std::min(cs1, ce1);
|
||||
double lesser1 = SkTMin(cs1, ce1);
|
||||
index += cs1 > ce1;
|
||||
if (s1in < lesser1) {
|
||||
fCoincidentT[fSwap][index] = s1in;
|
||||
@ -35,7 +35,7 @@ void Intersections::addCoincident(double s1, double e1, double s2, double e2) {
|
||||
fCoincidentT[fSwap][index] = e1in;
|
||||
}
|
||||
index &= ~1;
|
||||
double lesser2 = std::min(cs2, ce2);
|
||||
double lesser2 = SkTMin(cs2, ce2);
|
||||
index += cs2 > ce2;
|
||||
if (s2in < lesser2) {
|
||||
fCoincidentT[fSwap ^ 1][index] = s2in;
|
||||
@ -52,7 +52,7 @@ void Intersections::addCoincident(double s1, double e1, double s2, double e2) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(fCoincidentUsed < 9);
|
||||
SkASSERT(fCoincidentUsed < 9);
|
||||
fCoincidentT[fSwap][fCoincidentUsed] = s1;
|
||||
fCoincidentT[fSwap ^ 1][fCoincidentUsed] = s2;
|
||||
++fCoincidentUsed;
|
||||
@ -62,15 +62,15 @@ void Intersections::addCoincident(double s1, double e1, double s2, double e2) {
|
||||
}
|
||||
|
||||
void Intersections::cleanUp() {
|
||||
assert(fCoincidentUsed);
|
||||
assert(fUsed);
|
||||
SkASSERT(fCoincidentUsed);
|
||||
SkASSERT(fUsed);
|
||||
// find any entries in fT that could be part of the coincident range
|
||||
|
||||
}
|
||||
|
||||
// FIXME: this doesn't respect swap, but add coincident does -- seems inconsistent
|
||||
void Intersections::insert(double one, double two) {
|
||||
assert(fUsed <= 1 || fT[0][0] < fT[0][1]);
|
||||
SkASSERT(fUsed <= 1 || fT[0][0] < fT[0][1]);
|
||||
int index;
|
||||
for (index = 0; index < fUsed; ++index) {
|
||||
if (approximately_equal(fT[0][index], one)
|
||||
@ -81,7 +81,7 @@ void Intersections::insert(double one, double two) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(fUsed < 9);
|
||||
SkASSERT(fUsed < 9);
|
||||
int remaining = fUsed - index;
|
||||
if (remaining > 0) {
|
||||
memmove(&fT[0][index + 1], &fT[0][index], sizeof(fT[0][0]) * remaining);
|
||||
@ -96,7 +96,7 @@ void Intersections::insert(double one, double two) {
|
||||
// if two separate callers differ on whether ts are equal or not
|
||||
void Intersections::insertOne(double t, int side) {
|
||||
int used = side ? fUsed2 : fUsed;
|
||||
assert(used <= 1 || fT[side][0] < fT[side][1]);
|
||||
SkASSERT(used <= 1 || fT[side][0] < fT[side][1]);
|
||||
int index;
|
||||
for (index = 0; index < used; ++index) {
|
||||
if (approximately_equal(fT[side][index], t)) {
|
||||
@ -106,7 +106,7 @@ void Intersections::insertOne(double t, int side) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(used < 9);
|
||||
SkASSERT(used < 9);
|
||||
int remaining = used - index;
|
||||
if (remaining > 0) {
|
||||
memmove(&fT[side][index + 1], &fT[side][index], sizeof(fT[side][0]) * remaining);
|
||||
|
@ -7,9 +7,6 @@
|
||||
#ifndef Intersections_DEFINE
|
||||
#define Intersections_DEFINE
|
||||
|
||||
#include <algorithm> // for std::min -- Skia doesn't have a SkMinDouble
|
||||
#include "SkTypes.h"
|
||||
|
||||
class Intersections {
|
||||
public:
|
||||
Intersections()
|
||||
@ -29,7 +26,7 @@ public:
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(fUsed < 9);
|
||||
SkASSERT(fUsed < 9);
|
||||
fT[fSwap][fUsed] = one;
|
||||
fT[fSwap ^ 1][fUsed] = two;
|
||||
++fUsed;
|
||||
@ -43,7 +40,7 @@ public:
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(fCoincidentUsed < 9);
|
||||
SkASSERT(fCoincidentUsed < 9);
|
||||
fCoincidentT[fSwap][fCoincidentUsed] = one;
|
||||
fCoincidentT[fSwap ^ 1][fCoincidentUsed] = two;
|
||||
++fCoincidentUsed;
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "CurveIntersection.h"
|
||||
#include "Intersections.h"
|
||||
#include "LineIntersection.h"
|
||||
#include <algorithm> // used for std::swap
|
||||
|
||||
/* Determine the intersection point of two lines. This assumes the lines are not parallel,
|
||||
and that that the lines are infinite.
|
||||
@ -19,7 +18,7 @@ void lineIntersect(const _Line& a, const _Line& b, _Point& p) {
|
||||
double bxLen = b[1].x - b[0].x;
|
||||
double byLen = b[1].y - b[0].y;
|
||||
double denom = byLen * axLen - ayLen * bxLen;
|
||||
assert(denom);
|
||||
SkASSERT(denom);
|
||||
double term1 = a[1].x * a[0].y - a[1].y * a[0].x;
|
||||
double term2 = b[1].x * b[0].y - b[1].y * b[0].x;
|
||||
p.x = (term1 * bxLen - axLen * term2) / denom;
|
||||
@ -68,10 +67,10 @@ int intersect(const _Line& a, const _Line& b, double aRange[2], double bRange[2]
|
||||
double bMin = bPtr[0];
|
||||
double bMax = bPtr[2];
|
||||
if (aMin > aMax) {
|
||||
std::swap(aMin, aMax);
|
||||
SkTSwap(aMin, aMax);
|
||||
}
|
||||
if (bMin > bMax) {
|
||||
std::swap(bMin, bMax);
|
||||
SkTSwap(bMin, bMax);
|
||||
}
|
||||
if (aMax < bMin || bMax < aMin) {
|
||||
return 0;
|
||||
@ -87,8 +86,8 @@ int intersect(const _Line& a, const _Line& b, double aRange[2], double bRange[2]
|
||||
}
|
||||
return 1 + ((aRange[0] != aRange[1]) || (bRange[0] != bRange[1]));
|
||||
#else
|
||||
assert(aRange);
|
||||
assert(bRange);
|
||||
SkASSERT(aRange);
|
||||
SkASSERT(bRange);
|
||||
double a0 = aPtr[0];
|
||||
double a1 = aPtr[2];
|
||||
double b0 = bPtr[0];
|
||||
@ -101,13 +100,18 @@ int intersect(const _Line& a, const _Line& b, double aRange[2], double bRange[2]
|
||||
if ((at0 < 0 && at1 < 0) || (at0 > 1 && at1 > 1)) {
|
||||
return 0;
|
||||
}
|
||||
aRange[0] = std::max(std::min(at0, 1.0), 0.0);
|
||||
aRange[1] = std::max(std::min(at1, 1.0), 0.0);
|
||||
aRange[0] = SkTMax(SkTMin(at0, 1.0), 0.0);
|
||||
aRange[1] = SkTMax(SkTMin(at1, 1.0), 0.0);
|
||||
int bIn = (a0 - a1) * (b0 - b1) < 0;
|
||||
bRange[bIn] = std::max(std::min((b0 - a0) / (b0 - b1), 1.0), 0.0);
|
||||
bRange[!bIn] = std::max(std::min((b0 - a1) / (b0 - b1), 1.0), 0.0);
|
||||
double bDenom = b0 - b1;
|
||||
if (approximately_zero(bDenom)) {
|
||||
bRange[0] = bRange[1] = 0;
|
||||
} else {
|
||||
bRange[bIn] = SkTMax(SkTMin((b0 - a0) / bDenom, 1.0), 0.0);
|
||||
bRange[!bIn] = SkTMax(SkTMin((b0 - a1) / bDenom, 1.0), 0.0);
|
||||
}
|
||||
bool second = fabs(aRange[0] - aRange[1]) > FLT_EPSILON;
|
||||
assert((fabs(bRange[0] - bRange[1]) <= FLT_EPSILON) ^ second);
|
||||
SkASSERT((fabs(bRange[0] - bRange[1]) <= FLT_EPSILON) ^ second);
|
||||
return 1 + second;
|
||||
#endif
|
||||
}
|
||||
@ -136,7 +140,7 @@ int horizontalIntersect(const _Line& line, double y, double tRange[2]) {
|
||||
double min = line[0].y;
|
||||
double max = line[1].y;
|
||||
if (min > max) {
|
||||
std::swap(min, max);
|
||||
SkTSwap(min, max);
|
||||
}
|
||||
if (min > y || max < y) {
|
||||
return 0;
|
||||
@ -192,10 +196,10 @@ int horizontalIntersect(const _Line& line, double left, double right,
|
||||
double lineL = line[0].x;
|
||||
double lineR = line[1].x;
|
||||
if (lineL > lineR) {
|
||||
std::swap(lineL, lineR);
|
||||
SkTSwap(lineL, lineR);
|
||||
}
|
||||
double overlapL = std::max(left, lineL);
|
||||
double overlapR = std::min(right, lineR);
|
||||
double overlapL = SkTMax(left, lineL);
|
||||
double overlapR = SkTMin(right, lineR);
|
||||
if (overlapL > overlapR) {
|
||||
return 0;
|
||||
}
|
||||
@ -219,16 +223,16 @@ int horizontalIntersect(const _Line& line, double left, double right,
|
||||
if ((at0 < 0 && at1 < 0) || (at0 > 1 && at1 > 1)) {
|
||||
return 0;
|
||||
}
|
||||
intersections.fT[0][0] = std::max(std::min(at0, 1.0), 0.0);
|
||||
intersections.fT[0][1] = std::max(std::min(at1, 1.0), 0.0);
|
||||
intersections.fT[0][0] = SkTMax(SkTMin(at0, 1.0), 0.0);
|
||||
intersections.fT[0][1] = SkTMax(SkTMin(at1, 1.0), 0.0);
|
||||
int bIn = (a0 - a1) * (b0 - b1) < 0;
|
||||
intersections.fT[1][bIn] = std::max(std::min((b0 - a0) / (b0 - b1),
|
||||
intersections.fT[1][bIn] = SkTMax(SkTMin((b0 - a0) / (b0 - b1),
|
||||
1.0), 0.0);
|
||||
intersections.fT[1][!bIn] = std::max(std::min((b0 - a1) / (b0 - b1),
|
||||
intersections.fT[1][!bIn] = SkTMax(SkTMin((b0 - a1) / (b0 - b1),
|
||||
1.0), 0.0);
|
||||
bool second = fabs(intersections.fT[0][0] - intersections.fT[0][1])
|
||||
> FLT_EPSILON;
|
||||
assert((fabs(intersections.fT[1][0] - intersections.fT[1][1])
|
||||
SkASSERT((fabs(intersections.fT[1][0] - intersections.fT[1][1])
|
||||
<= FLT_EPSILON) ^ second);
|
||||
return 1 + second;
|
||||
#endif
|
||||
@ -247,7 +251,7 @@ static int verticalIntersect(const _Line& line, double x, double tRange[2]) {
|
||||
double min = line[0].x;
|
||||
double max = line[1].x;
|
||||
if (min > max) {
|
||||
std::swap(min, max);
|
||||
SkTSwap(min, max);
|
||||
}
|
||||
if (min > x || max < x) {
|
||||
return 0;
|
||||
@ -281,10 +285,10 @@ int verticalIntersect(const _Line& line, double top, double bottom,
|
||||
double lineT = line[0].y;
|
||||
double lineB = line[1].y;
|
||||
if (lineT > lineB) {
|
||||
std::swap(lineT, lineB);
|
||||
SkTSwap(lineT, lineB);
|
||||
}
|
||||
double overlapT = std::max(top, lineT);
|
||||
double overlapB = std::min(bottom, lineB);
|
||||
double overlapT = SkTMax(top, lineT);
|
||||
double overlapB = SkTMin(bottom, lineB);
|
||||
if (overlapT > overlapB) {
|
||||
return 0;
|
||||
}
|
||||
@ -308,16 +312,16 @@ int verticalIntersect(const _Line& line, double top, double bottom,
|
||||
if ((at0 < 0 && at1 < 0) || (at0 > 1 && at1 > 1)) {
|
||||
return 0;
|
||||
}
|
||||
intersections.fT[0][0] = std::max(std::min(at0, 1.0), 0.0);
|
||||
intersections.fT[0][1] = std::max(std::min(at1, 1.0), 0.0);
|
||||
intersections.fT[0][0] = SkTMax(SkTMin(at0, 1.0), 0.0);
|
||||
intersections.fT[0][1] = SkTMax(SkTMin(at1, 1.0), 0.0);
|
||||
int bIn = (a0 - a1) * (b0 - b1) < 0;
|
||||
intersections.fT[1][bIn] = std::max(std::min((b0 - a0) / (b0 - b1),
|
||||
intersections.fT[1][bIn] = SkTMax(SkTMin((b0 - a0) / (b0 - b1),
|
||||
1.0), 0.0);
|
||||
intersections.fT[1][!bIn] = std::max(std::min((b0 - a1) / (b0 - b1),
|
||||
intersections.fT[1][!bIn] = SkTMax(SkTMin((b0 - a1) / (b0 - b1),
|
||||
1.0), 0.0);
|
||||
bool second = fabs(intersections.fT[0][0] - intersections.fT[0][1])
|
||||
> FLT_EPSILON;
|
||||
assert((fabs(intersections.fT[1][0] - intersections.fT[1][1])
|
||||
SkASSERT((fabs(intersections.fT[1][0] - intersections.fT[1][1])
|
||||
<= FLT_EPSILON) ^ second);
|
||||
return 1 + second;
|
||||
#endif
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
}
|
||||
|
||||
double controlPtDistance(const Cubic& pts, int index) const {
|
||||
assert(index == 1 || index == 2);
|
||||
SkASSERT(index == 1 || index == 2);
|
||||
return a * pts[index].x + b * pts[index].y + c;
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ void LineParameter_Test() {
|
||||
if (AlmostEqualUlps(distSq, normalSquared * answersSq)) {
|
||||
continue;
|
||||
}
|
||||
printf("%s [%d,%d] denormalizedDistance:%g != answer:%g"
|
||||
SkDebugf("%s [%d,%d] denormalizedDistance:%g != answer:%g"
|
||||
" distSq:%g answerSq:%g normalSquared:%g\n",
|
||||
__FUNCTION__, (int)index, (int)inner,
|
||||
denormalizedDistance[inner], answers[index][inner],
|
||||
@ -71,7 +71,7 @@ void LineParameter_Test() {
|
||||
if (AlmostEqualUlps(fabs(normalizedDistance[inner]), answers[index][inner])) {
|
||||
continue;
|
||||
}
|
||||
printf("%s [%d,%d] normalizedDistance:%1.10g != answer:%g\n",
|
||||
SkDebugf("%s [%d,%d] normalizedDistance:%1.10g != answer:%g\n",
|
||||
__FUNCTION__, (int)index, (int)inner,
|
||||
normalizedDistance[inner], answers[index][inner]);
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ static void testOneOffs() {
|
||||
double lineT = intersections.fT[1][inner];
|
||||
double lineX, lineY;
|
||||
xy_at_t(line, lineT, lineX, lineY);
|
||||
assert(AlmostEqualUlps(quadX, lineX)
|
||||
SkASSERT(AlmostEqualUlps(quadX, lineX)
|
||||
&& AlmostEqualUlps(quadY, lineY));
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "CurveIntersection.h"
|
||||
#include "CurveUtilities.h"
|
||||
#include "LineParameters.h"
|
||||
#include <algorithm> // used for std::swap
|
||||
|
||||
#define DEBUG_BEZIER_CLIP 1
|
||||
|
||||
@ -24,7 +23,7 @@ bool bezier_clip(const Quadratic& q1, const Quadratic& q2, double& minT, double&
|
||||
endLine.quadEndPoints(q1);
|
||||
if (!endLine.normalize()) {
|
||||
printf("line cannot be normalized: need more code here\n");
|
||||
assert(0);
|
||||
SkASSERT(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -34,7 +33,7 @@ bool bezier_clip(const Quadratic& q1, const Quadratic& q2, double& minT, double&
|
||||
double top = 0;
|
||||
double bottom = distance / 2; // http://students.cs.byu.edu/~tom/557/text/cic.pdf (7.6)
|
||||
if (top > bottom) {
|
||||
std::swap(top, bottom);
|
||||
SkTSwap(top, bottom);
|
||||
}
|
||||
|
||||
// compute intersecting candidate distance
|
||||
|
@ -50,10 +50,10 @@ static void standardTestCases() {
|
||||
int order1 = reduceOrder(quad1, reduce1);
|
||||
int order2 = reduceOrder(quad2, reduce2);
|
||||
if (order1 < 3) {
|
||||
printf("%s [%d] quad1 order=%d\n", __FUNCTION__, (int)index, order1);
|
||||
SkDebugf("%s [%d] quad1 order=%d\n", __FUNCTION__, (int)index, order1);
|
||||
}
|
||||
if (order2 < 3) {
|
||||
printf("%s [%d] quad2 order=%d\n", __FUNCTION__, (int)index, order2);
|
||||
SkDebugf("%s [%d] quad2 order=%d\n", __FUNCTION__, (int)index, order2);
|
||||
}
|
||||
if (order1 == 3 && order2 == 3) {
|
||||
double minT = 0;
|
||||
|
@ -110,7 +110,7 @@ static bool onlyEndPtsInCommon(const Quadratic& q1, const Quadratic& q2, Interse
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(i.fUsed < 3);
|
||||
SkASSERT(i.fUsed < 3);
|
||||
return true;
|
||||
tryNextHalfPlane:
|
||||
;
|
||||
@ -340,7 +340,7 @@ static void unsortableExpanse(const Quadratic& q1, const Quadratic& q2, Intersec
|
||||
perp[1].y += dxdy.x;
|
||||
Intersections hitData;
|
||||
int hits = intersectRay(*qs[qIdx ^ 1], perp, hitData);
|
||||
assert(hits <= 1);
|
||||
SkASSERT(hits <= 1);
|
||||
if (hits) {
|
||||
if (flip < 0) {
|
||||
_Point dxdy2;
|
||||
@ -397,7 +397,7 @@ bool intersect2(const Quadratic& q1, const Quadratic& q2, Intersections& i) {
|
||||
if ((t = axialIntersect(q2, q1[2], useVertical)) >= 0) {
|
||||
i.addCoincident(1, t);
|
||||
}
|
||||
assert(i.fCoincidentUsed <= 2);
|
||||
SkASSERT(i.fCoincidentUsed <= 2);
|
||||
return i.fCoincidentUsed > 0;
|
||||
}
|
||||
double roots1[4], roots2[4];
|
||||
|
@ -76,7 +76,7 @@ bool intersect(double minT1, double maxT1, double minT2, double maxT2) {
|
||||
smallT = minT1;
|
||||
} else {
|
||||
xy_at_t(quad1, maxT1, q1pt.x, q1pt.y); // FIXME: debug code
|
||||
assert(AlmostEqualUlps(q2pt.x, q1pt.x) && AlmostEqualUlps(q2pt.y, q1pt.y));
|
||||
SkASSERT(AlmostEqualUlps(q2pt.x, q1pt.x) && AlmostEqualUlps(q2pt.y, q1pt.y));
|
||||
smallT = maxT1;
|
||||
}
|
||||
} else {
|
||||
@ -87,7 +87,7 @@ bool intersect(double minT1, double maxT1, double minT2, double maxT2) {
|
||||
largeT = minT2;
|
||||
} else {
|
||||
xy_at_t(quad2, maxT2, q2pt.x, q2pt.y); // FIXME: debug code
|
||||
assert(AlmostEqualUlps(q2pt.x, q1pt.x) && AlmostEqualUlps(q2pt.y, q1pt.y));
|
||||
SkASSERT(AlmostEqualUlps(q2pt.x, q1pt.x) && AlmostEqualUlps(q2pt.y, q1pt.y));
|
||||
largeT = maxT2;
|
||||
}
|
||||
}
|
||||
@ -127,9 +127,9 @@ bool intersectAsLine(double minT1, double maxT1, double minT2, double maxT2,
|
||||
{
|
||||
_Line line1, line2;
|
||||
if (intersections.swapped()) {
|
||||
std::swap(treat1AsLine, treat2AsLine);
|
||||
std::swap(minT1, minT2);
|
||||
std::swap(maxT1, maxT2);
|
||||
SkTSwap(treat1AsLine, treat2AsLine);
|
||||
SkTSwap(minT1, minT2);
|
||||
SkTSwap(maxT1, maxT2);
|
||||
}
|
||||
if (coinMinT1 >= 0) {
|
||||
bool earlyExit;
|
||||
@ -388,7 +388,7 @@ bool intersect(const Quadratic& q1, const Quadratic& q2, Intersections& i) {
|
||||
if ((t = axialIntersect(q2, q1[2], useVertical)) >= 0) {
|
||||
i.addCoincident(1, t);
|
||||
}
|
||||
assert(i.fCoincidentUsed <= 2);
|
||||
SkASSERT(i.fCoincidentUsed <= 2);
|
||||
return i.fCoincidentUsed > 0;
|
||||
}
|
||||
QuadraticIntersections q(q1, q2, i);
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "Intersections.h"
|
||||
#include "QuadraticIntersection_TestData.h"
|
||||
#include "TestUtilities.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
const int firstQuadIntersectionTest = 9;
|
||||
|
||||
|
@ -34,12 +34,12 @@ void QuadraticCoincidence_Test() {
|
||||
for (size_t two = 0; two < quadsCount; ++two) {
|
||||
for (size_t inner = 0; inner < 3; inner += 2) {
|
||||
if (!point_on_parameterized_curve(*quads[one], (*quads[two])[inner])) {
|
||||
printf("%s %zu [%zu,%zu] %zu parameterization failed\n",
|
||||
SkDebugf("%s %zu [%zu,%zu] %zu parameterization failed\n",
|
||||
__FUNCTION__, index, one, two, inner);
|
||||
}
|
||||
}
|
||||
if (!implicit_matches(*quads[one], *quads[two])) {
|
||||
printf("%s %zu [%zu,%zu] coincidence failed\n", __FUNCTION__,
|
||||
SkDebugf("%s %zu [%zu,%zu] coincidence failed\n", __FUNCTION__,
|
||||
index, one, two);
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ static int check_linear(const Quadratic& quad, Quadratic& reduction,
|
||||
--endIndex;
|
||||
if (endIndex == 0) {
|
||||
printf("%s shouldn't get here if all four points are about equal", __FUNCTION__);
|
||||
assert(0);
|
||||
SkASSERT(0);
|
||||
}
|
||||
}
|
||||
if (!isLinear(quad, startIndex, endIndex)) {
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "Intersection_Tests.h"
|
||||
#include "QuadraticIntersection_TestData.h"
|
||||
#include "TestUtilities.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
static const Quadratic testSet[] = {
|
||||
{{1, 1}, {2, 2}, {1, 1.000003}},
|
||||
@ -43,8 +42,8 @@ static void standardTestCases() {
|
||||
run = RunQuadraticLines;
|
||||
firstTestIndex = 1;
|
||||
#endif
|
||||
int firstQuadraticLineTest = run == RunAll ? 0 : run == RunQuadraticLines ? firstTestIndex : INT_MAX;
|
||||
int firstQuadraticModLineTest = run == RunAll ? 0 : run == RunQuadraticModLines ? firstTestIndex : INT_MAX;
|
||||
int firstQuadraticLineTest = run == RunAll ? 0 : run == RunQuadraticLines ? firstTestIndex : SK_MaxS32;
|
||||
int firstQuadraticModLineTest = run == RunAll ? 0 : run == RunQuadraticModLines ? firstTestIndex : SK_MaxS32;
|
||||
|
||||
for (index = firstQuadraticLineTest; index < quadraticLines_count; ++index) {
|
||||
const Quadratic& quad = quadraticLines[index];
|
||||
|
@ -5,7 +5,6 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#include "QuadraticUtilities.h"
|
||||
#include "SkTypes.h"
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
|
@ -58,7 +58,7 @@ int reducedQuarticRoots(const double t4, const double t3, const double t2, const
|
||||
return num;
|
||||
}
|
||||
if (oneHint) {
|
||||
assert(approximately_zero(t4 + t3 + t2 + t1 + t0)); // 1 is one root
|
||||
SkASSERT(approximately_zero(t4 + t3 + t2 + t1 + t0)); // 1 is one root
|
||||
int num = cubicRootsReal(t4, t4 + t3, -(t1 + t0), -t0, roots); // note that -C==A+B+D+E
|
||||
for (int i = 0; i < num; ++i) {
|
||||
if (approximately_equal(roots[i], 1)) {
|
||||
|
@ -1,5 +1,3 @@
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include "CubicUtilities.h"
|
||||
#include "Intersection_Tests.h"
|
||||
#include "QuadraticUtilities.h"
|
||||
@ -41,15 +39,15 @@ static void quadraticTest(bool limit) {
|
||||
} else {
|
||||
expected = 1 + (B != C);
|
||||
}
|
||||
assert(rootCount == expected);
|
||||
SkASSERT(rootCount == expected);
|
||||
if (!rootCount) {
|
||||
continue;
|
||||
}
|
||||
assert(approximately_equal(roots[0], -B)
|
||||
SkASSERT(approximately_equal(roots[0], -B)
|
||||
|| approximately_equal(roots[0], -C));
|
||||
if (expected > 1) {
|
||||
assert(!approximately_equal(roots[0], roots[1]));
|
||||
assert(approximately_equal(roots[1], -B)
|
||||
SkASSERT(!approximately_equal(roots[0], roots[1]));
|
||||
SkASSERT(approximately_equal(roots[1], -B)
|
||||
|| approximately_equal(roots[1], -C));
|
||||
}
|
||||
}
|
||||
@ -81,26 +79,26 @@ static void testOneCubic(bool limit, size_t aIndex, size_t bIndex, size_t cIndex
|
||||
} else {
|
||||
expected = 1 + (B != C) + (B != D && C != D);
|
||||
}
|
||||
assert(rootCount == expected);
|
||||
SkASSERT(rootCount == expected);
|
||||
if (!rootCount) {
|
||||
return;
|
||||
}
|
||||
assert(approximately_equal(roots[0], -B)
|
||||
SkASSERT(approximately_equal(roots[0], -B)
|
||||
|| approximately_equal(roots[0], -C)
|
||||
|| approximately_equal(roots[0], -D));
|
||||
if (expected <= 1) {
|
||||
return;
|
||||
}
|
||||
assert(!approximately_equal(roots[0], roots[1]));
|
||||
assert(approximately_equal(roots[1], -B)
|
||||
SkASSERT(!approximately_equal(roots[0], roots[1]));
|
||||
SkASSERT(approximately_equal(roots[1], -B)
|
||||
|| approximately_equal(roots[1], -C)
|
||||
|| approximately_equal(roots[1], -D));
|
||||
if (expected <= 2) {
|
||||
return;
|
||||
}
|
||||
assert(!approximately_equal(roots[0], roots[2])
|
||||
SkASSERT(!approximately_equal(roots[0], roots[2])
|
||||
&& !approximately_equal(roots[1], roots[2]));
|
||||
assert(approximately_equal(roots[2], -B)
|
||||
SkASSERT(approximately_equal(roots[2], -B)
|
||||
|| approximately_equal(roots[2], -C)
|
||||
|| approximately_equal(roots[2], -D));
|
||||
}
|
||||
@ -136,35 +134,35 @@ static void testOneQuartic(size_t aIndex, size_t bIndex, size_t cIndex, size_t d
|
||||
rootCount = quarticRootsReal(A, b, c, d, e, roots);
|
||||
}
|
||||
const int expected = 1 + (B != C) + (B != D && C != D) + (B != E && C != E && D != E);
|
||||
assert(rootCount == expected);
|
||||
assert(AlmostEqualUlps(roots[0], -B)
|
||||
SkASSERT(rootCount == expected);
|
||||
SkASSERT(AlmostEqualUlps(roots[0], -B)
|
||||
|| AlmostEqualUlps(roots[0], -C)
|
||||
|| AlmostEqualUlps(roots[0], -D)
|
||||
|| AlmostEqualUlps(roots[0], -E));
|
||||
if (expected <= 1) {
|
||||
return;
|
||||
}
|
||||
assert(!AlmostEqualUlps(roots[0], roots[1]));
|
||||
assert(AlmostEqualUlps(roots[1], -B)
|
||||
SkASSERT(!AlmostEqualUlps(roots[0], roots[1]));
|
||||
SkASSERT(AlmostEqualUlps(roots[1], -B)
|
||||
|| AlmostEqualUlps(roots[1], -C)
|
||||
|| AlmostEqualUlps(roots[1], -D)
|
||||
|| AlmostEqualUlps(roots[1], -E));
|
||||
if (expected <= 2) {
|
||||
return;
|
||||
}
|
||||
assert(!AlmostEqualUlps(roots[0], roots[2])
|
||||
SkASSERT(!AlmostEqualUlps(roots[0], roots[2])
|
||||
&& !AlmostEqualUlps(roots[1], roots[2]));
|
||||
assert(AlmostEqualUlps(roots[2], -B)
|
||||
SkASSERT(AlmostEqualUlps(roots[2], -B)
|
||||
|| AlmostEqualUlps(roots[2], -C)
|
||||
|| AlmostEqualUlps(roots[2], -D)
|
||||
|| AlmostEqualUlps(roots[2], -E));
|
||||
if (expected <= 3) {
|
||||
return;
|
||||
}
|
||||
assert(!AlmostEqualUlps(roots[0], roots[3])
|
||||
SkASSERT(!AlmostEqualUlps(roots[0], roots[3])
|
||||
&& !AlmostEqualUlps(roots[1], roots[3])
|
||||
&& !AlmostEqualUlps(roots[2], roots[3]));
|
||||
assert(AlmostEqualUlps(roots[3], -B)
|
||||
SkASSERT(AlmostEqualUlps(roots[3], -B)
|
||||
|| AlmostEqualUlps(roots[3], -C)
|
||||
|| AlmostEqualUlps(roots[3], -D)
|
||||
|| AlmostEqualUlps(roots[3], -E));
|
||||
|
94
experimental/Intersection/ShapeOpCubic4x4_Test.cpp
Normal file
94
experimental/Intersection/ShapeOpCubic4x4_Test.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#include "EdgeWalker_Test.h"
|
||||
#include "Intersection_Tests.h"
|
||||
#include "ShapeOps.h"
|
||||
|
||||
// four rects, of four sizes
|
||||
// for 3 smaller sizes, tall, wide
|
||||
// top upper mid lower bottom aligned (3 bits, 5 values)
|
||||
// same with x (3 bits, 5 values)
|
||||
// not included, square, tall, wide (2 bits)
|
||||
// cw or ccw (1 bit)
|
||||
|
||||
static void* testShapeOps4x4CubicsMain(void* data)
|
||||
{
|
||||
SkASSERT(data);
|
||||
State4& state = *(State4*) data;
|
||||
char pathStr[1024]; // gdb: set print elements 400
|
||||
bzero(pathStr, sizeof(pathStr));
|
||||
do {
|
||||
for (int a = 0 ; a < 6; ++a) {
|
||||
for (int b = a + 1 ; b < 7; ++b) {
|
||||
for (int c = 0 ; c < 6; ++c) {
|
||||
for (int d = c + 1 ; d < 7; ++d) {
|
||||
for (int e = SkPath::kWinding_FillType ; e <= SkPath::kEvenOdd_FillType; ++e) {
|
||||
for (int f = SkPath::kWinding_FillType ; f <= SkPath::kEvenOdd_FillType; ++f) {
|
||||
SkPath pathA, pathB;
|
||||
char* str = pathStr;
|
||||
pathA.setFillType((SkPath::FillType) e);
|
||||
str += sprintf(str, " path.setFillType(SkPath::k%s_FillType);\n",
|
||||
e == SkPath::kWinding_FillType ? "Winding" : e == SkPath::kEvenOdd_FillType
|
||||
? "EvenOdd" : "?UNDEFINED");
|
||||
pathA.moveTo(state.a, state.b);
|
||||
str += sprintf(str, " path.moveTo(%d,%d);\n", state.a, state.b);
|
||||
pathA.cubicTo(state.c, state.d, b, a, d, c);
|
||||
str += sprintf(str, " path.cubicTo(%d,%d, %d,%d, %d,%d);\n", state.c, state.d,
|
||||
b, a, d, c);
|
||||
pathA.close();
|
||||
str += sprintf(str, " path.close();\n");
|
||||
pathB.setFillType((SkPath::FillType) f);
|
||||
str += sprintf(str, " pathB.setFillType(SkPath::k%s_FillType);\n",
|
||||
f == SkPath::kWinding_FillType ? "Winding" : f == SkPath::kEvenOdd_FillType
|
||||
? "EvenOdd" : "?UNDEFINED");
|
||||
pathB.moveTo(a, b);
|
||||
str += sprintf(str, " pathB.moveTo(%d,%d);\n", a, b);
|
||||
pathB.cubicTo(c, d, state.b, state.a, state.d, state.c);
|
||||
str += sprintf(str, " pathB.cubicTo(%d,%d, %d,%d, %d,%d);\n", c, d,
|
||||
state.b, state.a, state.d, state.c);
|
||||
pathB.close();
|
||||
str += sprintf(str, " pathB.close();\n");
|
||||
for (int op = 0 ; op < kShapeOp_Count; ++op) {
|
||||
outputProgress(state, pathStr, (ShapeOp) op);
|
||||
testShapeOp(pathA, pathB, (ShapeOp) op);
|
||||
state.testsRun++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (runNextTestSet(state));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ShapeOps4x4CubicsThreaded_Test(int& testsRun)
|
||||
{
|
||||
SkDebugf("%s\n", __FUNCTION__);
|
||||
#ifdef SK_DEBUG
|
||||
gDebugMaxWindSum = 4;
|
||||
gDebugMaxWindValue = 4;
|
||||
#endif
|
||||
const char testLineStr[] = "cubicOp";
|
||||
initializeTests(testLineStr, sizeof(testLineStr));
|
||||
int testsStart = testsRun;
|
||||
for (int a = 0; a < 6; ++a) { // outermost
|
||||
for (int b = a + 1; b < 7; ++b) {
|
||||
for (int c = 0 ; c < 6; ++c) {
|
||||
for (int d = c + 1; d < 7; ++d) {
|
||||
testsRun += dispatchTest4(testShapeOps4x4CubicsMain, a, b, c, d);
|
||||
}
|
||||
if (!gRunTestsInOneThread) SkDebugf(".");
|
||||
}
|
||||
if (!gRunTestsInOneThread) SkDebugf("%d", b);
|
||||
}
|
||||
if (!gRunTestsInOneThread) SkDebugf("\n%d", a);
|
||||
}
|
||||
testsRun += waitForCompletion();
|
||||
SkDebugf("%s tests=%d total=%d\n", __FUNCTION__, testsRun - testsStart, testsRun);
|
||||
}
|
@ -26,7 +26,6 @@ static void* testShapeOps4x4RectsMain(void* data)
|
||||
for (int b = a + 1 ; b < 7; ++b) {
|
||||
for (int c = 0 ; c < 6; ++c) {
|
||||
for (int d = c + 1 ; d < 7; ++d) {
|
||||
for (int op = 0 ; op < kShapeOp_Count; ++op) {
|
||||
for (int e = SkPath::kWinding_FillType ; e <= SkPath::kEvenOdd_FillType; ++e) {
|
||||
for (int f = SkPath::kWinding_FillType ; f <= SkPath::kEvenOdd_FillType; ++f) {
|
||||
SkPath pathA, pathB;
|
||||
@ -53,19 +52,11 @@ static void* testShapeOps4x4RectsMain(void* data)
|
||||
str += sprintf(str, " pathB.addRect(%d, %d, %d, %d,"
|
||||
" SkPath::kCW_Direction);\n", c, c, d, d);
|
||||
pathB.close();
|
||||
outputProgress(state, pathStr, kDifference_Op);
|
||||
testShapeOp(pathA, pathB, kDifference_Op);
|
||||
state.testsRun++;
|
||||
outputProgress(state, pathStr, kIntersect_Op);
|
||||
testShapeOp(pathA, pathB, kIntersect_Op);
|
||||
state.testsRun++;
|
||||
outputProgress(state, pathStr, kUnion_Op);
|
||||
testShapeOp(pathA, pathB, kUnion_Op);
|
||||
state.testsRun++;
|
||||
outputProgress(state, pathStr, kXor_Op);
|
||||
testShapeOp(pathA, pathB, kXor_Op);
|
||||
state.testsRun++;
|
||||
}
|
||||
for (int op = 0 ; op < kShapeOp_Count; ++op) {
|
||||
outputProgress(state, pathStr, (ShapeOp) op);
|
||||
testShapeOp(pathA, pathB, (ShapeOp) op);
|
||||
state.testsRun++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -392,34 +392,19 @@ static void (* const SegmentSubDivide[])(const SkPoint [], double , double ,
|
||||
CubicSubDivide
|
||||
};
|
||||
|
||||
static void LineSubDivideHD(const SkPoint a[2], double startT, double endT,
|
||||
_Line sub) {
|
||||
static void LineSubDivideHD(const SkPoint a[2], double startT, double endT, _Line& dst) {
|
||||
MAKE_CONST_LINE(aLine, a);
|
||||
_Line dst;
|
||||
sub_divide(aLine, startT, endT, dst);
|
||||
sub[0] = dst[0];
|
||||
sub[1] = dst[1];
|
||||
}
|
||||
|
||||
static void QuadSubDivideHD(const SkPoint a[3], double startT, double endT,
|
||||
Quadratic sub) {
|
||||
static void QuadSubDivideHD(const SkPoint a[3], double startT, double endT, Quadratic& dst) {
|
||||
MAKE_CONST_QUAD(aQuad, a);
|
||||
Quadratic dst;
|
||||
sub_divide(aQuad, startT, endT, dst);
|
||||
sub[0] = dst[0];
|
||||
sub[1] = dst[1];
|
||||
sub[2] = dst[2];
|
||||
}
|
||||
|
||||
static void CubicSubDivideHD(const SkPoint a[4], double startT, double endT,
|
||||
Cubic sub) {
|
||||
static void CubicSubDivideHD(const SkPoint a[4], double startT, double endT, Cubic& dst) {
|
||||
MAKE_CONST_CUBIC(aCubic, a);
|
||||
Cubic dst;
|
||||
sub_divide(aCubic, startT, endT, dst);
|
||||
sub[0] = dst[0];
|
||||
sub[1] = dst[1];
|
||||
sub[2] = dst[2];
|
||||
sub[3] = dst[3];
|
||||
}
|
||||
|
||||
#if DEBUG_UNUSED
|
||||
@ -780,12 +765,27 @@ public:
|
||||
case SkPath::kQuad_Verb:
|
||||
QuadSubDivideHD(fPts, startT, endT, fQ);
|
||||
fTangent1.quadEndPoints(fQ, 0, 1);
|
||||
#if 1 // FIXME: try enabling this and see if a) it's called and b) does it break anything
|
||||
if (dx() == 0 && dy() == 0) {
|
||||
SkDebugf("*** %s quad is line\n");
|
||||
fTangent1.quadEndPoints(fQ);
|
||||
}
|
||||
#endif
|
||||
fSide = -fTangent1.pointDistance(fQ[2]); // not normalized -- compare sign only
|
||||
break;
|
||||
case SkPath::kCubic_Verb:
|
||||
Cubic c;
|
||||
CubicSubDivideHD(fPts, startT, endT, c);
|
||||
fTangent1.cubicEndPoints(c, 0, 1);
|
||||
if (dx() == 0 && dy() == 0) {
|
||||
fTangent1.cubicEndPoints(c, 0, 2);
|
||||
#if 1 // FIXME: try enabling this and see if a) it's called and b) does it break anything
|
||||
if (dx() == 0 && dy() == 0) {
|
||||
SkDebugf("*** %s cubic is line\n");
|
||||
fTangent1.cubicEndPoints(c, 0, 3);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
fSide = -fTangent1.pointDistance(c[2]); // not normalized -- compare sign only
|
||||
break;
|
||||
default:
|
||||
@ -1792,7 +1792,7 @@ public:
|
||||
}
|
||||
|
||||
// FIXME: this doesn't prevent the same span from being added twice
|
||||
// fix in caller, assert here?
|
||||
// fix in caller, SkASSERT here?
|
||||
void addTPair(double t, Segment& other, double otherT, bool borrowWind) {
|
||||
int tCount = fTs.count();
|
||||
for (int tIndex = 0; tIndex < tCount; ++tIndex) {
|
||||
@ -3346,7 +3346,9 @@ the same winding is shared by both.
|
||||
const Span& endSpan = fTs[end];
|
||||
Segment* other = endSpan.fOther;
|
||||
index = endSpan.fOtherIndex;
|
||||
SkASSERT(index >= 0);
|
||||
int otherEnd = other->nextExactSpan(index, step);
|
||||
SkASSERT(otherEnd >= 0);
|
||||
min = SkMin32(index, otherEnd);
|
||||
return other;
|
||||
}
|
||||
@ -3765,7 +3767,7 @@ the same winding is shared by both.
|
||||
#endif
|
||||
|
||||
#if DEBUG_CONCIDENT
|
||||
// assert if pair has not already been added
|
||||
// SkASSERT if pair has not already been added
|
||||
void debugAddTPair(double t, const Segment& other, double otherT) const {
|
||||
for (int i = 0; i < fTs.count(); ++i) {
|
||||
if (fTs[i].fT == t && fTs[i].fOther == &other && fTs[i].fOtherT == otherT) {
|
||||
@ -6051,7 +6053,7 @@ static void assemble(const PathWrapper& path, PathWrapper& simple) {
|
||||
eLink.setCount(count);
|
||||
int rIndex, iIndex;
|
||||
for (rIndex = 0; rIndex < count; ++rIndex) {
|
||||
sLink[rIndex] = eLink[rIndex] = INT_MAX;
|
||||
sLink[rIndex] = eLink[rIndex] = SK_MaxS32;
|
||||
}
|
||||
SkTDArray<double> distances;
|
||||
const int ends = count * 2; // all starts and ends
|
||||
@ -6088,14 +6090,14 @@ static void assemble(const PathWrapper& path, PathWrapper& simple) {
|
||||
int ndxOne = thingOne >> 1;
|
||||
bool endOne = thingOne & 1;
|
||||
int* linkOne = endOne ? eLink.begin() : sLink.begin();
|
||||
if (linkOne[ndxOne] != INT_MAX) {
|
||||
if (linkOne[ndxOne] != SK_MaxS32) {
|
||||
continue;
|
||||
}
|
||||
int thingTwo = row < col ? col : ends - row + col - 1;
|
||||
int ndxTwo = thingTwo >> 1;
|
||||
bool endTwo = thingTwo & 1;
|
||||
int* linkTwo = endTwo ? eLink.begin() : sLink.begin();
|
||||
if (linkTwo[ndxTwo] != INT_MAX) {
|
||||
if (linkTwo[ndxTwo] != SK_MaxS32) {
|
||||
continue;
|
||||
}
|
||||
SkASSERT(&linkOne[ndxOne] != &linkTwo[ndxTwo]);
|
||||
@ -6120,17 +6122,17 @@ static void assemble(const PathWrapper& path, PathWrapper& simple) {
|
||||
bool forward = true;
|
||||
bool first = true;
|
||||
int sIndex = sLink[rIndex];
|
||||
SkASSERT(sIndex != INT_MAX);
|
||||
sLink[rIndex] = INT_MAX;
|
||||
SkASSERT(sIndex != SK_MaxS32);
|
||||
sLink[rIndex] = SK_MaxS32;
|
||||
int eIndex;
|
||||
if (sIndex < 0) {
|
||||
eIndex = sLink[~sIndex];
|
||||
sLink[~sIndex] = INT_MAX;
|
||||
sLink[~sIndex] = SK_MaxS32;
|
||||
} else {
|
||||
eIndex = eLink[sIndex];
|
||||
eLink[sIndex] = INT_MAX;
|
||||
eLink[sIndex] = SK_MaxS32;
|
||||
}
|
||||
SkASSERT(eIndex != INT_MAX);
|
||||
SkASSERT(eIndex != SK_MaxS32);
|
||||
#if DEBUG_ASSEMBLE
|
||||
SkDebugf("%s sIndex=%c%d eIndex=%c%d\n", __FUNCTION__, sIndex < 0 ? 's' : 'e',
|
||||
sIndex < 0 ? ~sIndex : sIndex, eIndex < 0 ? 's' : 'e',
|
||||
@ -6160,25 +6162,25 @@ static void assemble(const PathWrapper& path, PathWrapper& simple) {
|
||||
}
|
||||
if (forward) {
|
||||
eIndex = eLink[rIndex];
|
||||
SkASSERT(eIndex != INT_MAX);
|
||||
eLink[rIndex] = INT_MAX;
|
||||
SkASSERT(eIndex != SK_MaxS32);
|
||||
eLink[rIndex] = SK_MaxS32;
|
||||
if (eIndex >= 0) {
|
||||
SkASSERT(sLink[eIndex] == rIndex);
|
||||
sLink[eIndex] = INT_MAX;
|
||||
sLink[eIndex] = SK_MaxS32;
|
||||
} else {
|
||||
SkASSERT(eLink[~eIndex] == ~rIndex);
|
||||
eLink[~eIndex] = INT_MAX;
|
||||
eLink[~eIndex] = SK_MaxS32;
|
||||
}
|
||||
} else {
|
||||
eIndex = sLink[rIndex];
|
||||
SkASSERT(eIndex != INT_MAX);
|
||||
sLink[rIndex] = INT_MAX;
|
||||
SkASSERT(eIndex != SK_MaxS32);
|
||||
sLink[rIndex] = SK_MaxS32;
|
||||
if (eIndex >= 0) {
|
||||
SkASSERT(eLink[eIndex] == rIndex);
|
||||
eLink[eIndex] = INT_MAX;
|
||||
eLink[eIndex] = SK_MaxS32;
|
||||
} else {
|
||||
SkASSERT(sLink[~eIndex] == ~rIndex);
|
||||
sLink[~eIndex] = INT_MAX;
|
||||
sLink[~eIndex] = SK_MaxS32;
|
||||
}
|
||||
}
|
||||
rIndex = eIndex;
|
||||
@ -6188,15 +6190,15 @@ static void assemble(const PathWrapper& path, PathWrapper& simple) {
|
||||
}
|
||||
} while (true);
|
||||
for (rIndex = 0; rIndex < count; ++rIndex) {
|
||||
if (sLink[rIndex] != INT_MAX) {
|
||||
if (sLink[rIndex] != SK_MaxS32) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (rIndex < count);
|
||||
#if DEBUG_ASSEMBLE
|
||||
for (rIndex = 0; rIndex < count; ++rIndex) {
|
||||
SkASSERT(sLink[rIndex] == INT_MAX);
|
||||
SkASSERT(eLink[rIndex] == INT_MAX);
|
||||
SkASSERT(sLink[rIndex] == SK_MaxS32);
|
||||
SkASSERT(eLink[rIndex] == SK_MaxS32);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -15,4 +15,3 @@
|
||||
#include "SkTDArray.h"
|
||||
#include "ShapeOps.h"
|
||||
#include "TSearch.h"
|
||||
#include <algorithm> // used for std::min
|
||||
|
@ -3536,6 +3536,7 @@ static void testCubic1() {
|
||||
testSimplifyx(path);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void testQuadratic93() {
|
||||
SkPath path;
|
||||
path.moveTo(3, 0);
|
||||
@ -3548,6 +3549,20 @@ static void testQuadratic93() {
|
||||
path.close();
|
||||
testSimplifyx(path);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void cubicOp1d() {
|
||||
SkPath path, pathB;
|
||||
path.setFillType(SkPath::kWinding_FillType);
|
||||
path.moveTo(0,1);
|
||||
path.cubicTo(0,2, 1,0, 1,0);
|
||||
path.close();
|
||||
pathB.setFillType(SkPath::kWinding_FillType);
|
||||
pathB.moveTo(0,1);
|
||||
pathB.cubicTo(0,1, 1,0, 2,0);
|
||||
pathB.close();
|
||||
testShapeOp(path, pathB, kDifference_Op);
|
||||
}
|
||||
|
||||
static void (*firstTest)() = 0;
|
||||
|
||||
@ -3555,7 +3570,8 @@ static struct {
|
||||
void (*fun)();
|
||||
const char* str;
|
||||
} tests[] = {
|
||||
TEST(testQuadratic93),
|
||||
TEST(cubicOp1d),
|
||||
// TEST(testQuadratic93), // FIXME: gets stuck in a loop because top is unsortable
|
||||
TEST(testCubic1),
|
||||
TEST(testQuadralateral1),
|
||||
TEST(testLine85),
|
||||
|
@ -7,8 +7,6 @@
|
||||
#ifndef TSearch_DEFINED
|
||||
#define TSearch_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
// FIXME: Move this templated version into SKTSearch.h
|
||||
|
||||
template <typename T>
|
||||
|
@ -3328,11 +3328,23 @@ path.addRect(4, 13, 13, 16, SkPath::kCCW_Direction);
|
||||
path.close();
|
||||
</div>
|
||||
|
||||
<div id="cubicOp1d">
|
||||
path.setFillType(SkPath::kWinding_FillType);
|
||||
path.moveTo(0,1);
|
||||
path.cubicTo(0,2, 1,0, 1,0);
|
||||
path.close();
|
||||
pathB.setFillType(SkPath::kWinding_FillType);
|
||||
pathB.moveTo(0,1);
|
||||
pathB.cubicTo(0,1, 1,0, 2,0);
|
||||
pathB.close();
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var testDivs = [
|
||||
cubicOp1d,
|
||||
testQuadratic93,
|
||||
testCubic1,
|
||||
testQuadralateral1,
|
||||
|
@ -1703,11 +1703,26 @@ $7 = {{x = 24.006224853920855, y = 72.621119847810419}, {x = 29.758671200376888,
|
||||
{{x = 0.30387252963474076, y = 0.69616688005807803}, {x = 0.3039751936710845, y = 0.69622610811401087}}
|
||||
</div>
|
||||
|
||||
<div id="cubicOp1d">
|
||||
{{0, 1}, {0, 2}, {1, 0}, {1, 0}},
|
||||
{{0, 1}, {0, 1}, {1, 0}, {2, 0}},
|
||||
|
||||
{{0,1}, {0.0078125,1.35546875}, {0.15625,1.265625}},
|
||||
{{0.15625,1.265625}, {0.3046875,1.17578125}, {0.5,0.875}},
|
||||
{{0.5,0.875}, {0.6953125,0.57421875}, {0.84375,0.296875}},
|
||||
{{0.84375,0.296875}, {0.9921875,0.01953125}, {1,0}},
|
||||
|
||||
{{0,1}, {0.00925925926,0.981481481}, {0.296296296,0.740740741}},
|
||||
{{0.296296296,0.740740741}, {0.583333333,0.5}, {1.03703704,0.259259259}},
|
||||
{{1.03703704,0.259259259}, {1.49074074,0.0185185185}, {2,0}},
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var testDivs = [
|
||||
cubicOp1d,
|
||||
testCubic1b,
|
||||
testCubic1a,
|
||||
testCubic1,
|
||||
|
@ -1,8 +1,53 @@
|
||||
#import "SkCanvas.h"
|
||||
#import "SkPaint.h"
|
||||
#import "SkWindow.h"
|
||||
#include "SkGraphics.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkCGUtils.h"
|
||||
#include "SkGraphics.h"
|
||||
#include "SkImageDecoder.h"
|
||||
#include "SkOSFile.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPicture.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkWindow.h"
|
||||
|
||||
static void make_filepath(SkString* path, const char* dir, const SkString& name) {
|
||||
size_t len = strlen(dir);
|
||||
path->set(dir);
|
||||
if (len > 0 && dir[len - 1] != '/') {
|
||||
path->append("/");
|
||||
}
|
||||
path->append(name);
|
||||
}
|
||||
|
||||
static SkPicture* LoadPicture(const char path[]) {
|
||||
SkPicture* pic = NULL;
|
||||
|
||||
SkBitmap bm;
|
||||
if (SkImageDecoder::DecodeFile(path, &bm)) {
|
||||
bm.setImmutable();
|
||||
pic = SkNEW(SkPicture);
|
||||
SkCanvas* can = pic->beginRecording(bm.width(), bm.height());
|
||||
can->drawBitmap(bm, 0, 0, NULL);
|
||||
pic->endRecording();
|
||||
} else {
|
||||
SkFILEStream stream(path);
|
||||
if (stream.isValid()) {
|
||||
pic = SkNEW_ARGS(SkPicture,
|
||||
(&stream, NULL, &SkImageDecoder::DecodeStream));
|
||||
}
|
||||
|
||||
if (false) { // re-record
|
||||
SkPicture p2;
|
||||
pic->draw(p2.beginRecording(pic->width(), pic->height()));
|
||||
p2.endRecording();
|
||||
|
||||
SkString path2(path);
|
||||
path2.append(".new.skp");
|
||||
SkFILEWStream writer(path2.c_str());
|
||||
p2.serialize(&writer);
|
||||
}
|
||||
}
|
||||
return pic;
|
||||
}
|
||||
|
||||
class SkSampleView : public SkView {
|
||||
public:
|
||||
SkSampleView() {
|
||||
@ -16,17 +61,216 @@ protected:
|
||||
p.setTextSize(20);
|
||||
p.setAntiAlias(true);
|
||||
canvas->drawText("Hello World!", 13, 50, 30, p);
|
||||
SkRect r = {50, 50, 80, 80};
|
||||
// SkRect r = {50, 50, 80, 80};
|
||||
p.setColor(0xAA11EEAA);
|
||||
canvas->drawRect(r, p);
|
||||
// canvas->drawRect(r, p);
|
||||
|
||||
SkRect result;
|
||||
SkPath path;
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(1, 1);
|
||||
path.lineTo(1, 8);
|
||||
path.lineTo(0, 9);
|
||||
SkASSERT(path.hasRectangularInterior(&result));
|
||||
|
||||
path.reset();
|
||||
path.addRect(10, 10, 100, 100, SkPath::kCW_Direction);
|
||||
path.addRect(20, 20, 50, 50, SkPath::kCW_Direction);
|
||||
path.addRect(50, 50, 90, 90, SkPath::kCCW_Direction);
|
||||
p.setColor(0xAA335577);
|
||||
canvas->drawPath(path, p);
|
||||
SkASSERT(!path.hasRectangularInterior(NULL));
|
||||
path.reset();
|
||||
path.addRect(10, 10, 100, 100, SkPath::kCW_Direction);
|
||||
path.addRect(20, 20, 80, 80, SkPath::kCW_Direction);
|
||||
SkRect expected = {20, 20, 80, 80};
|
||||
SkASSERT(path.hasRectangularInterior(&result));
|
||||
SkASSERT(result == expected);
|
||||
|
||||
}
|
||||
private:
|
||||
typedef SkView INHERITED;
|
||||
};
|
||||
|
||||
void application_init();
|
||||
void application_term();
|
||||
|
||||
static int showPathContour(SkPath::Iter& iter) {
|
||||
uint8_t verb;
|
||||
SkPoint pts[4];
|
||||
int moves = 0;
|
||||
bool waitForClose = false;
|
||||
while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
|
||||
switch (verb) {
|
||||
case SkPath::kMove_Verb:
|
||||
if (!waitForClose) {
|
||||
++moves;
|
||||
waitForClose = true;
|
||||
}
|
||||
SkDebugf("path.moveTo(%1.9g, %1.9g);\n", pts[0].fX, pts[0].fY);
|
||||
break;
|
||||
case SkPath::kLine_Verb:
|
||||
SkDebugf("path.lineTo(%1.9g, %1.9g);\n", pts[1].fX, pts[1].fY);
|
||||
break;
|
||||
case SkPath::kQuad_Verb:
|
||||
SkDebugf("path.quadTo(%1.9g, %1.9g, %1.9g, %1.9g);\n",
|
||||
pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
|
||||
break;
|
||||
case SkPath::kCubic_Verb:
|
||||
SkDebugf("path.cubicTo(%1.9g, %1.9g, %1.9g, %1.9g, %1.9g, %1.9g);\n",
|
||||
pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY,
|
||||
pts[3].fX, pts[3].fY);
|
||||
break;
|
||||
case SkPath::kClose_Verb:
|
||||
waitForClose = false;
|
||||
SkDebugf("path.close();\n");
|
||||
break;
|
||||
default:
|
||||
SkDEBUGFAIL("bad verb");
|
||||
SkASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return moves;
|
||||
}
|
||||
|
||||
class PathCanvas : public SkCanvas {
|
||||
virtual void drawPath(const SkPath& path, const SkPaint& paint) {
|
||||
if (nameonly) {
|
||||
SkDebugf(" %s%d,\n", filename.c_str(), ++count);
|
||||
return;
|
||||
}
|
||||
SkPath::Iter iter(path, true);
|
||||
SkDebugf("<div id=\"%s%d\">\n", filename.c_str(), ++count);
|
||||
SkASSERT(path.getFillType() < SkPath::kInverseWinding_FillType);
|
||||
SkDebugf("path.setFillType(SkPath::k%s_FillType);\n",
|
||||
path.getFillType() == SkPath::kWinding_FillType ? "Winding" : "EvenOdd");
|
||||
int contours = showPathContour(iter);
|
||||
SkRect r;
|
||||
SkRect copy = r;
|
||||
bool hasOne = path.hasRectangularInterior(&r);
|
||||
bool expected = (path.getFillType() == SkPath::kWinding_FillType && contours == 1)
|
||||
|| (path.getFillType() == SkPath::kEvenOdd_FillType && contours == 2);
|
||||
if (!expected) {
|
||||
SkDebugf("suspect contours=%d\n", contours);
|
||||
}
|
||||
int verbs = path.countVerbs();
|
||||
int points = path.countPoints();
|
||||
if (hasOne) {
|
||||
if (rectVerbsMin > verbs) {
|
||||
rectVerbsMin = verbs;
|
||||
}
|
||||
if (rectVerbsMax < verbs) {
|
||||
rectVerbsMax = verbs;
|
||||
}
|
||||
if (rectPointsMin > points) {
|
||||
rectPointsMin = points;
|
||||
}
|
||||
if (rectPointsMax < points) {
|
||||
rectPointsMax = points;
|
||||
}
|
||||
SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g);\n",
|
||||
r.fLeft, r.fTop, r.fRight, r.fBottom);
|
||||
} else {
|
||||
if (verbsMin > verbs) {
|
||||
verbsMin = verbs;
|
||||
}
|
||||
if (verbsMax < verbs) {
|
||||
verbsMax = verbs;
|
||||
}
|
||||
if (pointsMin > points) {
|
||||
pointsMin = points;
|
||||
}
|
||||
if (pointsMax < points) {
|
||||
pointsMax = points;
|
||||
}
|
||||
SkDebugf("no interior bounds\n");
|
||||
}
|
||||
path.hasRectangularInterior(©);
|
||||
SkDebugf("</div>\n\n");
|
||||
}
|
||||
|
||||
virtual void drawPosTextH(const void* text, size_t byteLength,
|
||||
const SkScalar xpos[], SkScalar constY,
|
||||
const SkPaint& paint) {
|
||||
}
|
||||
|
||||
public:
|
||||
void divName(const SkString& str, bool only) {
|
||||
filename = str;
|
||||
char* chars = filename.writable_str();
|
||||
while (*chars) {
|
||||
if (*chars == '.' || *chars == '-') *chars = '_';
|
||||
chars++;
|
||||
}
|
||||
count = 0;
|
||||
nameonly = only;
|
||||
}
|
||||
|
||||
void init() {
|
||||
pointsMin = verbsMin = SK_MaxS32;
|
||||
pointsMax = verbsMax = SK_MinS32;
|
||||
rectPointsMin = rectVerbsMin = SK_MaxS32;
|
||||
rectPointsMax = rectVerbsMax = SK_MinS32;
|
||||
}
|
||||
|
||||
SkString filename;
|
||||
int count;
|
||||
bool nameonly;
|
||||
int pointsMin;
|
||||
int pointsMax;
|
||||
int verbsMin;
|
||||
int verbsMax;
|
||||
int rectPointsMin;
|
||||
int rectPointsMax;
|
||||
int rectVerbsMin;
|
||||
int rectVerbsMax;
|
||||
};
|
||||
|
||||
bool runone = false;
|
||||
|
||||
void application_init() {
|
||||
SkGraphics::Init();
|
||||
SkEvent::Init();
|
||||
if (runone) {
|
||||
return;
|
||||
}
|
||||
const char pictDir[] = "/Volumes/chrome/nih/skia/skp/skp";
|
||||
SkOSFile::Iter iter(pictDir, "skp");
|
||||
SkString filename;
|
||||
PathCanvas canvas;
|
||||
canvas.init();
|
||||
while (iter.next(&filename)) {
|
||||
SkString path;
|
||||
// if (true) filename.set("tabl_www_sahadan_com.skp");
|
||||
make_filepath(&path, pictDir, filename);
|
||||
canvas.divName(filename, false);
|
||||
SkPicture* pic = LoadPicture(path.c_str());
|
||||
pic->draw(&canvas);
|
||||
SkDELETE(pic);
|
||||
}
|
||||
SkDebugf("\n</div>\n\n");
|
||||
|
||||
SkDebugf("<script type=\"text/javascript\">\n\n");
|
||||
SkDebugf("var testDivs = [\n");
|
||||
|
||||
iter.reset(pictDir, "skp");
|
||||
while (iter.next(&filename)) {
|
||||
SkString path;
|
||||
make_filepath(&path, pictDir, filename);
|
||||
canvas.divName(filename, true);
|
||||
SkPicture* pic = LoadPicture(path.c_str());
|
||||
pic->draw(&canvas);
|
||||
SkDELETE(pic);
|
||||
}
|
||||
SkDebugf("];\n\n");
|
||||
|
||||
SkDebugf("points min=%d max=%d verbs min=%d max=%d\n", canvas.pointsMin, canvas.pointsMax,
|
||||
canvas.verbsMin, canvas.verbsMax);
|
||||
SkDebugf("rect points min=%d max=%d verbs min=%d max=%d\n", canvas.rectPointsMin, canvas.rectPointsMax,
|
||||
canvas.rectVerbsMin, canvas.rectVerbsMax);
|
||||
|
||||
SkDebugf("\n");
|
||||
}
|
||||
|
||||
void application_term() {
|
||||
@ -46,7 +290,7 @@ protected:
|
||||
@implementation SimpleNSView
|
||||
|
||||
- (id)initWithDefaults {
|
||||
if (self = [super initWithDefaults]) {
|
||||
if ((self = [super initWithDefaults])) {
|
||||
fWind = new SkOSWindow(self);
|
||||
fWind->setLayout(new FillLayout, false);
|
||||
fWind->attachChildToFront(new SkSampleView)->unref();
|
||||
@ -59,4 +303,4 @@ protected:
|
||||
SkCGDrawBitmap(ctx, fWind->getBitmap(), 0, 0);
|
||||
}
|
||||
|
||||
@end
|
||||
@end
|
||||
|
@ -75,6 +75,7 @@
|
||||
'../experimental/Intersection/QuarticRoot.cpp',
|
||||
'../experimental/Intersection/QuarticRoot_Test.cpp',
|
||||
'../experimental/Intersection/ShapeOps.cpp',
|
||||
'../experimental/Intersection/ShapeOpCubic4x4_Test.cpp',
|
||||
'../experimental/Intersection/ShapeOpRect4x4_Test.cpp',
|
||||
'../experimental/Intersection/Simplify.cpp',
|
||||
'../experimental/Intersection/SimplifyAddIntersectingTs_Test.cpp',
|
||||
|
Loading…
Reference in New Issue
Block a user