linepaths.cpp revision 108b5b2c23f2a44ab80b23183e6e962fc3b541e8
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
12namespace skiagm {
13
14class LinePathGM : public GM {
15public:
16    LinePathGM() {}
17
18protected:
19
20    SkString onShortName() {
21        return SkString("linepath");
22    }
23
24    SkISize onISize() { return SkISize::Make(1240, 390); }
25
26    void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
27                  const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
28                  SkPaint::Style style, SkPath::FillType fill,
29                  SkScalar strokeWidth) {
30        path.setFillType(fill);
31        SkPaint paint;
32        paint.setStrokeCap(cap);
33        paint.setStrokeWidth(strokeWidth);
34        paint.setStrokeJoin(join);
35        paint.setColor(color);
36        paint.setStyle(style);
37        canvas->save();
38        canvas->clipRect(clip);
39        canvas->drawPath(path, paint);
40        canvas->restore();
41    }
42
43    virtual void onDraw(SkCanvas* canvas) {
44        struct FillAndName {
45            SkPath::FillType fFill;
46            const char*      fName;
47        };
48        static const FillAndName gFills[] = {
49            {SkPath::kWinding_FillType, "Winding"},
50            {SkPath::kEvenOdd_FillType, "Even / Odd"},
51            {SkPath::kInverseWinding_FillType, "Inverse Winding"},
52            {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
53        };
54        struct StyleAndName {
55            SkPaint::Style fStyle;
56            const char*    fName;
57        };
58        static const StyleAndName gStyles[] = {
59            {SkPaint::kFill_Style, "Fill"},
60            {SkPaint::kStroke_Style, "Stroke"},
61            {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
62        };
63        struct CapAndName {
64            SkPaint::Cap  fCap;
65            SkPaint::Join fJoin;
66            const char*   fName;
67        };
68        static const CapAndName gCaps[] = {
69            {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
70            {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
71            {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
72        };
73        struct PathAndName {
74            SkPath      fPath;
75            const char* fName;
76        };
77        PathAndName path;
78        path.fPath.moveTo(25*SK_Scalar1, 15*SK_Scalar1);
79        path.fPath.lineTo(75*SK_Scalar1, 15*SK_Scalar1);
80        path.fName = "moveTo-line";
81
82        SkPaint titlePaint;
83        titlePaint.setColor(SK_ColorBLACK);
84        titlePaint.setAntiAlias(true);
85        sk_tool_utils::set_portable_typeface_always(&titlePaint);
86        titlePaint.setTextSize(15 * SK_Scalar1);
87        const char title[] = "Line Drawn Into Rectangle Clips With "
88                             "Indicated Style, Fill and Linecaps, with stroke width 10";
89        canvas->drawText(title, strlen(title),
90                            20 * SK_Scalar1,
91                            20 * SK_Scalar1,
92                            titlePaint);
93
94        SkRandom rand;
95        SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
96        canvas->save();
97        canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
98        canvas->save();
99        for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
100            if (0 < cap) {
101                canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
102            }
103            canvas->save();
104            for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
105                if (0 < fill) {
106                    canvas->translate(0, rect.height() + 40 * SK_Scalar1);
107                }
108                canvas->save();
109                for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
110                    if (0 < style) {
111                        canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
112                    }
113
114                    SkColor color = sk_tool_utils::color_to_565(0xff007000);
115                    this->drawPath(path.fPath, canvas, color, rect,
116                                    gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
117                                    gFills[fill].fFill, SK_Scalar1*10);
118
119                    SkPaint rectPaint;
120                    rectPaint.setColor(SK_ColorBLACK);
121                    rectPaint.setStyle(SkPaint::kStroke_Style);
122                    rectPaint.setStrokeWidth(-1);
123                    rectPaint.setAntiAlias(true);
124                    canvas->drawRect(rect, rectPaint);
125
126                    SkPaint labelPaint;
127                    labelPaint.setColor(color);
128                    labelPaint.setAntiAlias(true);
129                    sk_tool_utils::set_portable_typeface_always(&labelPaint);
130                    labelPaint.setTextSize(10 * SK_Scalar1);
131                    canvas->drawText(gStyles[style].fName,
132                                        strlen(gStyles[style].fName),
133                                        0, rect.height() + 12 * SK_Scalar1,
134                                        labelPaint);
135                    canvas->drawText(gFills[fill].fName,
136                                        strlen(gFills[fill].fName),
137                                        0, rect.height() + 24 * SK_Scalar1,
138                                        labelPaint);
139                    canvas->drawText(gCaps[cap].fName,
140                                        strlen(gCaps[cap].fName),
141                                        0, rect.height() + 36 * SK_Scalar1,
142                                        labelPaint);
143                }
144                canvas->restore();
145            }
146            canvas->restore();
147        }
148        canvas->restore();
149        canvas->restore();
150    }
151
152private:
153    typedef GM INHERITED;
154};
155
156class LineClosePathGM : public GM {
157public:
158    LineClosePathGM() {}
159
160protected:
161    SkString onShortName() {
162        return SkString("lineclosepath");
163    }
164
165    SkISize onISize() { return SkISize::Make(1240, 390); }
166
167    void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
168                  const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
169                  SkPaint::Style style, SkPath::FillType 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
184    virtual void onDraw(SkCanvas* canvas) {
185        struct FillAndName {
186            SkPath::FillType fFill;
187            const char*      fName;
188        };
189        static const FillAndName gFills[] = {
190            {SkPath::kWinding_FillType, "Winding"},
191            {SkPath::kEvenOdd_FillType, "Even / Odd"},
192            {SkPath::kInverseWinding_FillType, "Inverse Winding"},
193            {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
194        };
195        struct StyleAndName {
196            SkPaint::Style fStyle;
197            const char*    fName;
198        };
199        static const 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        static const 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, 15*SK_Scalar1);
220        path.fPath.lineTo(75*SK_Scalar1, 15*SK_Scalar1);
221        path.fPath.close();
222        path.fName = "moveTo-line-close";
223
224        SkPaint titlePaint;
225        titlePaint.setColor(SK_ColorBLACK);
226        titlePaint.setAntiAlias(true);
227        sk_tool_utils::set_portable_typeface_always(&titlePaint);
228        titlePaint.setTextSize(15 * SK_Scalar1);
229        const char title[] = "Line Closed Drawn Into Rectangle Clips With "
230                             "Indicated Style, Fill and Linecaps, with stroke width 10";
231        canvas->drawText(title, strlen(title),
232                            20 * SK_Scalar1,
233                            20 * SK_Scalar1,
234                            titlePaint);
235
236        SkRandom rand;
237        SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
238        canvas->save();
239        canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
240        canvas->save();
241        for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
242            if (0 < cap) {
243                canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
244            }
245            canvas->save();
246            for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
247                if (0 < fill) {
248                    canvas->translate(0, rect.height() + 40 * SK_Scalar1);
249                }
250                canvas->save();
251                for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
252                    if (0 < style) {
253                        canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
254                    }
255
256                    SkColor color = sk_tool_utils::color_to_565(0xff007000);
257                    this->drawPath(path.fPath, canvas, color, rect,
258                                    gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
259                                    gFills[fill].fFill, SK_Scalar1*10);
260
261                    SkPaint rectPaint;
262                    rectPaint.setColor(SK_ColorBLACK);
263                    rectPaint.setStyle(SkPaint::kStroke_Style);
264                    rectPaint.setStrokeWidth(-1);
265                    rectPaint.setAntiAlias(true);
266                    canvas->drawRect(rect, rectPaint);
267
268                    SkPaint labelPaint;
269                    labelPaint.setColor(color);
270                    labelPaint.setAntiAlias(true);
271                    sk_tool_utils::set_portable_typeface_always(&labelPaint);
272                    labelPaint.setTextSize(10 * SK_Scalar1);
273                    canvas->drawText(gStyles[style].fName,
274                                        strlen(gStyles[style].fName),
275                                        0, rect.height() + 12 * SK_Scalar1,
276                                        labelPaint);
277                    canvas->drawText(gFills[fill].fName,
278                                        strlen(gFills[fill].fName),
279                                        0, rect.height() + 24 * SK_Scalar1,
280                                        labelPaint);
281                    canvas->drawText(gCaps[cap].fName,
282                                        strlen(gCaps[cap].fName),
283                                        0, rect.height() + 36 * SK_Scalar1,
284                                        labelPaint);
285                }
286                canvas->restore();
287            }
288            canvas->restore();
289        }
290        canvas->restore();
291        canvas->restore();
292    }
293
294private:
295    typedef GM INHERITED;
296};
297
298//////////////////////////////////////////////////////////////////////////////
299
300static GM* LinePathFactory(void*) { return new LinePathGM; }
301static GMRegistry regLinePath(LinePathFactory);
302
303static GM* LineClosePathFactory(void*) { return new LineClosePathGM; }
304static GMRegistry regLineClosePath(LineClosePathFactory);
305
306}
307