Add fixes & test for isConfigTexturable and isConfigRenderable
[platform/upstream/libSkiaSharp.git] / gm / strokedlines.cpp
1 /*
2  * Copyright 2016 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.h"
9 #include "sk_tool_utils.h"
10 #include "SkBlurMaskFilter.h"
11 #include "SkDashPathEffect.h"
12 #include "SkGradientShader.h"
13 #include "SkPaint.h"
14 #include "SkPath.h"
15 #include "SkPoint3.h"
16
17 constexpr int kNumColumns = 6;
18 constexpr int kNumRows = 8;
19 constexpr int kRadius = 40;  // radius of the snowflake
20 constexpr int kPad = 5;      // padding on both sides of the snowflake
21 constexpr int kNumSpokes = 6;
22 constexpr SkScalar kStrokeWidth = 5.0f;
23
24 static void draw_fins(SkCanvas* canvas, const SkPoint& offset, float angle, const SkPaint& paint) {
25     SkScalar cos, sin;
26
27     // first fin
28     sin = SkScalarSinCos(angle + (SK_ScalarPI/4), &cos);
29     sin *= kRadius / 2.0f;
30     cos *= kRadius / 2.0f;
31
32     SkPath p;
33     p.moveTo(offset.fX, offset.fY);
34     p.lineTo(offset.fX + cos, offset.fY + sin);
35     canvas->drawPath(p, paint);
36
37     // second fin
38     sin = SkScalarSinCos(angle - (SK_ScalarPI/4), &cos);
39     sin *= kRadius / 2.0f;
40     cos *= kRadius / 2.0f;
41
42     p.reset();
43     p.moveTo(offset.fX, offset.fY);
44     p.lineTo(offset.fX + cos, offset.fY + sin);
45     canvas->drawPath(p, paint);
46 }
47
48 // draw a snowflake centered at the origin
49 static void draw_snowflake(SkCanvas* canvas, const SkPaint& paint) {
50
51     canvas->clipRect(SkRect::MakeLTRB(-kRadius-kPad, -kRadius-kPad, kRadius+kPad, kRadius+kPad));
52
53     SkScalar sin, cos, angle = 0.0f;
54     for (int i = 0; i < kNumSpokes/2; ++i, angle += SK_ScalarPI/(kNumSpokes/2)) {
55         sin = SkScalarSinCos(angle, &cos);
56         sin *= kRadius;
57         cos *= kRadius;
58
59         // main spoke
60         SkPath p;
61         p.moveTo(-cos, -sin);
62         p.lineTo(cos, sin);
63         canvas->drawPath(p, paint);
64
65         // fins on positive side
66         const SkPoint posOffset = SkPoint::Make(0.5f * cos, 0.5f * sin);
67         draw_fins(canvas, posOffset, angle, paint);
68
69         // fins on negative side
70         const SkPoint negOffset = SkPoint::Make(-0.5f * cos, -0.5f * sin);
71         draw_fins(canvas, negOffset, angle+SK_ScalarPI, paint);
72     }
73 }
74
75 static void draw_row(SkCanvas* canvas, const SkPaint& paint, const SkMatrix& localMatrix) {
76     canvas->translate(kRadius+kPad, 0.0f);
77
78     for (auto cap : { SkPaint::kButt_Cap, SkPaint::kRound_Cap, SkPaint::kSquare_Cap }) {
79         for (auto isAA : { true, false }) {
80             SkPaint tmp(paint);
81             tmp.setStrokeWidth(kStrokeWidth);
82             tmp.setStyle(SkPaint::kStroke_Style);
83             tmp.setStrokeCap(cap);
84             tmp.setAntiAlias(isAA);
85
86             int saveCount = canvas->save();
87             canvas->concat(localMatrix);
88             draw_snowflake(canvas, tmp);
89             canvas->restoreToCount(saveCount);
90
91             canvas->translate(2*(kRadius+kPad), 0.0f);
92         }
93     }
94 }
95
96 namespace skiagm {
97
98 // This GM exercises the special case of a stroked lines.
99 // Various shaders are applied to ensure the coordinate spaces work out right.
100 class StrokedLinesGM : public GM {
101 public:
102     StrokedLinesGM() {
103         this->setBGColor(sk_tool_utils::color_to_565(0xFF1A65D7));
104     }
105
106 protected:
107     SkString onShortName() override {
108         return SkString("strokedlines");
109     }
110
111     SkISize onISize() override {
112         return SkISize::Make(kNumColumns * (2*kRadius+2*kPad), kNumRows * (2*kRadius+2*kPad));
113     }
114
115     void onOnceBeforeDraw() override {
116         // paints
117         {
118             // basic white
119             SkPaint p;
120             p.setColor(SK_ColorWHITE);
121             fPaints.push_back(p);
122         }
123         {
124             // gradient
125             SkColor colors[] = { SK_ColorRED, SK_ColorGREEN };
126             SkPoint pts[] = { {-kRadius-kPad, -kRadius-kPad }, { kRadius+kPad, kRadius+kPad } };
127
128             SkPaint p;
129             p.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, 2,
130                                                      SkShader::kClamp_TileMode, 0, nullptr));
131
132             fPaints.push_back(p);
133         }
134         {
135             // dashing
136             SkScalar intervals[] = { kStrokeWidth, kStrokeWidth };
137             int intervalCount = (int) SK_ARRAY_COUNT(intervals);
138             SkPaint p;
139             p.setColor(SK_ColorWHITE);
140             p.setPathEffect(SkDashPathEffect::Make(intervals, intervalCount, kStrokeWidth));
141
142             fPaints.push_back(p);
143         }
144         {
145             // Bitmap shader
146             SkBitmap bm;
147             bm.allocN32Pixels(2, 2);
148             *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF;
149             *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = 0x0;
150
151             SkMatrix m;
152             m.setRotate(12.0f);
153             m.preScale(3.0f, 3.0f);;
154
155             SkPaint p;
156             p.setShader(SkShader::MakeBitmapShader(bm,
157                                                    SkShader::kRepeat_TileMode,
158                                                    SkShader::kRepeat_TileMode,
159                                                    &m));
160             fPaints.push_back(p);
161         }
162         {
163             // blur
164             SkPaint p;
165             p.setColor(SK_ColorWHITE);
166             p.setMaskFilter(SkBlurMaskFilter::Make(kOuter_SkBlurStyle, 3.0f,
167                                                    SkBlurMaskFilter::kHighQuality_BlurFlag));
168             fPaints.push_back(p);
169         }
170
171         // matrices
172         {
173             // rotation
174             SkMatrix m;
175             m.setRotate(12.0f);
176
177             fMatrices.push_back(m);
178         }
179         {
180             // skew
181             SkMatrix m;
182             m.setSkew(0.3f, 0.5f);
183
184             fMatrices.push_back(m);
185         }
186         {
187             // perspective
188             SkMatrix m;
189             m.reset();
190             m.setPerspX(-SK_Scalar1 / 300);
191             m.setPerspY(SK_Scalar1 / 300);
192
193             fMatrices.push_back(m);
194         }
195
196         SkASSERT(kNumRows == fPaints.count() + fMatrices.count());
197     }
198
199     void onDraw(SkCanvas* canvas) override {
200         canvas->translate(0, kRadius+kPad);
201
202         for (int i = 0; i < fPaints.count(); ++i) {
203             int saveCount = canvas->save();
204             draw_row(canvas, fPaints[i], SkMatrix::I());
205             canvas->restoreToCount(saveCount);
206
207             canvas->translate(0, 2*(kRadius+kPad));
208         }
209
210         for (int i = 0; i < fMatrices.count(); ++i) {
211             int saveCount = canvas->save();
212             draw_row(canvas, fPaints[0], fMatrices[i]);
213             canvas->restoreToCount(saveCount);
214
215             canvas->translate(0, 2*(kRadius+kPad));
216         }
217     }
218
219 private:
220     SkTArray<SkPaint> fPaints;
221     SkTArray<SkMatrix> fMatrices;
222
223     typedef GM INHERITED;
224 };
225
226 //////////////////////////////////////////////////////////////////////////////
227
228 DEF_GM(return new StrokedLinesGM;)
229 }