44#ifdef SK_BUILD_FOR_MAC
45#include <sys/sysctl.h>
54 std::ostringstream os ;
70 "<script type=\"text/javascript\">\n"
75 "kDifference_SkPathOp",
76 "kIntersect_SkPathOp",
79 "kReverseDifference_SkPathOp",
122 SkDebugf(
"op reverse difference\n");
134 larger.
join(two.getBounds());
136 if (largerWidth < 4) {
140 if (largerHeight < 4) {
146 scale.preScale(hScale, vScale);
147 larger.
fLeft *= hScale;
149 larger.
fTop *= vScale;
155 scale.postTranslate(dx, dy);
160 if (bits.width() == 0) {
178 uint32_t* addr1 = bits.getAddr32(0,
y);
179 uint32_t* addr2 = bits.getAddr32(0,
y + 1);
180 uint32_t* addr3 = bits.getAddr32(
kBitWidth,
y);
181 uint32_t* addr4 = bits.getAddr32(
kBitWidth,
y + 1);
184 bool err = addr1[
x] != addr3[
x];
186 errors2 += addr1[
x + 1] != addr3[
x + 1]
187 && addr2[
x] != addr4[
x] && addr2[
x + 1] != addr4[
x + 1];
197 SkPath& scaledTwo,
int& error2x2) {
201 two.transform(
scale, &scaledTwo);
210 const SkRect& bounds2 = two.getBounds();
212 larger.
join(bounds2);
216 if (bitWidth * 2 + 1 >= (
int)
sizeof(out)) {
220 if (bitHeight >= (
int)
sizeof(out)) {
223 bits.allocN32Pixels(bitWidth * 2, bitHeight);
235 for (
int y = 0;
y < bitHeight; ++
y) {
236 uint32_t* addr1 = bits.getAddr32(0,
y);
239 for (
x = 0;
x < bitWidth; ++
x) {
240 *outPtr++ = addr1[
x] == (uint32_t) -1 ?
'_' :
'x';
243 for (
x = bitWidth;
x < bitWidth * 2; ++
x) {
244 *outPtr++ = addr1[
x] == (uint32_t) -1 ?
'_' :
'x';
255 SkPath scaledOne, scaledTwo;
257 if (errors2x2 == 0) {
260 const int MAX_ERRORS = 9;
261 return errors2x2 > MAX_ERRORS ? errors2x2 : 0;
273 SkDebugf(
"static void %s_%s(skiatest::Reporter* reporter, const char* filename) {\n",
279 SkDebugf(
" testPathOp(reporter, path, pathB, %s, filename);\n",
opStrs[shapeOp]);
288 static SkMutex& compareDebugOut3 = *(
new SkMutex);
290 const int MAX_ERRORS = 8;
293 if (errors2x2 < MAX_ERRORS) {
298 if (errors2x2 == 0) {
308 return errors2x2 >= MAX_ERRORS ? errors2x2 : 0;
320 out.append(nameSuffix);
324static void appendTest(
const char* pathStr,
const char* pathPrefix,
const char* nameSuffix,
325 const char* testFunction,
bool twoPaths, std::string& out) {
327 out.append(
"\n<div id=\"");
331 out.append(pathPrefix);
334 out.append(
"</div>\n\n");
339 out.append(
",\n\n\n");
341 out.append(
"static void ");
343 out.append(
"(skiatest::Reporter* reporter) {\n SkPath path");
345 out.append(
", pathB");
349 out.append(pathPrefix);
355 out.append(
"static void (*firstTest)() = ");
359 out.append(
"static struct {\n");
360 out.append(
" void (*fun)();\n");
361 out.append(
" const char* str;\n");
362 out.append(
"} tests[] = {\n");
363 out.append(
" TEST(");
377 const char* pathStr) {
378 static SkMutex& simplifyDebugOut = *(
new SkMutex);
380 path.setFillType(fillType);
381 state.fReporter->bumpTestCount();
383 SkDebugf(
"%s did not expect failure\n", __FUNCTION__);
387 if (!
state.fReporter->verbose()) {
394 const char* pathPrefix =
nullptr;
395 const char* nameSuffix =
nullptr;
397 pathPrefix =
" path.setFillType(SkPathFillType::kEvenOdd);\n";
400 const char testFunction[] =
"testSimplify(reporter, path);";
401 appendTest(pathStr, pathPrefix, nameSuffix, testFunction,
false, str);
405 state.fReporter->bumpTestCount();
425 char const *
const gFillTypeStrs[] = {
436 const int verbConst[] = { 0, 1, 2, 3, 4, 5 };
437 const int pointIndex[] = { 0, 1, 1, 1, 1, 0 };
438 const int pointCount[] = { 1, 2, 3, 3, 4, 0 };
447 int verbIndex = (
int) verb;
449 for (
int i = pointIndex[verbIndex]; i < pointCount[verbIndex]; ++i) {
461 gFillTypeStrs[(
int) path.getFillType()], lastField ?
"\n}" :
",\n");
467 std::string(testName))) {
493 SkDebugf(
"%s did not expect %s failure\n", __FUNCTION__, filename);
503 SkDebugf(
"%s %s unexpected success\n", __FUNCTION__, filename);
515 SkDebugf(
"%s failing test %s now succeeds\n", __FUNCTION__, filename);
567 SkDebugf(
"%s %s did not expect failure\n", __FUNCTION__, testName);
577 SkDebugf(
"%s %s unexpected success\n", __FUNCTION__, testName);
588 SkPath pathOut, scaledPathOut;
589 SkRegion rgnA, rgnB, openClip, rgnOut;
590 openClip.
setRect({-16000, -16000, 16000, 16000});
598 SkRegion scaledRgnA, scaledRgnB, scaledRgnOut;
604 scaledRgnA.
setPath(scaledA, openClip);
605 scaledRgnB.
setPath(scaledB, openClip);
613 a,
b, shapeOp,
scale, expectMatch);
619 const SkPathOp shapeOp,
const char* testName) {
625 const SkPathOp shapeOp,
const char* testName,
bool checkFail) {
631 const SkPathOp shapeOp,
const char* testName) {
637 const SkPathOp shapeOp,
const char* testName) {
641 if (Op(
a,
b, shapeOp, &out) ) {
642 SkDebugf(
"%s test is expected to fail\n", __FUNCTION__);
651 static SkMutex& mu = *(
new SkMutex);
655 size_t testNameSize = strlen(
test);
656 SkFILEStream inFile(
"../../experimental/Intersection/op.htm");
660 size_t inLen = inData.
size();
665 insert +=
sizeof(
marker) - 1;
666 const char* numLoc = insert + 4 + testNameSize - 1;
674 const char testFunction[] =
"testSimplify(path);";
675 const char* pathPrefix =
nullptr;
676 const char* nameSuffix =
nullptr;
678 pathPrefix =
" path.setFillType(SkPathFillType::kEvenOdd);\n";
685 const char testFunction[] =
"testOp(path);";
706 index = reverse ?
count - 1 : 0;
707 size_t last = reverse ? 0 :
count - 1;
719 index += reverse ? -1 : 1;
static const int points[]
static void(* stopTest)(skiatest::Reporter *, const char *filename)
static void(* firstTest)(skiatest::Reporter *, const char *filename)
static void(* skipTest)(skiatest::Reporter *, const char *filename)
bool testSimplifyCheck(skiatest::Reporter *reporter, const SkPath &path, const char *filename, bool checkFail)
bool OpDebug(const SkPath &one, const SkPath &two, SkPathOp op, SkPath *result SkDEBUGPARAMS(bool skipAssert) SkDEBUGPARAMS(const char *testName))
bool testSimplifyFuzz(skiatest::Reporter *reporter, const SkPath &path, const char *filename)
bool SimplifyDebug(const SkPath &one, SkPath *result SkDEBUGPARAMS(bool skipAssert) SkDEBUGPARAMS(const char *testName))
bool testPathOp(skiatest::Reporter *reporter, const SkPath &a, const SkPath &b, const SkPathOp shapeOp, const char *testName)
void markTestFlakyForPathKit()
static void json_path_out(const SkPath &path, const char *pathName, const char *fillTypeName, bool lastField)
bool testSimplify(SkPath &path, bool useXor, SkPath &out, PathOpsThreadState &state, const char *pathStr)
static SkTDArray< SkPathOp > gTestOp
void RunTestSet(skiatest::Reporter *reporter, TestDesc tests[], size_t count, void(*firstTest)(skiatest::Reporter *, const char *filename), void(*skipTest)(skiatest::Reporter *, const char *filename), void(*stopTest)(skiatest::Reporter *, const char *filename), bool reverse)
int comparePaths(skiatest::Reporter *reporter, const char *filename, const SkPath &one, const SkPath &two, SkBitmap &bitmap)
bool testPathOpFuzz(skiatest::Reporter *reporter, const SkPath &a, const SkPath &b, const SkPathOp shapeOp, const char *testName)
std::string std_to_string(T value)
bool testPathOpFail(skiatest::Reporter *reporter, const SkPath &a, const SkPath &b, const SkPathOp shapeOp, const char *testName)
static const char marker[]
static void appendTestName(const char *nameSuffix, std::string &out)
static const char * opSuffixes[]
static const char * opStrs[]
static bool inner_simplify(skiatest::Reporter *reporter, const SkPath &path, const char *filename, ExpectSuccess expectSuccess, SkipAssert skipAssert, ExpectMatch expectMatch)
static void scaleMatrix(const SkPath &one, const SkPath &two, SkMatrix &scale)
static int pathsDrawTheSame(SkBitmap &bits, const SkPath &scaledOne, const SkPath &scaledTwo, int &error2x2)
static bool check_for_duplicate_names(const char *testName)
std::vector< std::string > gUniqueNames
void showOp(const SkPathOp op)
bool drawAsciiPaths(const SkPath &one, const SkPath &two, bool drawPaths)
static bool innerPathOp(skiatest::Reporter *reporter, const SkPath &a, const SkPath &b, const SkPathOp shapeOp, const char *testName, ExpectSuccess expectSuccess, SkipAssert skipAssert, ExpectMatch expectMatch)
static void appendTest(const char *pathStr, const char *pathPrefix, const char *nameSuffix, const char *testFunction, bool twoPaths, std::string &out)
static void json_status(ExpectSuccess expectSuccess, ExpectMatch expectMatch, bool opSucceeded)
static void showPathOpPath(const char *testName, const SkPath &one, const SkPath &two, const SkPath &a, const SkPath &b, const SkPath &scaledOne, const SkPath &scaledTwo, const SkPathOp shapeOp, const SkMatrix &scale)
void initializeTests(skiatest::Reporter *reporter, const char *test)
static const char * sTestName
bool testPathOpCheck(skiatest::Reporter *reporter, const SkPath &a, const SkPath &b, const SkPathOp shapeOp, const char *testName, bool checkFail)
bool testSimplifyFail(skiatest::Reporter *reporter, const SkPath &path, const char *filename)
constexpr SkColor SK_ColorWHITE
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static uint32_t SkFloat2Bits(float value)
#define SkDEBUGPARAMS(...)
@ kReverseDifference_SkPathOp
subtract the first path from the op path
@ kDifference_SkPathOp
subtract the op path from the first path
@ kIntersect_SkPathOp
intersect the two paths
@ kUnion_SkPathOp
union (inclusive-or) the two paths
@ kXOR_SkPathOp
exclusive-or the two paths
bool SK_API Simplify(const SkPath &path, SkPath *result)
@ kConic
SkPath::RawIter returns 3 points + 1 weight.
#define SkScalarCeilToInt(x)
#define REPORTER_ASSERT(r, cond,...)
Type::kYUV Type::kRGBA() int(0.7 *637)
static bool gCheckForDuplicateNames
static bool gMarkJsonFlaky
void translate(SkScalar dx, SkScalar dy)
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
void drawPath(const SkPath &path, const SkPaint &paint)
size_t read(void *buffer, size_t size) override
size_t getLength() const override
static SkString ToSVGString(const SkPath &, PathEncoding=PathEncoding::Absolute)
static void ShowOnePath(const SkPath &path, const char *name, bool includeDeclaration)
void setFillType(SkPathFillType ft)
SkPath & lineTo(SkScalar x, SkScalar y)
SkPath & addPath(const SkPath &src, SkScalar dx, SkScalar dy, AddPathMode mode=kAppend_AddPathMode)
const SkRect & getBounds() const
void transform(const SkMatrix &matrix, SkPath *dst, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
bool getBoundaryPath(SkPath *path) const
bool op(const SkIRect &rect, Op op)
bool setRect(const SkIRect &rect)
bool setPath(const SkPath &path, const SkRegion &clip)
void outputProgress(const char *pathStr, SkPathFillType)
SkScalar fBottom
larger y-axis bounds
SkScalar fLeft
smaller x-axis bounds
SkScalar fRight
larger x-axis bounds
constexpr float height() const
constexpr float width() const
void join(const SkRect &r)
SkScalar fTop
smaller y-axis bounds