Home | History | Annotate | Download | only in samplecode
      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);
    174