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