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;
}
// 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;
}
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;
}
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;
}
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];
}
}
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
++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],
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;
}
}
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]);
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]);
}
} 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]);
}
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]);
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]);
}
} 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]);
#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
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)
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;
}
#if SK_DEBUG
++debugDepth;
- assert(debugDepth < 10);
+ SkASSERT(debugDepth < 10);
#endif
i.swap();
intersect2(cubic2, SkTMax(to2 - dt2, 0.), SkTMin(to2 + dt2, 1.),
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;
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}},
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;
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];
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));
}
}
}
*/
#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
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;
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);
}
}
}
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);
}
}
}
--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)) {
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) {
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) {
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);
}
}
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
|| (!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);
}
}
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;
}
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;
}
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);
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) {
#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); }
}
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;
}
}
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;
}
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;
}
testSimplifyx(tiny);
}
+#endif
+#if 0
static void tryRonco(const SkPath& path) {
int divMax = 64;
int divMin = 1;
}
}
}
+#endif
static bool drawLetters(SkCanvas* canvas, int step, bool useOld)
{
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) {
#include "Intersection_Tests.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
-#include <assert.h>
static void* testSimplify4x4QuadraticsMain(void* data)
#include "SkStream.h"
#include <algorithm>
-#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
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);
}
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() {
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);
}
}
*/
#include "CubicIntersection_TestData.h"
#include "Intersection_Tests.h"
-#include "SkTypes.h"
void cubecode_test(int test);
int testsRun = 0;
SimplifyNew_Test();
- CubicToQuadratics_Test();
CubicIntersection_OneOffTest();
+ ShapeOps4x4CubicsThreaded_Test(testsRun);
+ CubicToQuadratics_Test();
QuadraticIntersection_Test();
QuarticRoot_Test();
CubicIntersection_RandTest();
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();
#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];
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;
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;
return;
}
}
- assert(fCoincidentUsed < 9);
+ SkASSERT(fCoincidentUsed < 9);
fCoincidentT[fSwap][fCoincidentUsed] = s1;
fCoincidentT[fSwap ^ 1][fCoincidentUsed] = s2;
++fCoincidentUsed;
}
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)
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);
// 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)) {
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);
#ifndef Intersections_DEFINE
#define Intersections_DEFINE
-#include <algorithm> // for std::min -- Skia doesn't have a SkMinDouble
-#include "SkTypes.h"
-
class Intersections {
public:
Intersections()
return;
}
}
- assert(fUsed < 9);
+ SkASSERT(fUsed < 9);
fT[fSwap][fUsed] = one;
fT[fSwap ^ 1][fUsed] = two;
++fUsed;
return;
}
}
- assert(fCoincidentUsed < 9);
+ SkASSERT(fCoincidentUsed < 9);
fCoincidentT[fSwap][fCoincidentUsed] = one;
fCoincidentT[fSwap ^ 1][fCoincidentUsed] = two;
++fCoincidentUsed;
#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.
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;
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;
}
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];
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
}
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;
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;
}
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
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;
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;
}
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
}
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;
}
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],
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]);
}
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));
}
}
#include "CurveIntersection.h"
#include "CurveUtilities.h"
#include "LineParameters.h"
-#include <algorithm> // used for std::swap
#define DEBUG_BEZIER_CLIP 1
endLine.quadEndPoints(q1);
if (!endLine.normalize()) {
printf("line cannot be normalized: need more code here\n");
- assert(0);
+ SkASSERT(0);
return false;
}
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
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;
}
}
}
- assert(i.fUsed < 3);
+ SkASSERT(i.fUsed < 3);
return true;
tryNextHalfPlane:
;
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;
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];
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 {
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;
}
}
{
_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;
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);
#include "Intersections.h"
#include "QuadraticIntersection_TestData.h"
#include "TestUtilities.h"
-#include "SkTypes.h"
const int firstQuadIntersectionTest = 9;
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);
}
}
--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)) {
#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}},
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];
* found in the LICENSE file.
*/
#include "QuadraticUtilities.h"
-#include "SkTypes.h"
#include <math.h>
/*
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)) {
-#include <assert.h>
-#include <math.h>
#include "CubicUtilities.h"
#include "Intersection_Tests.h"
#include "QuadraticUtilities.h"
} 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));
}
}
} 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));
}
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));
--- /dev/null
+/*
+ * 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);
+}
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;
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++;
+ }
}
}
}
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
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:
}
// 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) {
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;
}
#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) {
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
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]);
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',
}
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;
}
} 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
}
#include "SkTDArray.h"
#include "ShapeOps.h"
#include "TSearch.h"
-#include <algorithm> // used for std::min
testSimplifyx(path);
}
+#if 0
static void testQuadratic93() {
SkPath path;
path.moveTo(3, 0);
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;
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),
#ifndef TSearch_DEFINED
#define TSearch_DEFINED
-#include "SkTypes.h"
-
// FIXME: Move this templated version into SKTSearch.h
template <typename T>
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,
{{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,
-#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() {
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() {
@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();
SkCGDrawBitmap(ctx, fWind->getBitmap(), 0, 0);
}
-@end
\ No newline at end of file
+@end
'../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',