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