Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / gm / cubicpaths.cpp
1 /*
2  * Copyright 2011 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 "gm.h"
8 #include "SkCanvas.h"
9 #include "SkPaint.h"
10 #include "SkRandom.h"
11
12 // skbug.com/1316 shows that this cubic, when slightly clipped, creates big
13 // (incorrect) changes to its control points.
14 class ClippedCubicGM : public skiagm::GM {
15 public:
16     ClippedCubicGM() {}
17
18 protected:
19     virtual uint32_t onGetFlags() const SK_OVERRIDE {
20         return kSkipTiled_Flag;
21     }
22
23     SkString onShortName() {
24         return SkString("clippedcubic");
25     }
26
27     SkISize onISize() { return SkISize::Make(1240, 390); }
28
29     virtual void onDraw(SkCanvas* canvas) {
30         SkPath path;
31         path.moveTo(0, 0);
32         path.cubicTo(140, 150, 40, 10, 170, 150);
33
34         SkPaint paint;
35         SkRect bounds = path.getBounds();
36
37         for (SkScalar dy = -1; dy <= 1; dy += 1) {
38             canvas->save();
39             for (SkScalar dx = -1; dx <= 1; dx += 1) {
40                 canvas->save();
41                 canvas->clipRect(bounds);
42                 canvas->translate(dx, dy);
43                 canvas->drawPath(path, paint);
44                 canvas->restore();
45
46                 canvas->translate(bounds.width(), 0);
47             }
48             canvas->restore();
49             canvas->translate(0, bounds.height());
50         }
51     }
52
53 private:
54     typedef skiagm::GM INHERITED;
55 };
56
57 class CubicPathGM : public skiagm::GM {
58 public:
59     CubicPathGM() {}
60
61 protected:
62     virtual uint32_t onGetFlags() const SK_OVERRIDE {
63         return kSkipTiled_Flag;
64     }
65
66     SkString onShortName() {
67         return SkString("cubicpath");
68     }
69
70     SkISize onISize() { return SkISize::Make(1240, 390); }
71
72     void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
73                   const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
74                   SkPaint::Style style, SkPath::FillType fill,
75                   SkScalar strokeWidth) {
76         path.setFillType(fill);
77         SkPaint paint;
78         paint.setStrokeCap(cap);
79         paint.setStrokeWidth(strokeWidth);
80         paint.setStrokeJoin(join);
81         paint.setColor(color);
82         paint.setStyle(style);
83         canvas->save();
84         canvas->clipRect(clip);
85         canvas->drawPath(path, paint);
86         canvas->restore();
87     }
88
89     virtual void onDraw(SkCanvas* canvas) {
90         struct FillAndName {
91             SkPath::FillType fFill;
92             const char*      fName;
93         };
94         static const FillAndName gFills[] = {
95             {SkPath::kWinding_FillType, "Winding"},
96             {SkPath::kEvenOdd_FillType, "Even / Odd"},
97             {SkPath::kInverseWinding_FillType, "Inverse Winding"},
98             {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
99         };
100         struct StyleAndName {
101             SkPaint::Style fStyle;
102             const char*    fName;
103         };
104         static const StyleAndName gStyles[] = {
105             {SkPaint::kFill_Style, "Fill"},
106             {SkPaint::kStroke_Style, "Stroke"},
107             {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
108         };
109         struct CapAndName {
110             SkPaint::Cap  fCap;
111             SkPaint::Join fJoin;
112             const char*   fName;
113         };
114         static const CapAndName gCaps[] = {
115             {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
116             {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
117             {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
118         };
119         struct PathAndName {
120             SkPath      fPath;
121             const char* fName;
122         };
123         PathAndName path;
124         path.fPath.moveTo(25*SK_Scalar1, 10*SK_Scalar1);
125         path.fPath.cubicTo(40*SK_Scalar1, 20*SK_Scalar1,
126                            60*SK_Scalar1, 20*SK_Scalar1,
127                            75*SK_Scalar1, 10*SK_Scalar1);
128         path.fName = "moveTo-cubic";
129
130         SkPaint titlePaint;
131         titlePaint.setColor(SK_ColorBLACK);
132         titlePaint.setAntiAlias(true);
133         sk_tool_utils::set_portable_typeface(&titlePaint);
134         titlePaint.setLCDRenderText(true);
135         titlePaint.setTextSize(15 * SK_Scalar1);
136         const char title[] = "Cubic Drawn Into Rectangle Clips With "
137                              "Indicated Style, Fill and Linecaps, with stroke width 10";
138         canvas->drawText(title, strlen(title),
139                             20 * SK_Scalar1,
140                             20 * SK_Scalar1,
141                             titlePaint);
142
143         SkLCGRandom rand;
144         SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
145         canvas->save();
146         canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
147         canvas->save();
148         for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
149             if (0 < cap) {
150                 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
151             }
152             canvas->save();
153             for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
154                 if (0 < fill) {
155                     canvas->translate(0, rect.height() + 40 * SK_Scalar1);
156                 }
157                 canvas->save();
158                 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
159                     if (0 < style) {
160                         canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
161                     }
162
163                     SkColor color = 0xff007000;
164                     this->drawPath(path.fPath, canvas, color, rect,
165                                     gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
166                                     gFills[fill].fFill, SK_Scalar1*10);
167
168                     SkPaint rectPaint;
169                     rectPaint.setColor(SK_ColorBLACK);
170                     rectPaint.setStyle(SkPaint::kStroke_Style);
171                     rectPaint.setStrokeWidth(-1);
172                     rectPaint.setAntiAlias(true);
173                     canvas->drawRect(rect, rectPaint);
174
175                     SkPaint labelPaint;
176                     labelPaint.setColor(color);
177                     labelPaint.setAntiAlias(true);
178                     sk_tool_utils::set_portable_typeface(&labelPaint);
179                     labelPaint.setLCDRenderText(true);
180                     labelPaint.setTextSize(10 * SK_Scalar1);
181                     canvas->drawText(gStyles[style].fName,
182                                         strlen(gStyles[style].fName),
183                                         0, rect.height() + 12 * SK_Scalar1,
184                                         labelPaint);
185                     canvas->drawText(gFills[fill].fName,
186                                         strlen(gFills[fill].fName),
187                                         0, rect.height() + 24 * SK_Scalar1,
188                                         labelPaint);
189                     canvas->drawText(gCaps[cap].fName,
190                                         strlen(gCaps[cap].fName),
191                                         0, rect.height() + 36 * SK_Scalar1,
192                                         labelPaint);
193                 }
194                 canvas->restore();
195             }
196             canvas->restore();
197         }
198         canvas->restore();
199         canvas->restore();
200     }
201
202 private:
203     typedef skiagm::GM INHERITED;
204 };
205
206 class CubicClosePathGM : public skiagm::GM {
207 public:
208     CubicClosePathGM() {}
209
210 protected:
211     virtual uint32_t onGetFlags() const SK_OVERRIDE {
212         return kSkipTiled_Flag;
213     }
214
215     SkString onShortName() {
216         return SkString("cubicclosepath");
217     }
218
219     SkISize onISize() { return SkISize::Make(1240, 390); }
220
221     void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
222                   const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
223                   SkPaint::Style style, SkPath::FillType fill,
224                   SkScalar strokeWidth) {
225         path.setFillType(fill);
226         SkPaint paint;
227         paint.setStrokeCap(cap);
228         paint.setStrokeWidth(strokeWidth);
229         paint.setStrokeJoin(join);
230         paint.setColor(color);
231         paint.setStyle(style);
232         canvas->save();
233         canvas->clipRect(clip);
234         canvas->drawPath(path, paint);
235         canvas->restore();
236     }
237
238     virtual void onDraw(SkCanvas* canvas) {
239         struct FillAndName {
240             SkPath::FillType fFill;
241             const char*      fName;
242         };
243         static const FillAndName gFills[] = {
244             {SkPath::kWinding_FillType, "Winding"},
245             {SkPath::kEvenOdd_FillType, "Even / Odd"},
246             {SkPath::kInverseWinding_FillType, "Inverse Winding"},
247             {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
248         };
249         struct StyleAndName {
250             SkPaint::Style fStyle;
251             const char*    fName;
252         };
253         static const StyleAndName gStyles[] = {
254             {SkPaint::kFill_Style, "Fill"},
255             {SkPaint::kStroke_Style, "Stroke"},
256             {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
257         };
258         struct CapAndName {
259             SkPaint::Cap  fCap;
260             SkPaint::Join fJoin;
261             const char*   fName;
262         };
263         static const CapAndName gCaps[] = {
264             {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
265             {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
266             {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
267         };
268         struct PathAndName {
269             SkPath      fPath;
270             const char* fName;
271         };
272         PathAndName path;
273         path.fPath.moveTo(25*SK_Scalar1, 10*SK_Scalar1);
274         path.fPath.cubicTo(40*SK_Scalar1, 20*SK_Scalar1,
275                            60*SK_Scalar1, 20*SK_Scalar1,
276                            75*SK_Scalar1, 10*SK_Scalar1);
277         path.fPath.close();
278         path.fName = "moveTo-cubic-close";
279
280         SkPaint titlePaint;
281         titlePaint.setColor(SK_ColorBLACK);
282         titlePaint.setAntiAlias(true);
283         sk_tool_utils::set_portable_typeface(&titlePaint);
284         titlePaint.setLCDRenderText(true);
285         titlePaint.setTextSize(15 * SK_Scalar1);
286         const char title[] = "Cubic Closed Drawn Into Rectangle Clips With "
287                              "Indicated Style, Fill and Linecaps, with stroke width 10";
288         canvas->drawText(title, strlen(title),
289                             20 * SK_Scalar1,
290                             20 * SK_Scalar1,
291                             titlePaint);
292
293         SkLCGRandom rand;
294         SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
295         canvas->save();
296         canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
297         canvas->save();
298         for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
299             if (0 < cap) {
300                 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
301             }
302             canvas->save();
303             for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
304                 if (0 < fill) {
305                     canvas->translate(0, rect.height() + 40 * SK_Scalar1);
306                 }
307                 canvas->save();
308                 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
309                     if (0 < style) {
310                         canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
311                     }
312
313                     SkColor color = 0xff007000;
314                     this->drawPath(path.fPath, canvas, color, rect,
315                                     gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
316                                     gFills[fill].fFill, SK_Scalar1*10);
317
318                     SkPaint rectPaint;
319                     rectPaint.setColor(SK_ColorBLACK);
320                     rectPaint.setStyle(SkPaint::kStroke_Style);
321                     rectPaint.setStrokeWidth(-1);
322                     rectPaint.setAntiAlias(true);
323                     canvas->drawRect(rect, rectPaint);
324
325                     SkPaint labelPaint;
326                     labelPaint.setColor(color);
327                     labelPaint.setAntiAlias(true);
328                     sk_tool_utils::set_portable_typeface(&labelPaint);
329                     labelPaint.setLCDRenderText(true);
330                     labelPaint.setTextSize(10 * SK_Scalar1);
331                     canvas->drawText(gStyles[style].fName,
332                                         strlen(gStyles[style].fName),
333                                         0, rect.height() + 12 * SK_Scalar1,
334                                         labelPaint);
335                     canvas->drawText(gFills[fill].fName,
336                                         strlen(gFills[fill].fName),
337                                         0, rect.height() + 24 * SK_Scalar1,
338                                         labelPaint);
339                     canvas->drawText(gCaps[cap].fName,
340                                         strlen(gCaps[cap].fName),
341                                         0, rect.height() + 36 * SK_Scalar1,
342                                         labelPaint);
343                 }
344                 canvas->restore();
345             }
346             canvas->restore();
347         }
348         canvas->restore();
349         canvas->restore();
350     }
351
352 private:
353     typedef skiagm::GM INHERITED;
354 };
355
356 //////////////////////////////////////////////////////////////////////////////
357
358 DEF_GM( return new CubicPathGM; )
359 DEF_GM( return new CubicClosePathGM; )
360 DEF_GM( return new ClippedCubicGM; )