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