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