1/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7#include "PathOpsExtendedTest.h"
8#include "PathOpsThreadedCommon.h"
9#include "SkString.h"
10
11// four rects, of four sizes
12// for 3 smaller sizes, tall, wide
13    // top upper mid lower bottom aligned (3 bits, 5 values)
14    // same with x (3 bits, 5 values)
15// not included, square, tall, wide (2 bits)
16// cw or ccw (1 bit)
17
18static void testSimplify4x4RectsMain(PathOpsThreadState* data)
19{
20    SkASSERT(data);
21    PathOpsThreadState& state = *data;
22    int aShape = state.fA & 0x03;
23    SkPath::Direction aCW = state.fA >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
24    int bShape = state.fB & 0x03;
25    SkPath::Direction bCW = state.fB >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
26    int cShape = state.fC & 0x03;
27    SkPath::Direction cCW = state.fC >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
28    int dShape = state.fD & 0x03;
29    SkPath::Direction dCW = state.fD >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
30    for (int aXAlign = 0; aXAlign < 5; ++aXAlign) {
31        for (int aYAlign = 0; aYAlign < 5; ++aYAlign) {
32            for (int bXAlign = 0; bXAlign < 5; ++bXAlign) {
33                for (int bYAlign = 0; bYAlign < 5; ++bYAlign) {
34                    for (int cXAlign = 0; cXAlign < 5; ++cXAlign) {
35                         for (int cYAlign = 0; cYAlign < 5; ++cYAlign) {
36                            for (int dXAlign = 0; dXAlign < 5; ++dXAlign) {
37    for (int dYAlign = 0; dYAlign < 5; ++dYAlign) {
38        SkString pathStr;
39        SkPath path, out;
40        path.setFillType(SkPath::kWinding_FillType);
41        int l SK_INIT_TO_AVOID_WARNING, t SK_INIT_TO_AVOID_WARNING,
42            r SK_INIT_TO_AVOID_WARNING, b SK_INIT_TO_AVOID_WARNING;
43        if (aShape) {
44            switch (aShape) {
45                case 1:  // square
46                    l =  0; r = 60;
47                    t =  0; b = 60;
48                    aXAlign = 5;
49                    aYAlign = 5;
50                    break;
51                case 2:
52                    l =  aXAlign * 12;
53                    r =  l + 30;
54                    t =  0; b = 60;
55                    aYAlign = 5;
56                    break;
57                case 3:
58                    l =  0; r = 60;
59                    t =  aYAlign * 12;
60                    b =  l + 30;
61                    aXAlign = 5;
62                    break;
63            }
64            path.addRect(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
65                    aCW);
66            if (state.fReporter->verbose()) {
67                pathStr.appendf("    path.addRect(%d, %d, %d, %d,"
68                        " SkPath::kC%sW_Direction);\n", l, t, r, b, aCW ? "C" : "");
69            }
70        } else {
71            aXAlign = 5;
72            aYAlign = 5;
73        }
74        if (bShape) {
75            switch (bShape) {
76                case 1:  // square
77                    l =  bXAlign * 10;
78                    r =  l + 20;
79                    t =  bYAlign * 10;
80                    b =  l + 20;
81                    break;
82                case 2:
83                    l =  bXAlign * 10;
84                    r =  l + 20;
85                    t =  10; b = 40;
86                    bYAlign = 5;
87                    break;
88                case 3:
89                    l =  10; r = 40;
90                    t =  bYAlign * 10;
91                    b =  l + 20;
92                    bXAlign = 5;
93                    break;
94            }
95            path.addRect(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
96                    bCW);
97            if (state.fReporter->verbose()) {
98                pathStr.appendf("    path.addRect(%d, %d, %d, %d,"
99                        " SkPath::kC%sW_Direction);\n", l, t, r, b, bCW ? "C" : "");
100            }
101        } else {
102            bXAlign = 5;
103            bYAlign = 5;
104        }
105        if (cShape) {
106            switch (cShape) {
107                case 1:  // square
108                    l =  cXAlign * 6;
109                    r =  l + 12;
110                    t =  cYAlign * 6;
111                    b =  l + 12;
112                    break;
113                case 2:
114                    l =  cXAlign * 6;
115                    r =  l + 12;
116                    t =  20; b = 30;
117                    cYAlign = 5;
118                    break;
119                case 3:
120                    l =  20; r = 30;
121                    t =  cYAlign * 6;
122                    b =  l + 20;
123                    cXAlign = 5;
124                    break;
125            }
126            path.addRect(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
127                    cCW);
128            if (state.fReporter->verbose()) {
129                pathStr.appendf("    path.addRect(%d, %d, %d, %d,"
130                        " SkPath::kC%sW_Direction);\n", l, t, r, b, cCW ? "C" : "");
131            }
132        } else {
133            cXAlign = 5;
134            cYAlign = 5;
135        }
136        if (dShape) {
137            switch (dShape) {
138                case 1:  // square
139                    l =  dXAlign * 4;
140                    r =  l + 9;
141                    t =  dYAlign * 4;
142                    b =  l + 9;
143                    break;
144                case 2:
145                    l =  dXAlign * 6;
146                    r =  l + 9;
147                    t =  32; b = 36;
148                    dYAlign = 5;
149                    break;
150                case 3:
151                    l =  32; r = 36;
152                    t =  dYAlign * 6;
153                    b =  l + 9;
154                    dXAlign = 5;
155                    break;
156            }
157            path.addRect(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
158                    dCW);
159            if (state.fReporter->verbose()) {
160                pathStr.appendf("    path.addRect(%d, %d, %d, %d,"
161                        " SkPath::kC%sW_Direction);\n", l, t, r, b, dCW ? "C" : "");
162            }
163        } else {
164            dXAlign = 5;
165            dYAlign = 5;
166        }
167        path.close();
168        if (state.fReporter->verbose()) {
169            state.outputProgress(pathStr.c_str(), SkPath::kWinding_FillType);
170        }
171        testSimplify(path, false, out, state, pathStr.c_str());
172        if (state.fReporter->verbose()) {
173            state.outputProgress(pathStr.c_str(), SkPath::kEvenOdd_FillType);
174        }
175        testSimplify(path, true, out, state, pathStr.c_str());
176    }
177                            }
178                        }
179                    }
180                }
181            }
182        }
183    }
184}
185
186DEF_TEST(PathOpsSimplifyRectsThreaded, reporter) {
187    initializeTests(reporter, "testLine");
188    PathOpsThreadedTestRunner testRunner(reporter);
189    for (int a = 0; a < 8; ++a) {  // outermost
190        for (int b = a ; b < 8; ++b) {
191            for (int c = b ; c < 8; ++c) {
192                for (int d = c; d < 8; ++d) {
193                    *testRunner.fRunnables.append() = new PathOpsThreadedRunnable(
194                            &testSimplify4x4RectsMain, a, b, c, d, &testRunner);
195                }
196                if (!reporter->allowExtendedTest()) goto finish;
197            }
198        }
199    }
200finish:
201    testRunner.render();
202}
203