OLD | NEW |
| (Empty) |
1 #include "EdgeDemo.h" | |
2 #include "EdgeWalker_Test.h" | |
3 #include "ShapeOps.h" | |
4 #import "SkCanvas.h" | |
5 #import "SkPaint.h" | |
6 | |
7 extern void showPath(const SkPath& path, const char* str); | |
8 | |
9 static bool drawPaths(SkCanvas* canvas, const SkPath& path, bool useOld) | |
10 { | |
11 SkPath out; | |
12 #define SHOW_PATH 0 | |
13 #if SHOW_PATH | |
14 showPath(path, "original:"); | |
15 #endif | |
16 if (useOld) { | |
17 simplify(path, true, out); | |
18 } else { | |
19 simplifyx(path, out); | |
20 } | |
21 #if SHOW_PATH | |
22 showPath(out, "simplified:"); | |
23 #endif | |
24 SkPaint paint; | |
25 paint.setAntiAlias(true); | |
26 paint.setStyle(SkPaint::kStroke_Style); | |
27 // paint.setStrokeWidth(6); | |
28 // paint.setColor(0x1F003f7f); | |
29 // canvas->drawPath(path, paint); | |
30 paint.setColor(0xFF305F00); | |
31 paint.setStrokeWidth(1); | |
32 canvas->drawPath(out, paint); | |
33 return true; | |
34 } | |
35 | |
36 // Three circles bounce inside a rectangle. The circles describe three, four | |
37 // or five points which in turn describe a polygon. The polygon points | |
38 // bounce inside the circles. The circles rotate and scale over time. The | |
39 // polygons are combined into a single path, simplified, and stroked. | |
40 static bool drawCircles(SkCanvas* canvas, int step, bool useOld) | |
41 { | |
42 const int circles = 3; | |
43 int scales[circles]; | |
44 int angles[circles]; | |
45 int locs[circles * 2]; | |
46 int pts[circles * 2 * 4]; | |
47 int c, p; | |
48 for (c = 0; c < circles; ++c) { | |
49 scales[c] = abs(10 - (step + c * 4) % 21); | |
50 angles[c] = (step + c * 6) % 600; | |
51 locs[c * 2] = abs(130 - (step + c * 9) % 261); | |
52 locs[c * 2 + 1] = abs(170 - (step + c * 11) % 341); | |
53 for (p = 0; p < 4; ++p) { | |
54 pts[c * 8 + p * 2] = abs(90 - ((step + c * 121 + p * 13) % 190)); | |
55 pts[c * 8 + p * 2 + 1] = abs(110 - ((step + c * 223 + p * 17) % 230)
); | |
56 } | |
57 } | |
58 SkPath path; | |
59 for (c = 0; c < circles; ++c) { | |
60 for (p = 0; p < 4; ++p) { | |
61 SkScalar x = pts[c * 8 + p * 2]; | |
62 SkScalar y = pts[c * 8 + p * 2 + 1]; | |
63 x *= 3 + scales[c] / 10.0f; | |
64 y *= 3 + scales[c] / 10.0f; | |
65 SkScalar angle = angles[c] * 3.1415f * 2 / 600; | |
66 SkScalar temp = (SkScalar) (x * cos(angle) - y * sin(angle)); | |
67 y = (SkScalar) (x * sin(angle) + y * cos(angle)); | |
68 x = temp; | |
69 x += locs[c * 2] * 200 / 130.0f; | |
70 y += locs[c * 2 + 1] * 200 / 170.0f; | |
71 x += 50; | |
72 // y += 200; | |
73 if (p == 0) { | |
74 path.moveTo(x, y); | |
75 } else { | |
76 path.lineTo(x, y); | |
77 } | |
78 } | |
79 path.close(); | |
80 } | |
81 return drawPaths(canvas, path, useOld); | |
82 } | |
83 | |
84 static void createStar(SkPath& path, SkScalar innerRadius, SkScalar outerRadius, | |
85 SkScalar startAngle, int points, SkPoint center) { | |
86 SkScalar angle = startAngle; | |
87 for (int index = 0; index < points * 2; ++index) { | |
88 SkScalar radius = index & 1 ? outerRadius : innerRadius; | |
89 SkScalar x = (SkScalar) (radius * cos(angle)); | |
90 SkScalar y = (SkScalar) (radius * sin(angle)); | |
91 x += center.fX; | |
92 y += center.fY; | |
93 if (index == 0) { | |
94 path.moveTo(x, y); | |
95 } else { | |
96 path.lineTo(x, y); | |
97 } | |
98 angle += 3.1415f / points; | |
99 } | |
100 path.close(); | |
101 } | |
102 | |
103 static bool drawStars(SkCanvas* canvas, int step, bool useOld) | |
104 { | |
105 SkPath path; | |
106 const int stars = 25; | |
107 int pts[stars]; | |
108 // static bool initialize = true; | |
109 int s; | |
110 for (s = 0; s < stars; ++s) { | |
111 pts[s] = 4 + (s % 7); | |
112 } | |
113 SkPoint locs[stars]; | |
114 SkScalar angles[stars]; | |
115 SkScalar innerRadius[stars]; | |
116 SkScalar outerRadius[stars]; | |
117 const int width = 640; | |
118 const int height = 480; | |
119 const int margin = 30; | |
120 const int minRadius = 120; | |
121 const int maxInner = 800; | |
122 const int maxOuter = 1153; | |
123 for (s = 0; s < stars; ++s) { | |
124 int starW = (int) (width - margin * 2 + (SkScalar) s * (stars - s) / sta
rs); | |
125 locs[s].fX = (int) (step * (1.3f * (s + 1) / stars) + s * 121) % (starW
* 2); | |
126 if (locs[s].fX > starW) { | |
127 locs[s].fX = starW * 2 - locs[s].fX; | |
128 } | |
129 locs[s].fX += margin; | |
130 int starH = (int) (height - margin * 2 + (SkScalar) s * s / stars); | |
131 locs[s].fY = (int) (step * (1.7f * (s + 1) / stars) + s * 183) % (starH
* 2); | |
132 if (locs[s].fY > starH) { | |
133 locs[s].fY = starH * 2 - locs[s].fY; | |
134 } | |
135 locs[s].fY += margin; | |
136 angles[s] = ((step + s * 47) % (360 * 4)) * 3.1415f / 180 / 4; | |
137 innerRadius[s] = (step + s * 30) % (maxInner * 2); | |
138 if (innerRadius[s] > maxInner) { | |
139 innerRadius[s] = (maxInner * 2) - innerRadius[s]; | |
140 } | |
141 innerRadius[s] = innerRadius[s] / 4 + minRadius; | |
142 outerRadius[s] = (step + s * 70) % (maxOuter * 2); | |
143 if (outerRadius[s] > maxOuter) { | |
144 outerRadius[s] = (maxOuter * 2) - outerRadius[s]; | |
145 } | |
146 outerRadius[s] = outerRadius[s] / 4 + minRadius; | |
147 createStar(path, innerRadius[s] / 4.0f, outerRadius[s] / 4.0f, | |
148 angles[s], pts[s], locs[s]); | |
149 } | |
150 return drawPaths(canvas, path, useOld); | |
151 } | |
152 | |
153 #if 0 | |
154 static void tryRoncoOnce(const SkPath& path, const SkRect& target, bool show) { | |
155 // capture everything in a desired rectangle | |
156 SkPath tiny; | |
157 bool closed = true; | |
158 SkPath::Iter iter(path, false); | |
159 SkPoint pts[4]; | |
160 SkPath::Verb verb; | |
161 int count = 0; | |
162 SkPoint lastPt; | |
163 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { | |
164 switch (verb) { | |
165 case SkPath::kMove_Verb: | |
166 count = 0; | |
167 break; | |
168 case SkPath::kLine_Verb: | |
169 count = 1; | |
170 break; | |
171 case SkPath::kQuad_Verb: | |
172 count = 2; | |
173 break; | |
174 case SkPath::kCubic_Verb: | |
175 count = 3; | |
176 break; | |
177 case SkPath::kClose_Verb: | |
178 if (!closed) { | |
179 tiny.close(); | |
180 closed = true; | |
181 } | |
182 count = 0; | |
183 break; | |
184 default: | |
185 SkDEBUGFAIL("bad verb"); | |
186 } | |
187 if (!count) { | |
188 continue; | |
189 } | |
190 SkRect bounds; | |
191 bounds.set(pts[0].fX, pts[0].fY, pts[0].fX, pts[0].fY); | |
192 for (int i = 1; i <= count; ++i) { | |
193 bounds.growToInclude(pts[i].fX + 0.1f, pts[i].fY + 0.1f); | |
194 } | |
195 if (!SkRect::Intersects(target, bounds)) { | |
196 continue; | |
197 } | |
198 if (closed) { | |
199 tiny.moveTo(pts[0].fX, pts[0].fY); | |
200 closed = false; | |
201 } else if (pts[0] != lastPt) { | |
202 tiny.lineTo(pts[0].fX, pts[0].fY); | |
203 } | |
204 switch (verb) { | |
205 case SkPath::kLine_Verb: | |
206 tiny.lineTo(pts[1].fX, pts[1].fY); | |
207 lastPt = pts[1]; | |
208 break; | |
209 case SkPath::kQuad_Verb: | |
210 tiny.quadTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY); | |
211 lastPt = pts[2]; | |
212 break; | |
213 case SkPath::kCubic_Verb: | |
214 tiny.cubicTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY, pts[3].
fX, pts[3].fY); | |
215 lastPt = pts[3]; | |
216 break; | |
217 default: | |
218 SkDEBUGFAIL("bad verb"); | |
219 } | |
220 } | |
221 if (!closed) { | |
222 tiny.close(); | |
223 } | |
224 if (show) { | |
225 showPath(tiny, NULL); | |
226 SkDebugf("simplified:\n"); | |
227 } | |
228 testSimplifyx(tiny); | |
229 } | |
230 #endif | |
231 | |
232 #if 0 | |
233 static void tryRonco(const SkPath& path) { | |
234 int divMax = 64; | |
235 int divMin = 1; | |
236 int xDivMin = 0; | |
237 int yDivMin = 0; | |
238 bool allYs = true; | |
239 bool allXs = true; | |
240 if (1) { | |
241 divMax = divMin = 64; | |
242 xDivMin = 11; | |
243 yDivMin = 0; | |
244 allXs = true; | |
245 allYs = true; | |
246 } | |
247 for (int divs = divMax; divs >= divMin; divs /= 2) { | |
248 SkDebugf("divs=%d\n",divs); | |
249 const SkRect& overall = path.getBounds(); | |
250 SkScalar cellWidth = overall.width() / divs * 2; | |
251 SkScalar cellHeight = overall.height() / divs * 2; | |
252 SkRect target; | |
253 int xDivMax = divMax == divMin && !allXs ? xDivMin + 1 : divs; | |
254 int yDivMax = divMax == divMin && !allYs ? yDivMin + 1 : divs; | |
255 for (int xDiv = xDivMin; xDiv < xDivMax; ++xDiv) { | |
256 SkDebugf("xDiv=%d\n",xDiv); | |
257 for (int yDiv = yDivMin; yDiv < yDivMax; ++yDiv) { | |
258 SkDebugf("yDiv=%d\n",yDiv); | |
259 target.setXYWH(overall.fLeft + (overall.width() - cellWidth) * x
Div / divs, | |
260 overall.fTop + (overall.height() - cellHeight) * yDiv /
divs, | |
261 cellWidth, cellHeight); | |
262 tryRoncoOnce(path, target, divMax == divMin); | |
263 } | |
264 } | |
265 } | |
266 } | |
267 #endif | |
268 | |
269 static bool drawLetters(SkCanvas* canvas, int step, bool useOld) | |
270 { | |
271 SkPath path; | |
272 const int width = 640; | |
273 const int height = 480; | |
274 const char testStr[] = "Merge"; | |
275 const int testStrLen = sizeof(testStr) - 1; | |
276 SkPoint textPos[testStrLen]; | |
277 SkScalar widths[testStrLen]; | |
278 SkPaint paint; | |
279 paint.setTextSize(40); | |
280 paint.setAntiAlias(true); | |
281 paint.getTextWidths(testStr, testStrLen, widths, NULL); | |
282 SkScalar running = 0; | |
283 for (int x = 0; x < testStrLen; ++x) { | |
284 SkScalar width = widths[x]; | |
285 widths[x] = running; | |
286 running += width; | |
287 } | |
288 SkScalar bias = (width - widths[testStrLen - 1]) / 2; | |
289 for (int x = 0; x < testStrLen; ++x) { | |
290 textPos[x].fX = bias + widths[x]; | |
291 textPos[x].fY = height / 2; | |
292 } | |
293 paint.setTextSize(40 + step / 100.0f); | |
294 #if 0 | |
295 bool oneShot = false; | |
296 for (int mask = 0; mask < 1 << testStrLen; ++mask) { | |
297 char maskStr[testStrLen]; | |
298 #if 1 | |
299 mask = 12; | |
300 oneShot = true; | |
301 #endif | |
302 SkDebugf("mask=%d\n", mask); | |
303 for (int letter = 0; letter < testStrLen; ++letter) { | |
304 maskStr[letter] = mask & (1 << letter) ? testStr[letter] : ' '; | |
305 } | |
306 paint.getPosTextPath(maskStr, testStrLen, textPos, &path); | |
307 // showPath(path, NULL); | |
308 // SkDebugf("%d simplified:\n", mask); | |
309 tryRonco(path); | |
310 // testSimplifyx(path); | |
311 if (oneShot) { | |
312 break; | |
313 } | |
314 } | |
315 #endif | |
316 paint.getPosTextPath(testStr, testStrLen, textPos, &path); | |
317 #if 0 | |
318 tryRonco(path); | |
319 SkDebugf("RoncoDone!\n"); | |
320 #endif | |
321 #if 0 | |
322 showPath(path, NULL); | |
323 SkDebugf("simplified:\n"); | |
324 #endif | |
325 return drawPaths(canvas, path, false); | |
326 } | |
327 | |
328 static bool (*drawDemos[])(SkCanvas* , int , bool ) = { | |
329 drawStars, | |
330 drawCircles, | |
331 drawLetters, | |
332 }; | |
333 | |
334 static size_t drawDemosCount = sizeof(drawDemos) / sizeof(drawDemos[0]); | |
335 | |
336 static bool (*firstTest)(SkCanvas* , int , bool) = drawStars; | |
337 | |
338 | |
339 bool DrawEdgeDemo(SkCanvas* canvas, int step, bool useOld) { | |
340 size_t index = 0; | |
341 if (firstTest) { | |
342 while (index < drawDemosCount && drawDemos[index] != firstTest) { | |
343 ++index; | |
344 } | |
345 } | |
346 return (*drawDemos[index])(canvas, step, useOld); | |
347 } | |
OLD | NEW |