1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2011 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h"
8cb93a386Sopenharmony_ci#include "include/effects/SkGradientShader.h"
9cb93a386Sopenharmony_ci#include "samplecode/Sample.h"
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_cistatic sk_sp<SkShader> setgrad(const SkRect& r, SkColor c0, SkColor c1) {
12cb93a386Sopenharmony_ci    SkColor colors[] = { c0, c1 };
13cb93a386Sopenharmony_ci    SkPoint pts[] = { { r.fLeft, r.fTop }, { r.fRight, r.fTop } };
14cb93a386Sopenharmony_ci    return SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
15cb93a386Sopenharmony_ci}
16cb93a386Sopenharmony_ci
17cb93a386Sopenharmony_cistatic void test_alphagradients(SkCanvas* canvas) {
18cb93a386Sopenharmony_ci    SkRect r;
19cb93a386Sopenharmony_ci    r.setLTRB(10, 10, 410, 30);
20cb93a386Sopenharmony_ci    SkPaint p, p2;
21cb93a386Sopenharmony_ci    p2.setStyle(SkPaint::kStroke_Style);
22cb93a386Sopenharmony_ci
23cb93a386Sopenharmony_ci    p.setShader(setgrad(r, 0xFF00FF00, 0x0000FF00));
24cb93a386Sopenharmony_ci    canvas->drawRect(r, p);
25cb93a386Sopenharmony_ci    canvas->drawRect(r, p2);
26cb93a386Sopenharmony_ci
27cb93a386Sopenharmony_ci    r.offset(0, r.height() + SkIntToScalar(4));
28cb93a386Sopenharmony_ci    p.setShader(setgrad(r, 0xFF00FF00, 0x00000000));
29cb93a386Sopenharmony_ci    canvas->drawRect(r, p);
30cb93a386Sopenharmony_ci    canvas->drawRect(r, p2);
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_ci    r.offset(0, r.height() + SkIntToScalar(4));
33cb93a386Sopenharmony_ci    p.setShader(setgrad(r, 0xFF00FF00, 0x00FF0000));
34cb93a386Sopenharmony_ci    canvas->drawRect(r, p);
35cb93a386Sopenharmony_ci    canvas->drawRect(r, p2);
36cb93a386Sopenharmony_ci}
37cb93a386Sopenharmony_ci
38cb93a386Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////
39cb93a386Sopenharmony_ci
40cb93a386Sopenharmony_cistruct GradData {
41cb93a386Sopenharmony_ci    int             fCount;
42cb93a386Sopenharmony_ci    const SkColor*  fColors;
43cb93a386Sopenharmony_ci    const SkScalar* fPos;
44cb93a386Sopenharmony_ci};
45cb93a386Sopenharmony_ci
46cb93a386Sopenharmony_cistatic const SkColor gColors[] = {
47cb93a386Sopenharmony_ci    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
48cb93a386Sopenharmony_ci};
49cb93a386Sopenharmony_cistatic const SkScalar gPos0[] = { 0, SK_Scalar1 };
50cb93a386Sopenharmony_cistatic const SkScalar gPos1[] = { SK_Scalar1/4, SK_Scalar1*3/4 };
51cb93a386Sopenharmony_cistatic const SkScalar gPos2[] = {
52cb93a386Sopenharmony_ci    0, SK_Scalar1/8, SK_Scalar1/2, SK_Scalar1*7/8, SK_Scalar1
53cb93a386Sopenharmony_ci};
54cb93a386Sopenharmony_ci
55cb93a386Sopenharmony_cistatic const GradData gGradData[] = {
56cb93a386Sopenharmony_ci    { 2, gColors, nullptr },
57cb93a386Sopenharmony_ci    { 2, gColors, gPos0 },
58cb93a386Sopenharmony_ci    { 2, gColors, gPos1 },
59cb93a386Sopenharmony_ci    { 5, gColors, nullptr },
60cb93a386Sopenharmony_ci    { 5, gColors, gPos2 }
61cb93a386Sopenharmony_ci};
62cb93a386Sopenharmony_ci
63cb93a386Sopenharmony_cistatic sk_sp<SkShader> MakeLinear(const SkPoint pts[2], const GradData& data, SkTileMode tm) {
64cb93a386Sopenharmony_ci    return SkGradientShader::MakeLinear(pts, data.fColors, data.fPos, data.fCount, tm);
65cb93a386Sopenharmony_ci}
66cb93a386Sopenharmony_ci
67cb93a386Sopenharmony_cistatic sk_sp<SkShader> MakeRadial(const SkPoint pts[2], const GradData& data, SkTileMode tm) {
68cb93a386Sopenharmony_ci    SkPoint center;
69cb93a386Sopenharmony_ci    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
70cb93a386Sopenharmony_ci               SkScalarAve(pts[0].fY, pts[1].fY));
71cb93a386Sopenharmony_ci    return SkGradientShader::MakeRadial(center, center.fX, data.fColors,
72cb93a386Sopenharmony_ci                                        data.fPos, data.fCount, tm);
73cb93a386Sopenharmony_ci}
74cb93a386Sopenharmony_ci
75cb93a386Sopenharmony_cistatic sk_sp<SkShader> MakeSweep(const SkPoint pts[2], const GradData& data, SkTileMode tm) {
76cb93a386Sopenharmony_ci    SkPoint center;
77cb93a386Sopenharmony_ci    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
78cb93a386Sopenharmony_ci               SkScalarAve(pts[0].fY, pts[1].fY));
79cb93a386Sopenharmony_ci    return SkGradientShader::MakeSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
80cb93a386Sopenharmony_ci}
81cb93a386Sopenharmony_ci
82cb93a386Sopenharmony_cistatic sk_sp<SkShader> Make2Conical(const SkPoint pts[2], const GradData& data, SkTileMode tm) {
83cb93a386Sopenharmony_ci    SkPoint center0, center1;
84cb93a386Sopenharmony_ci    center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
85cb93a386Sopenharmony_ci                SkScalarAve(pts[0].fY, pts[1].fY));
86cb93a386Sopenharmony_ci    center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
87cb93a386Sopenharmony_ci                SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
88cb93a386Sopenharmony_ci    return SkGradientShader::MakeTwoPointConical(
89cb93a386Sopenharmony_ci                            center1, (pts[1].fX - pts[0].fX) / 7,
90cb93a386Sopenharmony_ci                            center0, (pts[1].fX - pts[0].fX) / 2,
91cb93a386Sopenharmony_ci                            data.fColors, data.fPos, data.fCount, tm);
92cb93a386Sopenharmony_ci}
93cb93a386Sopenharmony_ci
94cb93a386Sopenharmony_cistatic sk_sp<SkShader> Make2ConicalConcentric(const SkPoint pts[2], const GradData& data,
95cb93a386Sopenharmony_ci                                       SkTileMode tm) {
96cb93a386Sopenharmony_ci    SkPoint center;
97cb93a386Sopenharmony_ci    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
98cb93a386Sopenharmony_ci               SkScalarAve(pts[0].fY, pts[1].fY));
99cb93a386Sopenharmony_ci    return SkGradientShader::MakeTwoPointConical(
100cb93a386Sopenharmony_ci                            center, (pts[1].fX - pts[0].fX) / 7,
101cb93a386Sopenharmony_ci                            center, (pts[1].fX - pts[0].fX) / 2,
102cb93a386Sopenharmony_ci                            data.fColors, data.fPos, data.fCount, tm);
103cb93a386Sopenharmony_ci}
104cb93a386Sopenharmony_ci
105cb93a386Sopenharmony_citypedef sk_sp<SkShader> (*GradMaker)(const SkPoint pts[2], const GradData& data, SkTileMode tm);
106cb93a386Sopenharmony_ci
107cb93a386Sopenharmony_cistatic const GradMaker gGradMakers[] = {
108cb93a386Sopenharmony_ci    MakeLinear, MakeRadial, MakeSweep, Make2Conical, Make2ConicalConcentric
109cb93a386Sopenharmony_ci};
110cb93a386Sopenharmony_ci
111cb93a386Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////
112cb93a386Sopenharmony_ci
113cb93a386Sopenharmony_ciclass GradientsView : public Sample {
114cb93a386Sopenharmony_cipublic:
115cb93a386Sopenharmony_ci    GradientsView() {
116cb93a386Sopenharmony_ci        this->setBGColor(0xFFDDDDDD);
117cb93a386Sopenharmony_ci    }
118cb93a386Sopenharmony_ci
119cb93a386Sopenharmony_ciprotected:
120cb93a386Sopenharmony_ci    SkString name() override { return SkString("Gradients"); }
121cb93a386Sopenharmony_ci
122cb93a386Sopenharmony_ci    void onDrawContent(SkCanvas* canvas) override {
123cb93a386Sopenharmony_ci        SkPoint pts[2] = {
124cb93a386Sopenharmony_ci            { 0, 0 },
125cb93a386Sopenharmony_ci            { SkIntToScalar(100), SkIntToScalar(100) }
126cb93a386Sopenharmony_ci        };
127cb93a386Sopenharmony_ci        SkRect r = { 0, 0, SkIntToScalar(100), SkIntToScalar(100) };
128cb93a386Sopenharmony_ci        SkPaint paint;
129cb93a386Sopenharmony_ci        paint.setDither(true);
130cb93a386Sopenharmony_ci
131cb93a386Sopenharmony_ci        canvas->save();
132cb93a386Sopenharmony_ci        canvas->translate(SkIntToScalar(20), SkIntToScalar(10));
133cb93a386Sopenharmony_ci
134cb93a386Sopenharmony_ci        for (int tm = 0; tm < kSkTileModeCount; ++tm) {
135cb93a386Sopenharmony_ci            canvas->save();
136cb93a386Sopenharmony_ci            for (size_t i = 0; i < SK_ARRAY_COUNT(gGradData); i++) {
137cb93a386Sopenharmony_ci                canvas->save();
138cb93a386Sopenharmony_ci                for (size_t j = 0; j < SK_ARRAY_COUNT(gGradMakers); j++) {
139cb93a386Sopenharmony_ci                    paint.setShader(gGradMakers[j](pts, gGradData[i], (SkTileMode)tm));
140cb93a386Sopenharmony_ci                    canvas->drawRect(r, paint);
141cb93a386Sopenharmony_ci                    canvas->translate(0, SkIntToScalar(120));
142cb93a386Sopenharmony_ci                }
143cb93a386Sopenharmony_ci                canvas->restore();
144cb93a386Sopenharmony_ci                canvas->translate(SkIntToScalar(120), 0);
145cb93a386Sopenharmony_ci            }
146cb93a386Sopenharmony_ci            canvas->restore();
147cb93a386Sopenharmony_ci            canvas->translate(SK_ARRAY_COUNT(gGradData)*SkIntToScalar(120), 0);
148cb93a386Sopenharmony_ci        }
149cb93a386Sopenharmony_ci        canvas->restore();
150cb93a386Sopenharmony_ci
151cb93a386Sopenharmony_ci        canvas->translate(0, SkIntToScalar(370));
152cb93a386Sopenharmony_ci        if (false) { // avoid bit rot, suppress warning
153cb93a386Sopenharmony_ci            test_alphagradients(canvas);
154cb93a386Sopenharmony_ci        }
155cb93a386Sopenharmony_ci    }
156cb93a386Sopenharmony_ci
157cb93a386Sopenharmony_ciprivate:
158cb93a386Sopenharmony_ci    using INHERITED = Sample;
159cb93a386Sopenharmony_ci};
160cb93a386Sopenharmony_ci
161cb93a386Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////
162cb93a386Sopenharmony_ci
163cb93a386Sopenharmony_ciDEF_SAMPLE( return new GradientsView(); )
164