• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
8 #include "gm/gm.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkColor.h"
11 #include "include/core/SkFont.h"
12 #include "include/core/SkPaint.h"
13 #include "include/core/SkPath.h"
14 #include "include/core/SkRect.h"
15 #include "include/core/SkScalar.h"
16 #include "include/core/SkSize.h"
17 #include "include/core/SkString.h"
18 #include "include/core/SkTypeface.h"
19 #include "include/core/SkTypes.h"
20 #include "src/base/SkRandom.h"
21 #include "tools/ToolUtils.h"
22 
23 namespace skiagm {
24 
25 class QuadPathGM : public GM {
26 public:
QuadPathGM()27     QuadPathGM() {}
28 
29 protected:
30 
onShortName()31     SkString onShortName() override {
32         return SkString("quadpath");
33     }
34 
onISize()35     SkISize onISize() override { return SkISize::Make(1240, 390); }
36 
drawPath(SkPath & path,SkCanvas * canvas,SkColor color,const SkRect & clip,SkPaint::Cap cap,SkPaint::Join join,SkPaint::Style style,SkPathFillType fill,SkScalar strokeWidth)37     void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
38                   const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
39                   SkPaint::Style style, SkPathFillType fill,
40                   SkScalar strokeWidth) {
41         path.setFillType(fill);
42         SkPaint paint;
43         paint.setStrokeCap(cap);
44         paint.setStrokeWidth(strokeWidth);
45         paint.setStrokeJoin(join);
46         paint.setColor(color);
47         paint.setStyle(style);
48         canvas->save();
49         canvas->clipRect(clip);
50         canvas->drawPath(path, paint);
51         canvas->restore();
52     }
53 
onDraw(SkCanvas * canvas)54     void onDraw(SkCanvas* canvas) override {
55         struct FillAndName {
56             SkPathFillType fFill;
57             const char*      fName;
58         };
59         constexpr FillAndName gFills[] = {
60             {SkPathFillType::kWinding, "Winding"},
61             {SkPathFillType::kEvenOdd, "Even / Odd"},
62             {SkPathFillType::kInverseWinding, "Inverse Winding"},
63             {SkPathFillType::kInverseEvenOdd, "Inverse Even / Odd"},
64         };
65         struct StyleAndName {
66             SkPaint::Style fStyle;
67             const char*    fName;
68         };
69         constexpr StyleAndName gStyles[] = {
70             {SkPaint::kFill_Style, "Fill"},
71             {SkPaint::kStroke_Style, "Stroke"},
72             {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
73         };
74         struct CapAndName {
75             SkPaint::Cap  fCap;
76             SkPaint::Join fJoin;
77             const char*   fName;
78         };
79         constexpr CapAndName gCaps[] = {
80             {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
81             {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
82             {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
83         };
84         struct PathAndName {
85             SkPath      fPath;
86             const char* fName;
87         };
88         PathAndName path;
89         path.fPath.moveTo(25*SK_Scalar1, 10*SK_Scalar1);
90         path.fPath.quadTo(50*SK_Scalar1, 20*SK_Scalar1,
91                           75*SK_Scalar1, 10*SK_Scalar1);
92         path.fName = "moveTo-quad";
93 
94         SkPaint titlePaint;
95         SkFont  font(ToolUtils::create_portable_typeface(), 15);
96         SkFont  labelFont(ToolUtils::create_portable_typeface(), 10);
97 
98         const char title[] = "Quad Drawn Into Rectangle Clips With "
99                              "Indicated Style, Fill and Linecaps, with stroke width 10";
100         canvas->drawString(title, 20.0f, 20.0f, font, titlePaint);
101 
102         SkRandom rand;
103         SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
104         canvas->save();
105         canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
106         canvas->save();
107         for (size_t cap = 0; cap < std::size(gCaps); ++cap) {
108             if (0 < cap) {
109                 canvas->translate((rect.width() + 40 * SK_Scalar1) * std::size(gStyles), 0);
110             }
111             canvas->save();
112             for (size_t fill = 0; fill < std::size(gFills); ++fill) {
113                 if (0 < fill) {
114                     canvas->translate(0, rect.height() + 40 * SK_Scalar1);
115                 }
116                 canvas->save();
117                 for (size_t style = 0; style < std::size(gStyles); ++style) {
118                     if (0 < style) {
119                         canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
120                     }
121 
122                     SkColor color = ToolUtils::color_to_565(0xff007000);
123                     this->drawPath(path.fPath, canvas, color, rect,
124                                     gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
125                                     gFills[fill].fFill, SK_Scalar1*10);
126 
127                     SkPaint rectPaint;
128                     rectPaint.setColor(SK_ColorBLACK);
129                     rectPaint.setStyle(SkPaint::kStroke_Style);
130                     rectPaint.setStrokeWidth(-1);
131                     rectPaint.setAntiAlias(true);
132                     canvas->drawRect(rect, rectPaint);
133 
134                     SkPaint labelPaint;
135                     labelPaint.setColor(color);
136                     canvas->drawString(gStyles[style].fName, 0, rect.height() + 12.0f,
137                                        labelFont, labelPaint);
138                     canvas->drawString(gFills[fill].fName, 0, rect.height() + 24.0f,
139                                        labelFont, labelPaint);
140                     canvas->drawString(gCaps[cap].fName, 0, rect.height() + 36.0f,
141                                        labelFont, labelPaint);
142                 }
143                 canvas->restore();
144             }
145             canvas->restore();
146         }
147         canvas->restore();
148         canvas->restore();
149     }
150 
151 private:
152     using INHERITED = GM;
153 };
154 
155 class QuadClosePathGM : public GM {
156 public:
QuadClosePathGM()157     QuadClosePathGM() {}
158 
159 protected:
160 
onShortName()161     SkString onShortName() override {
162         return SkString("quadclosepath");
163     }
164 
onISize()165     SkISize onISize() override { return SkISize::Make(1240, 390); }
166 
drawPath(SkPath & path,SkCanvas * canvas,SkColor color,const SkRect & clip,SkPaint::Cap cap,SkPaint::Join join,SkPaint::Style style,SkPathFillType fill,SkScalar strokeWidth)167     void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
168                   const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
169                   SkPaint::Style style, SkPathFillType fill,
170                   SkScalar strokeWidth) {
171         path.setFillType(fill);
172         SkPaint paint;
173         paint.setStrokeCap(cap);
174         paint.setStrokeWidth(strokeWidth);
175         paint.setStrokeJoin(join);
176         paint.setColor(color);
177         paint.setStyle(style);
178         canvas->save();
179         canvas->clipRect(clip);
180         canvas->drawPath(path, paint);
181         canvas->restore();
182     }
183 
onDraw(SkCanvas * canvas)184     void onDraw(SkCanvas* canvas) override {
185         struct FillAndName {
186             SkPathFillType fFill;
187             const char*      fName;
188         };
189         constexpr FillAndName gFills[] = {
190             {SkPathFillType::kWinding, "Winding"},
191             {SkPathFillType::kEvenOdd, "Even / Odd"},
192             {SkPathFillType::kInverseWinding, "Inverse Winding"},
193             {SkPathFillType::kInverseEvenOdd, "Inverse Even / Odd"},
194         };
195         struct StyleAndName {
196             SkPaint::Style fStyle;
197             const char*    fName;
198         };
199         constexpr StyleAndName gStyles[] = {
200             {SkPaint::kFill_Style, "Fill"},
201             {SkPaint::kStroke_Style, "Stroke"},
202             {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
203         };
204         struct CapAndName {
205             SkPaint::Cap  fCap;
206             SkPaint::Join fJoin;
207             const char*   fName;
208         };
209         constexpr CapAndName gCaps[] = {
210             {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
211             {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
212             {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
213         };
214         struct PathAndName {
215             SkPath      fPath;
216             const char* fName;
217         };
218         PathAndName path;
219         path.fPath.moveTo(25*SK_Scalar1, 10*SK_Scalar1);
220         path.fPath.quadTo(50*SK_Scalar1, 20*SK_Scalar1,
221                           75*SK_Scalar1, 10*SK_Scalar1);
222         path.fPath.close();
223         path.fName = "moveTo-quad-close";
224 
225         SkPaint titlePaint;
226         SkFont     font(ToolUtils::create_portable_typeface(), 15);
227         SkFont     labelFont(ToolUtils::create_portable_typeface(), 10);
228         const char title[] = "Quad Closed Drawn Into Rectangle Clips With "
229                              "Indicated Style, Fill and Linecaps, with stroke width 10";
230         canvas->drawString(title, 20.0f, 20.0f, font, titlePaint);
231 
232         SkRandom rand;
233         SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
234         canvas->save();
235         canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
236         canvas->save();
237         for (size_t cap = 0; cap < std::size(gCaps); ++cap) {
238             if (0 < cap) {
239                 canvas->translate((rect.width() + 40 * SK_Scalar1) * std::size(gStyles), 0);
240             }
241             canvas->save();
242             for (size_t fill = 0; fill < std::size(gFills); ++fill) {
243                 if (0 < fill) {
244                     canvas->translate(0, rect.height() + 40 * SK_Scalar1);
245                 }
246                 canvas->save();
247                 for (size_t style = 0; style < std::size(gStyles); ++style) {
248                     if (0 < style) {
249                         canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
250                     }
251 
252                     SkColor color = ToolUtils::color_to_565(0xff007000);
253                     this->drawPath(path.fPath, canvas, color, rect,
254                                     gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
255                                     gFills[fill].fFill, SK_Scalar1*10);
256 
257                     SkPaint rectPaint;
258                     rectPaint.setColor(SK_ColorBLACK);
259                     rectPaint.setStyle(SkPaint::kStroke_Style);
260                     rectPaint.setStrokeWidth(-1);
261                     rectPaint.setAntiAlias(true);
262                     canvas->drawRect(rect, rectPaint);
263 
264                     SkPaint labelPaint;
265                     labelPaint.setColor(color);
266                     canvas->drawString(gStyles[style].fName, 0, rect.height() + 12.0f,
267                                        labelFont, labelPaint);
268                     canvas->drawString(gFills[fill].fName, 0, rect.height() + 24.0f,
269                                        labelFont, labelPaint);
270                     canvas->drawString(gCaps[cap].fName, 0, rect.height() + 36.0f,
271                                        labelFont, labelPaint);
272                 }
273                 canvas->restore();
274             }
275             canvas->restore();
276         }
277         canvas->restore();
278         canvas->restore();
279     }
280 
281 private:
282     using INHERITED = GM;
283 };
284 
285 //////////////////////////////////////////////////////////////////////////////
286 
287 DEF_GM( return new QuadPathGM; )
288 
289 DEF_GM( return new QuadClosePathGM; )
290 
291 }  // namespace skiagm
292