Find cubic KLM functionals directly
[platform/upstream/libSkiaSharp.git] / gm / emptypath.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 "sk_tool_utils.h"
9 #include "SkCanvas.h"
10 #include "SkPaint.h"
11 #include "SkPath.h"
12 #include "SkRandom.h"
13
14 namespace skiagm {
15
16 class EmptyPathGM : public GM {
17 public:
18     EmptyPathGM() {}
19
20 protected:
21     SkString onShortName() {
22         return SkString("emptypath");
23     }
24
25     SkISize onISize() { return SkISize::Make(600, 280); }
26
27     void drawEmpty(SkCanvas* canvas,
28                     SkColor color,
29                     const SkRect& clip,
30                     SkPaint::Style style,
31                     SkPath::FillType fill) {
32         SkPath path;
33         path.setFillType(fill);
34         SkPaint paint;
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         constexpr 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         constexpr StyleAndName gStyles[] = {
59             {SkPaint::kFill_Style, "Fill"},
60             {SkPaint::kStroke_Style, "Stroke"},
61             {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
62         };
63
64         SkPaint titlePaint;
65         titlePaint.setColor(SK_ColorBLACK);
66         titlePaint.setAntiAlias(true);
67         sk_tool_utils::set_portable_typeface(&titlePaint);
68         titlePaint.setTextSize(15 * SK_Scalar1);
69         const char title[] = "Empty Paths Drawn Into Rectangle Clips With "
70                              "Indicated Style and Fill";
71         canvas->drawText(title, strlen(title),
72                             20 * SK_Scalar1,
73                             20 * SK_Scalar1,
74                             titlePaint);
75
76         SkRandom rand;
77         SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
78         int i = 0;
79         canvas->save();
80         canvas->translate(10 * SK_Scalar1, 0);
81         canvas->save();
82         for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
83             for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
84                 if (0 == i % 4) {
85                     canvas->restore();
86                     canvas->translate(0, rect.height() + 40 * SK_Scalar1);
87                     canvas->save();
88                 } else {
89                     canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
90                 }
91                 ++i;
92
93
94                 SkColor color = rand.nextU();
95                 color = 0xff000000 | color; // force solid
96                 color = sk_tool_utils::color_to_565(color);
97                 this->drawEmpty(canvas, color, rect,
98                                 gStyles[style].fStyle, gFills[fill].fFill);
99
100                 SkPaint rectPaint;
101                 rectPaint.setColor(SK_ColorBLACK);
102                 rectPaint.setStyle(SkPaint::kStroke_Style);
103                 rectPaint.setStrokeWidth(-1);
104                 rectPaint.setAntiAlias(true);
105                 canvas->drawRect(rect, rectPaint);
106
107                 SkPaint labelPaint;
108                 labelPaint.setColor(color);
109                 labelPaint.setAntiAlias(true);
110                 sk_tool_utils::set_portable_typeface(&labelPaint);
111                 labelPaint.setTextSize(12 * SK_Scalar1);
112                 canvas->drawText(gStyles[style].fName,
113                                  strlen(gStyles[style].fName),
114                                  0, rect.height() + 15 * SK_Scalar1,
115                                  labelPaint);
116                 canvas->drawText(gFills[fill].fName,
117                                  strlen(gFills[fill].fName),
118                                  0, rect.height() + 28 * SK_Scalar1,
119                                  labelPaint);
120             }
121         }
122         canvas->restore();
123         canvas->restore();
124     }
125
126 private:
127     typedef GM INHERITED;
128 };
129 DEF_GM( return new EmptyPathGM; )
130
131 //////////////////////////////////////////////////////////////////////////////
132
133 static void make_path_move(SkPath* path, const SkPoint pts[3]) {
134     for (int i = 0; i < 3; ++i) {
135         path->moveTo(pts[i]);
136     }
137 }
138
139 static void make_path_move_close(SkPath* path, const SkPoint pts[3]) {
140     for (int i = 0; i < 3; ++i) {
141         path->moveTo(pts[i]);
142         path->close();
143     }
144 }
145
146 static void make_path_move_line(SkPath* path, const SkPoint pts[3]) {
147     for (int i = 0; i < 3; ++i) {
148         path->moveTo(pts[i]);
149         path->lineTo(pts[i]);
150     }
151 }
152
153 typedef void (*MakePathProc)(SkPath*, const SkPoint pts[3]);
154
155 static void make_path_move_mix(SkPath* path, const SkPoint pts[3]) {
156     path->moveTo(pts[0]);
157     path->moveTo(pts[1]); path->close();
158     path->moveTo(pts[2]); path->lineTo(pts[2]);
159 }
160
161 class EmptyStrokeGM : public GM {
162     SkPoint fPts[3];
163
164 public:
165     EmptyStrokeGM() {
166         fPts[0].set(40, 40);
167         fPts[1].set(80, 40);
168         fPts[2].set(120, 40);
169     }
170
171 protected:
172     SkString onShortName() override {
173         return SkString("emptystroke");
174     }
175
176     SkISize onISize() override { return SkISize::Make(200, 240); }
177
178     void onDraw(SkCanvas* canvas) override {
179         const MakePathProc procs[] = {
180             make_path_move,             // expect red red red
181             make_path_move_close,       // expect black black black
182             make_path_move_line,        // expect black black black
183             make_path_move_mix,         // expect red black black,
184         };
185
186         SkPaint strokePaint;
187         strokePaint.setStyle(SkPaint::kStroke_Style);
188         strokePaint.setStrokeWidth(21);
189         strokePaint.setStrokeCap(SkPaint::kSquare_Cap);
190
191         SkPaint dotPaint;
192         dotPaint.setColor(SK_ColorRED);
193         strokePaint.setStyle(SkPaint::kStroke_Style);
194         dotPaint.setStrokeWidth(7);
195
196         for (size_t i = 0; i < SK_ARRAY_COUNT(procs); ++i) {
197             SkPath path;
198             procs[i](&path, fPts);
199             canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, fPts, dotPaint);
200             canvas->drawPath(path, strokePaint);
201             canvas->translate(0, 40);
202         }
203     }
204
205 private:
206     typedef GM INHERITED;
207 };
208 DEF_GM( return new EmptyStrokeGM; )
209
210 }