EdgeWalker_TestUtility.cpp revision 78e17130f396d8b2157116c2504e357192f87ed1
1cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com#include "EdgeWalker_Test.h"
2cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com#include "Intersection_Tests.h"
3cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com#include "SkBitmap.h"
4cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com#include "SkCanvas.h"
5cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com#include "SkPaint.h"
6fb173424e915e696a73067d616ce4f39a407261acaryclark@google.com#include <algorithm>
7cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com
878e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com#undef SkASSERT
978e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com#define SkASSERT(cond) while (!(cond)) { sk_throw(); }
1078e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com
112e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.comstatic bool gShowPath = false;
12198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.comstatic bool gComparePaths = true;
13752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.comstatic bool gDrawLastAsciiPaths = true;
14cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.comstatic bool gDrawAllAsciiPaths = false;
152e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.comstatic bool gShowAsciiPaths = false;
16752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.comstatic bool gComparePathsAssert = true;
17cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com
182e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.comvoid showPath(const SkPath& path, const char* str) {
19752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com    SkDebugf("%s\n", !str ? "original:" : str);
20cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    SkPath::Iter iter(path, true);
21cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    uint8_t verb;
22cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    SkPoint pts[4];
23cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
24cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        switch (verb) {
25cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com            case SkPath::kMove_Verb:
26d88e0894d0156f4d427b812fec69bfba3eec7a8dcaryclark@google.com                SkDebugf("path.moveTo(%1.9g, %1.9g);\n", pts[0].fX, pts[0].fY);
27cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com                continue;
28cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com            case SkPath::kLine_Verb:
29d88e0894d0156f4d427b812fec69bfba3eec7a8dcaryclark@google.com                SkDebugf("path.lineTo(%1.9g, %1.9g);\n", pts[1].fX, pts[1].fY);
30cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com                break;
31cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com            case SkPath::kQuad_Verb:
32d88e0894d0156f4d427b812fec69bfba3eec7a8dcaryclark@google.com                SkDebugf("path.quadTo(%1.9g, %1.9g, %1.9g, %1.9g);\n",
33cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com                    pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
34cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com                break;
35cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com            case SkPath::kCubic_Verb:
36d88e0894d0156f4d427b812fec69bfba3eec7a8dcaryclark@google.com                SkDebugf("path.cubicTo(%1.9g, %1.9g, %1.9g, %1.9g);\n",
37cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com                    pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY,
38cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com                    pts[3].fX, pts[3].fY);
39cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com                break;
40cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com            case SkPath::kClose_Verb:
41cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com                SkDebugf("path.close();\n");
42cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com                continue;
43cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com            default:
44cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com                SkDEBUGFAIL("bad verb");
45cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com                return;
46cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        }
47cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    }
48cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com}
49cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com
50198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.comstatic int pathsDrawTheSame(const SkPath& one, const SkPath& two,
51198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        SkBitmap& bits, SkCanvas* c) {
52198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    SkCanvas* canvasPtr = c;
53198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    if (!c) {
54198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        canvasPtr = new SkCanvas(bits);
55198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    }
56cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    const SkRect& bounds1 = one.getBounds();
57cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    const SkRect& bounds2 = two.getBounds();
58cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    SkRect larger = bounds1;
59cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    larger.join(bounds2);
60cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    int bitWidth = SkScalarCeil(larger.width()) + 2;
61cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    int bitHeight = SkScalarCeil(larger.height()) + 2;
62198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    if (bits.width() < bitWidth * 2 || bits.height() < bitHeight) {
63198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        if (bits.width() >= 200) {
64198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com            SkDebugf("%s bitWidth=%d bitHeight=%d\n", __FUNCTION__, bitWidth, bitHeight);
65198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        }
66198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        bits.setConfig(SkBitmap::kARGB_8888_Config, bitWidth * 2, bitHeight);
67198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        bits.allocPixels();
68198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        canvasPtr->setBitmapDevice(bits);
69198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    }
70198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    SkCanvas& canvas = *canvasPtr;
71cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.drawColor(SK_ColorWHITE);
72cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    SkPaint paint;
73cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.save();
74cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.translate(-bounds1.fLeft + 1, -bounds1.fTop + 1);
75cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.drawPath(one, paint);
76cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.restore();
77cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.save();
78cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.translate(-bounds1.fLeft + 1 + bitWidth, -bounds1.fTop + 1);
79cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.drawPath(two, paint);
80cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.restore();
81198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    int errors = 0;
82cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    for (int y = 0; y < bitHeight; ++y) {
83cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        uint32_t* addr1 = bits.getAddr32(0, y);
84cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        uint32_t* addr2 = bits.getAddr32(bitWidth, y);
85cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        for (int x = 0; x < bitWidth; ++x) {
86198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com            errors += addr1[x] != addr2[x];
87cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        }
88cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    }
89198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    if (!c) {
90198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        delete canvasPtr;
91198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    }
92198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    return errors;
93198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com}
94198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com
95198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.comvoid bitmapInit(SkBitmap& bits) {
96cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com}
97cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com
98752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.combool drawAsciiPaths(const SkPath& one, const SkPath& two,
99cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        bool drawPaths) {
100cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    if (!drawPaths) {
101752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com        return true;
102cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    }
1032e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com    if (gShowAsciiPaths) {
1042e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com        showPath(one, "one:");
1052e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com        showPath(two, "two:");
106cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    }
107cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    const SkRect& bounds1 = one.getBounds();
108cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    const SkRect& bounds2 = two.getBounds();
109cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    SkRect larger = bounds1;
110cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    larger.join(bounds2);
111cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    SkBitmap bits;
112752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com    char out[256];
113cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    int bitWidth = SkScalarCeil(larger.width()) + 2;
114752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com    if (bitWidth * 2 + 1 >= (int) sizeof(out)) {
115752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com        return false;
116752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com    }
117cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    int bitHeight = SkScalarCeil(larger.height()) + 2;
118752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com    if (bitHeight >= (int) sizeof(out)) {
119752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com        return false;
120752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com    }
121cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    bits.setConfig(SkBitmap::kARGB_8888_Config, bitWidth * 2, bitHeight);
122cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    bits.allocPixels();
123cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    SkCanvas canvas(bits);
124cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.drawColor(SK_ColorWHITE);
125cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    SkPaint paint;
126cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.save();
127cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.translate(-bounds1.fLeft + 1, -bounds1.fTop + 1);
128cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.drawPath(one, paint);
129cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.restore();
130cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.save();
131fb173424e915e696a73067d616ce4f39a407261acaryclark@google.com    canvas.translate(-bounds1.fLeft + 1 + bitWidth, -bounds1.fTop + 1);
132cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.drawPath(two, paint);
133cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.restore();
134cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    for (int y = 0; y < bitHeight; ++y) {
135cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        uint32_t* addr1 = bits.getAddr32(0, y);
136cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        int x;
137cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        char* outPtr = out;
138cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        for (x = 0; x < bitWidth; ++x) {
139cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com            *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x';
140cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        }
141cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        *outPtr++ = '|';
142cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        for (x = bitWidth; x < bitWidth * 2; ++x) {
143cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com            *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x';
144cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        }
145cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        *outPtr++ = '\0';
146cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        SkDebugf("%s\n", out);
147cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    }
148752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com    return true;
149cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com}
150cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com
151198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.comstatic int scaledDrawTheSame(const SkPath& one, const SkPath& two,
152198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        int a, int b, bool drawPaths, SkBitmap& bitmap, SkCanvas* canvas) {
153cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    SkMatrix scale;
154cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    scale.reset();
155752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com    float aScale = 1.21f;
156752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com    float bScale = 1.11f;
157752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com    scale.preScale(a * aScale, b * bScale);
158cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    SkPath scaledOne, scaledTwo;
159cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    one.transform(scale, &scaledOne);
160cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    two.transform(scale, &scaledTwo);
161198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    int errors = pathsDrawTheSame(scaledOne, scaledTwo, bitmap, canvas);
162198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    if (errors == 0) {
163198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        return 0;
164cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    }
165752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com    while (!drawAsciiPaths(scaledOne, scaledTwo, drawPaths)) {
166752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com        scale.reset();
167752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com        aScale *= 0.5f;
168752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com        bScale *= 0.5f;
169752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com        scale.preScale(a * aScale, b * bScale);
170752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com        one.transform(scale, &scaledOne);
171752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com        two.transform(scale, &scaledTwo);
172752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com    }
173198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    return errors;
174cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com}
175cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com
17678e17130f396d8b2157116c2504e357192f87ed1caryclark@google.comstatic int max = 0;
17778e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com
178198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.comstatic int comparePaths(const SkPath& one, const SkPath& two, SkBitmap& bitmap,
179198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        SkCanvas* canvas) {
180198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    int errors = pathsDrawTheSame(one, two, bitmap, canvas);
181198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    if (errors == 0) {
182198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        return 0;
183cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    }
184cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    drawAsciiPaths(one, two, gDrawAllAsciiPaths);
185cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    for (int x = 9; x <= 33; ++x) {
186198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        errors = scaledDrawTheSame(one, two, x, x - (x >> 2), gDrawAllAsciiPaths,
187198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com            bitmap, canvas);
188198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        if (errors == 0) {
189198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com            return 0;
190cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        }
191cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    }
192cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    if (!gDrawAllAsciiPaths) {
193fb173424e915e696a73067d616ce4f39a407261acaryclark@google.com        const SkRect& bounds1 = one.getBounds();
194fb173424e915e696a73067d616ce4f39a407261acaryclark@google.com        const SkRect& bounds2 = two.getBounds();
195fb173424e915e696a73067d616ce4f39a407261acaryclark@google.com        SkRect larger = bounds1;
196fb173424e915e696a73067d616ce4f39a407261acaryclark@google.com        larger.join(bounds2);
197fb173424e915e696a73067d616ce4f39a407261acaryclark@google.com        SkScalar xScale = std::max(80.0f / larger.width(), 1.0f);
198fb173424e915e696a73067d616ce4f39a407261acaryclark@google.com        SkScalar yScale = std::max(60.0f / larger.height(), 1.0f);
199fb173424e915e696a73067d616ce4f39a407261acaryclark@google.com        errors = scaledDrawTheSame(one, two, xScale, yScale, false, bitmap, canvas);
20078e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com        if (errors > 50) {
201fb173424e915e696a73067d616ce4f39a407261acaryclark@google.com            scaledDrawTheSame(one, two, xScale, yScale, true, bitmap, canvas);
202198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        }
203cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    }
20478e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com    if (errors > max) {
20578e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com        SkDebugf("\n%s errors=%d\n", __FUNCTION__, errors);
20678e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com        max = errors;
20778e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com    }
20878e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com    const int MAX_ERRORS = 100;
20978e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com    if (errors > MAX_ERRORS) SkDebugf("\n%s errors=%d\n", __FUNCTION__, errors);
21078e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com    if (errors > MAX_ERRORS && gComparePathsAssert) {
2112e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com        showPath(one);
2122e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com        showPath(two, "simplified:");
2132e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com        SkASSERT(0);
2142e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com    }
21578e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com    return errors > MAX_ERRORS ? errors : 0;
216cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com}
217cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com
218cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com// doesn't work yet
219cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.comvoid comparePathsTiny(const SkPath& one, const SkPath& two) {
220cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    const SkRect& bounds1 = one.getBounds();
221cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    const SkRect& bounds2 = two.getBounds();
222cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    SkRect larger = bounds1;
223cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    larger.join(bounds2);
224cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    SkBitmap bits;
225cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    int bitWidth = SkScalarCeil(larger.width()) + 2;
226cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    int bitHeight = SkScalarCeil(larger.height()) + 2;
227cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    bits.setConfig(SkBitmap::kA1_Config, bitWidth * 2, bitHeight);
228cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    bits.allocPixels();
229cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    SkCanvas canvas(bits);
230cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.drawColor(SK_ColorWHITE);
231cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    SkPaint paint;
232cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.save();
233cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.translate(-bounds1.fLeft + 1, -bounds1.fTop + 1);
234cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.drawPath(one, paint);
235cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.restore();
236cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.save();
237cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.translate(-bounds2.fLeft + 1, -bounds2.fTop + 1);
238cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.drawPath(two, paint);
239cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    canvas.restore();
240cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    for (int y = 0; y < bitHeight; ++y) {
241cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        uint8_t* addr1 = bits.getAddr1(0, y);
242cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        uint8_t* addr2 = bits.getAddr1(bitWidth, y);
243cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        for (int x = 0; x < bits.rowBytes(); ++x) {
244cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com            SkASSERT(addr1[x] == addr2[x]);
245cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com        }
246cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com    }
247cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com}
248cd4421df5012b75c792c6c8bf2c5ee0410921c15caryclark@google.com
249198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.combool testSimplify(const SkPath& path, bool fill, SkPath& out, SkBitmap& bitmap,
250198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com        SkCanvas* canvas) {
2512e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com    if (gShowPath) {
2522e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com        showPath(path);
2532e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com    }
2542e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com    simplify(path, fill, out);
255752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com    if (!gComparePaths) {
256752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com        return true;
257752b60e633a349c5b9f7bcc6a28b8064fc77bb41caryclark@google.com    }
258198e054b33051a6cd5f606ccbc8d539cefc5631fcaryclark@google.com    return comparePaths(path, out, bitmap, canvas) == 0;
2592e7f4c810dc717383df42d27bdba862514ab6d51caryclark@google.com}
26078e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com
26178e17130f396d8b2157116c2504e357192f87ed1caryclark@google.comState4::State4() {
26278e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com    bitmap.setConfig(SkBitmap::kARGB_8888_Config, 150 * 2, 100);
26378e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com    bitmap.allocPixels();
26478e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com    canvas = new SkCanvas(bitmap);
26578e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com}
26678e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com
26778e17130f396d8b2157116c2504e357192f87ed1caryclark@google.comvoid createThread(State4* statePtr, void* (*test)(void* )) {
26878e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com    int threadError = pthread_create(&statePtr->threadID, NULL, test,
26978e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com            (void*) statePtr);
27078e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com    SkASSERT(!threadError);
27178e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com}
27278e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com
27378e17130f396d8b2157116c2504e357192f87ed1caryclark@google.comvoid waitForCompletion(State4 threadState[], int& threadIndex) {
27478e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com    for (int index = 0; index < threadIndex; ++index) {
27578e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com        pthread_join(threadState[index].threadID, NULL);
27678e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com    }
27778e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com    SkDebugf(".");
27878e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com    threadIndex = 0;
27978e17130f396d8b2157116c2504e357192f87ed1caryclark@google.com}
280