• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
drawPaths(SkCanvas * canvas,const SkPath & path,bool useOld)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.
drawCircles(SkCanvas * canvas,int step,bool useOld)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 
createStar(SkPath & path,SkScalar innerRadius,SkScalar outerRadius,SkScalar startAngle,int points,SkPoint center)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 
drawStars(SkCanvas * canvas,int step,bool useOld)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) / stars);
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) * xDiv / 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 
drawLetters(SkCanvas * canvas,int step,bool useOld)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 
DrawEdgeDemo(SkCanvas * canvas,int step,bool useOld)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 }
348