Fix advances for aliased text with DirectWrite.
[platform/upstream/libSkiaSharp.git] / samplecode / SampleGradients.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 "SampleCode.h"
8 #include "SkView.h"
9 #include "SkCanvas.h"
10 #include "SkGradientShader.h"
11
12 static sk_sp<SkShader> setgrad(const SkRect& r, SkColor c0, SkColor c1) {
13     SkColor colors[] = { c0, c1 };
14     SkPoint pts[] = { { r.fLeft, r.fTop }, { r.fRight, r.fTop } };
15     return SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkShader::kClamp_TileMode);
16 }
17
18 static void test_alphagradients(SkCanvas* canvas) {
19     SkRect r;
20     r.set(SkIntToScalar(10), SkIntToScalar(10),
21           SkIntToScalar(410), SkIntToScalar(30));
22     SkPaint p, p2;
23     p2.setStyle(SkPaint::kStroke_Style);
24
25     p.setShader(setgrad(r, 0xFF00FF00, 0x0000FF00));
26     canvas->drawRect(r, p);
27     canvas->drawRect(r, p2);
28
29     r.offset(0, r.height() + SkIntToScalar(4));
30     p.setShader(setgrad(r, 0xFF00FF00, 0x00000000));
31     canvas->drawRect(r, p);
32     canvas->drawRect(r, p2);
33
34     r.offset(0, r.height() + SkIntToScalar(4));
35     p.setShader(setgrad(r, 0xFF00FF00, 0x00FF0000));
36     canvas->drawRect(r, p);
37     canvas->drawRect(r, p2);
38 }
39
40 ///////////////////////////////////////////////////////////////////////////////
41
42 struct GradData {
43     int             fCount;
44     const SkColor*  fColors;
45     const SkScalar* fPos;
46 };
47
48 static const SkColor gColors[] = {
49     SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
50 };
51 static const SkScalar gPos0[] = { 0, SK_Scalar1 };
52 static const SkScalar gPos1[] = { SK_Scalar1/4, SK_Scalar1*3/4 };
53 static const SkScalar gPos2[] = {
54     0, SK_Scalar1/8, SK_Scalar1/2, SK_Scalar1*7/8, SK_Scalar1
55 };
56
57 static const GradData gGradData[] = {
58     { 2, gColors, nullptr },
59     { 2, gColors, gPos0 },
60     { 2, gColors, gPos1 },
61     { 5, gColors, nullptr },
62     { 5, gColors, gPos2 }
63 };
64
65 static sk_sp<SkShader> MakeLinear(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
66     return SkGradientShader::MakeLinear(pts, data.fColors, data.fPos, data.fCount, tm);
67 }
68
69 static sk_sp<SkShader> MakeRadial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
70     SkPoint center;
71     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
72                SkScalarAve(pts[0].fY, pts[1].fY));
73     return SkGradientShader::MakeRadial(center, center.fX, data.fColors,
74                                         data.fPos, data.fCount, tm);
75 }
76
77 static sk_sp<SkShader> MakeSweep(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
78     SkPoint center;
79     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
80                SkScalarAve(pts[0].fY, pts[1].fY));
81     return SkGradientShader::MakeSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
82 }
83
84 static sk_sp<SkShader> Make2Conical(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
85     SkPoint center0, center1;
86     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
87                 SkScalarAve(pts[0].fY, pts[1].fY));
88     center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
89                 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
90     return SkGradientShader::MakeTwoPointConical(
91                             center1, (pts[1].fX - pts[0].fX) / 7,
92                             center0, (pts[1].fX - pts[0].fX) / 2,
93                             data.fColors, data.fPos, data.fCount, tm);
94 }
95
96 static sk_sp<SkShader> Make2ConicalConcentric(const SkPoint pts[2], const GradData& data,
97                                        SkShader::TileMode tm) {
98     SkPoint center;
99     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
100                SkScalarAve(pts[0].fY, pts[1].fY));
101     return SkGradientShader::MakeTwoPointConical(
102                             center, (pts[1].fX - pts[0].fX) / 7,
103                             center, (pts[1].fX - pts[0].fX) / 2,
104                             data.fColors, data.fPos, data.fCount, tm);
105 }
106
107 typedef sk_sp<SkShader> (*GradMaker)(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm);
108
109 static const GradMaker gGradMakers[] = {
110     MakeLinear, MakeRadial, MakeSweep, Make2Conical, Make2ConicalConcentric
111 };
112
113 ///////////////////////////////////////////////////////////////////////////////
114
115 class GradientsView : public SampleView {
116 public:
117     GradientsView() {
118         this->setBGColor(0xFFDDDDDD);
119     }
120
121 protected:
122     bool onQuery(SkEvent* evt) override {
123         if (SampleCode::TitleQ(*evt)) {
124             SampleCode::TitleR(evt, "Gradients");
125             return true;
126         }
127         return this->INHERITED::onQuery(evt);
128     }
129
130     void onDrawContent(SkCanvas* canvas) override {
131         SkPoint pts[2] = {
132             { 0, 0 },
133             { SkIntToScalar(100), SkIntToScalar(100) }
134         };
135         SkRect r = { 0, 0, SkIntToScalar(100), SkIntToScalar(100) };
136         SkPaint paint;
137         paint.setDither(true);
138
139         canvas->save();
140         canvas->translate(SkIntToScalar(20), SkIntToScalar(10));
141
142         for (int tm = 0; tm < SkShader::kTileModeCount; ++tm) {
143             canvas->save();
144             for (size_t i = 0; i < SK_ARRAY_COUNT(gGradData); i++) {
145                 canvas->save();
146                 for (size_t j = 0; j < SK_ARRAY_COUNT(gGradMakers); j++) {
147                     paint.setShader(gGradMakers[j](pts, gGradData[i], (SkShader::TileMode)tm));
148                     canvas->drawRect(r, paint);
149                     canvas->translate(0, SkIntToScalar(120));
150                 }
151                 canvas->restore();
152                 canvas->translate(SkIntToScalar(120), 0);
153             }
154             canvas->restore();
155             canvas->translate(SK_ARRAY_COUNT(gGradData)*SkIntToScalar(120), 0);
156         }
157         canvas->restore();
158
159         canvas->translate(0, SkIntToScalar(370));
160         if (false) { // avoid bit rot, suppress warning
161             test_alphagradients(canvas);
162         }
163         this->inval(nullptr);
164     }
165
166 private:
167     typedef SampleView INHERITED;
168 };
169
170 ///////////////////////////////////////////////////////////////////////////////
171
172 static SkView* MyFactory() { return new GradientsView; }
173 static SkViewRegister reg(MyFactory);