2012-05-18 20:50:33 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2012 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "Simplify.h"
|
|
|
|
|
|
|
|
namespace SimplifyFindTopTest {
|
|
|
|
|
|
|
|
#include "Simplify.cpp"
|
|
|
|
|
|
|
|
} // end of SimplifyFindTopTest namespace
|
|
|
|
|
|
|
|
#include "Intersection_Tests.h"
|
|
|
|
|
|
|
|
static const SimplifyFindTopTest::Segment* testCommon(
|
|
|
|
SkTArray<SimplifyFindTopTest::Contour>& contours,
|
2012-05-22 17:01:14 +00:00
|
|
|
int& index, int& end) {
|
2012-05-18 20:50:33 +00:00
|
|
|
SkTDArray<SimplifyFindTopTest::Contour*> contourList;
|
2012-05-22 17:01:14 +00:00
|
|
|
makeContourList(contours, contourList);
|
2012-05-23 18:09:25 +00:00
|
|
|
addIntersectTs(contourList[0], contourList[0]);
|
2012-05-18 20:50:33 +00:00
|
|
|
if (contours.count() > 1) {
|
|
|
|
SkASSERT(contours.count() == 2);
|
2012-05-23 18:09:25 +00:00
|
|
|
addIntersectTs(contourList[0], contourList[1]);
|
|
|
|
addIntersectTs(contourList[1], contourList[1]);
|
2012-05-18 20:50:33 +00:00
|
|
|
}
|
|
|
|
fixOtherTIndex(contourList);
|
2012-10-19 15:54:16 +00:00
|
|
|
#if SORTABLE_CONTOURS // old way
|
2012-08-02 20:08:21 +00:00
|
|
|
SimplifyFindTopTest::Segment* topStart = findTopContour(contourList);
|
2012-05-18 20:50:33 +00:00
|
|
|
const SimplifyFindTopTest::Segment* topSegment = topStart->findTop(index,
|
2012-05-22 17:01:14 +00:00
|
|
|
end);
|
2012-10-19 15:54:16 +00:00
|
|
|
#else
|
2012-10-26 21:03:50 +00:00
|
|
|
SkPoint bestXY = {SK_ScalarMin, SK_ScalarMin};
|
|
|
|
const SimplifyFindTopTest::Segment* topSegment =
|
|
|
|
findSortableTop(contourList, index, end, bestXY);
|
2012-10-19 15:54:16 +00:00
|
|
|
#endif
|
2012-05-18 20:50:33 +00:00
|
|
|
return topSegment;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void test(const SkPath& path) {
|
|
|
|
SkTArray<SimplifyFindTopTest::Contour> contours;
|
|
|
|
SimplifyFindTopTest::EdgeBuilder builder(path, contours);
|
2012-05-22 17:01:14 +00:00
|
|
|
int index, end;
|
2012-05-23 18:09:25 +00:00
|
|
|
testCommon(contours, index, end);
|
2012-05-22 17:01:14 +00:00
|
|
|
SkASSERT(index + 1 == end);
|
2012-05-18 20:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void test(const SkPath& path, SkScalar x1, SkScalar y1,
|
|
|
|
SkScalar x2, SkScalar y2) {
|
|
|
|
SkTArray<SimplifyFindTopTest::Contour> contours;
|
|
|
|
SimplifyFindTopTest::EdgeBuilder builder(path, contours);
|
2012-05-22 17:01:14 +00:00
|
|
|
int index, end;
|
2012-05-18 20:50:33 +00:00
|
|
|
const SimplifyFindTopTest::Segment* topSegment =
|
2012-05-23 18:09:25 +00:00
|
|
|
testCommon(contours, index, end);
|
2012-05-22 17:01:14 +00:00
|
|
|
SkPoint pts[2];
|
|
|
|
double firstT = topSegment->t(index);
|
2012-06-01 17:44:28 +00:00
|
|
|
pts[0] = topSegment->xyAtT(&topSegment->span(index));
|
2012-05-22 17:01:14 +00:00
|
|
|
int direction = index < end ? 1 : -1;
|
|
|
|
do {
|
|
|
|
index += direction;
|
|
|
|
double nextT = topSegment->t(index);
|
|
|
|
if (nextT == firstT) {
|
|
|
|
continue;
|
|
|
|
}
|
2012-06-01 17:44:28 +00:00
|
|
|
pts[1] = topSegment->xyAtT(&topSegment->span(index));
|
2012-05-22 17:01:14 +00:00
|
|
|
if (pts[0] != pts[1]) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (true);
|
|
|
|
SkASSERT(pts[0].fX == x1);
|
|
|
|
SkASSERT(pts[0].fY == y1);
|
|
|
|
SkASSERT(pts[1].fX == x2);
|
|
|
|
SkASSERT(pts[1].fY == y2);
|
2012-05-18 20:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void testLine1() {
|
|
|
|
SkPath path;
|
|
|
|
path.moveTo(2,0);
|
|
|
|
path.lineTo(1,1);
|
|
|
|
path.lineTo(0,0);
|
|
|
|
path.close();
|
|
|
|
test(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void addInnerCWTriangle(SkPath& path) {
|
|
|
|
path.moveTo(3,0);
|
|
|
|
path.lineTo(4,1);
|
|
|
|
path.lineTo(2,1);
|
|
|
|
path.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void addInnerCCWTriangle(SkPath& path) {
|
|
|
|
path.moveTo(3,0);
|
|
|
|
path.lineTo(2,1);
|
|
|
|
path.lineTo(4,1);
|
|
|
|
path.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void addOuterCWTriangle(SkPath& path) {
|
|
|
|
path.moveTo(3,0);
|
|
|
|
path.lineTo(6,2);
|
|
|
|
path.lineTo(0,2);
|
|
|
|
path.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void addOuterCCWTriangle(SkPath& path) {
|
|
|
|
path.moveTo(3,0);
|
|
|
|
path.lineTo(0,2);
|
|
|
|
path.lineTo(6,2);
|
|
|
|
path.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void testLine2() {
|
|
|
|
SkPath path;
|
|
|
|
addInnerCWTriangle(path);
|
|
|
|
addOuterCWTriangle(path);
|
2012-05-22 17:01:14 +00:00
|
|
|
test(path, 0, 2, 3, 0);
|
2012-05-18 20:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void testLine3() {
|
|
|
|
SkPath path;
|
|
|
|
addOuterCWTriangle(path);
|
|
|
|
addInnerCWTriangle(path);
|
2012-05-22 17:01:14 +00:00
|
|
|
test(path, 0, 2, 3, 0);
|
2012-05-18 20:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void testLine4() {
|
|
|
|
SkPath path;
|
|
|
|
addInnerCCWTriangle(path);
|
|
|
|
addOuterCWTriangle(path);
|
2012-05-22 17:01:14 +00:00
|
|
|
test(path, 0, 2, 3, 0);
|
2012-05-18 20:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void testLine5() {
|
|
|
|
SkPath path;
|
|
|
|
addOuterCWTriangle(path);
|
|
|
|
addInnerCCWTriangle(path);
|
2012-05-22 17:01:14 +00:00
|
|
|
test(path, 0, 2, 3, 0);
|
2012-05-18 20:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void testLine6() {
|
|
|
|
SkPath path;
|
|
|
|
addInnerCWTriangle(path);
|
|
|
|
addOuterCCWTriangle(path);
|
2012-05-22 17:01:14 +00:00
|
|
|
test(path, 0, 2, 3, 0);
|
2012-05-18 20:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void testLine7() {
|
|
|
|
SkPath path;
|
|
|
|
addOuterCCWTriangle(path);
|
|
|
|
addInnerCWTriangle(path);
|
2012-05-22 17:01:14 +00:00
|
|
|
test(path, 0, 2, 3, 0);
|
2012-05-18 20:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void testLine8() {
|
|
|
|
SkPath path;
|
|
|
|
addInnerCCWTriangle(path);
|
|
|
|
addOuterCCWTriangle(path);
|
2012-05-22 17:01:14 +00:00
|
|
|
test(path, 0, 2, 3, 0);
|
2012-05-18 20:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void testLine9() {
|
|
|
|
SkPath path;
|
|
|
|
addOuterCCWTriangle(path);
|
|
|
|
addInnerCCWTriangle(path);
|
2012-05-22 17:01:14 +00:00
|
|
|
test(path, 0, 2, 3, 0);
|
2012-05-18 20:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void testQuads() {
|
|
|
|
SkPath path;
|
|
|
|
path.moveTo(2,0);
|
|
|
|
path.quadTo(1,1, 0,0);
|
|
|
|
path.close();
|
|
|
|
test(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void testCubics() {
|
|
|
|
SkPath path;
|
|
|
|
path.moveTo(2,0);
|
|
|
|
path.cubicTo(2,3, 1,1, 0,0);
|
|
|
|
path.close();
|
|
|
|
test(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void (*tests[])() = {
|
|
|
|
testLine1,
|
|
|
|
testLine2,
|
|
|
|
testLine3,
|
|
|
|
testLine4,
|
|
|
|
testLine5,
|
|
|
|
testLine6,
|
|
|
|
testLine7,
|
|
|
|
testLine8,
|
|
|
|
testLine9,
|
|
|
|
testQuads,
|
|
|
|
testCubics
|
|
|
|
};
|
|
|
|
|
|
|
|
static const size_t testCount = sizeof(tests) / sizeof(tests[0]);
|
|
|
|
|
|
|
|
static void (*firstTest)() = 0;
|
|
|
|
static bool skipAll = false;
|
|
|
|
|
|
|
|
void SimplifyFindTop_Test() {
|
|
|
|
if (skipAll) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
size_t index = 0;
|
|
|
|
if (firstTest) {
|
|
|
|
while (index < testCount && tests[index] != firstTest) {
|
|
|
|
++index;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bool firstTestComplete = false;
|
|
|
|
for ( ; index < testCount; ++index) {
|
|
|
|
(*tests[index])();
|
|
|
|
firstTestComplete = true;
|
|
|
|
}
|
|
|
|
}
|