1#include "gm.h" 2#include "SkCanvas.h" 3#include "SkGradientShader.h" 4#include "SkUnitMappers.h" 5 6namespace skiagm { 7 8static void makebm(SkBitmap* bm, SkBitmap::Config config, int w, int h) { 9 bm->setConfig(config, w, h); 10 bm->allocPixels(); 11 bm->eraseColor(0); 12 13 SkCanvas canvas(*bm); 14 SkScalar s = SkIntToScalar(SkMin32(w, h)); 15 SkPoint pts[] = { { 0, 0 }, { s, s } }; 16 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE }; 17 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 }; 18 SkPaint paint; 19 20 SkUnitMapper* um = NULL; 21 22 um = new SkCosineMapper; 23 24 SkAutoUnref au(um); 25 26 paint.setDither(true); 27 paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos, 28 SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode, um))->unref(); 29 canvas.drawPaint(paint); 30} 31 32SkShader* MakeBitmapShader(SkShader::TileMode tx, SkShader::TileMode ty, 33 int w, int h) { 34 static SkBitmap bmp; 35 if (bmp.isNull()) { 36 makebm(&bmp, SkBitmap::kARGB_8888_Config, w/2, h/4); 37 } 38 return SkShader::CreateBitmapShader(bmp, tx, ty); 39} 40 41/////////////////////////////////////////////////////////////////////////////// 42 43struct GradData { 44 int fCount; 45 const SkColor* fColors; 46 const SkScalar* fPos; 47}; 48 49static const SkColor gColors[] = { 50 SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK 51}; 52 53static const GradData gGradData[] = { 54 { 2, gColors, NULL }, 55 { 5, gColors, NULL }, 56}; 57 58static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, 59 SkShader::TileMode tm, SkUnitMapper* mapper) { 60 return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, 61 data.fCount, tm, mapper); 62} 63 64static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data, 65 SkShader::TileMode tm, SkUnitMapper* mapper) { 66 SkPoint center; 67 center.set(SkScalarAve(pts[0].fX, pts[1].fX), 68 SkScalarAve(pts[0].fY, pts[1].fY)); 69 return SkGradientShader::CreateRadial(center, center.fX, data.fColors, 70 data.fPos, data.fCount, tm, mapper); 71} 72 73static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, 74 SkShader::TileMode tm, SkUnitMapper* mapper) { 75 SkPoint center; 76 center.set(SkScalarAve(pts[0].fX, pts[1].fX), 77 SkScalarAve(pts[0].fY, pts[1].fY)); 78 return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, 79 data.fPos, data.fCount, mapper); 80} 81 82static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, 83 SkShader::TileMode tm, SkUnitMapper* mapper) { 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::CreateTwoPointRadial( 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, mapper); 93} 94 95typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, 96 SkShader::TileMode tm, SkUnitMapper* mapper); 97static const GradMaker gGradMakers[] = { 98 MakeLinear, MakeRadial, MakeSweep, Make2Radial 99}; 100 101/////////////////////////////////////////////////////////////////////////////// 102 103class ShaderTextGM : public GM { 104public: 105 ShaderTextGM() {} 106 107protected: 108 109 SkString onShortName() { 110 return SkString("shadertext"); 111 } 112 113 SkISize onISize() { return make_isize(950, 500); } 114 115 void drawBG(SkCanvas* canvas) { 116 canvas->drawColor(0xFFDDDDDD); 117 } 118 119 virtual void onDraw(SkCanvas* canvas) { 120 this->drawBG(canvas); 121 122 const char text[] = "Shaded Text"; 123 const int textLen = SK_ARRAY_COUNT(text) - 1; 124 const int pointSize = 48; 125 126 int w = pointSize * textLen; 127 int h = pointSize; 128 129 SkPoint pts[2] = { 130 { 0, 0 }, 131 { SkIntToScalar(w), SkIntToScalar(h) } 132 }; 133 SkScalar textBase = SkIntToScalar(h/2); 134 135 SkShader::TileMode tileModes[] = { 136 SkShader::kClamp_TileMode, 137 SkShader::kRepeat_TileMode, 138 SkShader::kMirror_TileMode 139 }; 140 141 static const int gradCount = SK_ARRAY_COUNT(gGradData) * 142 SK_ARRAY_COUNT(gGradMakers); 143 static const int bmpCount = SK_ARRAY_COUNT(tileModes) * 144 SK_ARRAY_COUNT(tileModes); 145 SkShader* shaders[gradCount + bmpCount]; 146 147 int shdIdx = 0; 148 for (size_t d = 0; d < SK_ARRAY_COUNT(gGradData); ++d) { 149 for (size_t m = 0; m < SK_ARRAY_COUNT(gGradMakers); ++m) { 150 shaders[shdIdx++] = gGradMakers[m](pts, 151 gGradData[d], 152 SkShader::kClamp_TileMode, 153 NULL); 154 } 155 } 156 for (size_t tx = 0; tx < SK_ARRAY_COUNT(tileModes); ++tx) { 157 for (size_t ty = 0; ty < SK_ARRAY_COUNT(tileModes); ++ty) { 158 shaders[shdIdx++] = MakeBitmapShader(tileModes[tx], 159 tileModes[ty], 160 w/8, h); 161 } 162 } 163 164 SkPaint paint; 165 paint.setDither(true); 166 paint.setAntiAlias(true); 167 paint.setTextSize(SkIntToScalar(pointSize)); 168 169 canvas->save(); 170 canvas->translate(SkIntToScalar(20), SkIntToScalar(10)); 171 172 static const int testsPerCol = 8; 173 static const int rowHeight = 60; 174 static const int colWidth = 300; 175 canvas->save(); 176 for (size_t s = 0; s < SK_ARRAY_COUNT(shaders); s++) { 177 canvas->save(); 178 canvas->translate(SkIntToScalar((s / testsPerCol) * colWidth), 179 SkIntToScalar((s % testsPerCol) * rowHeight)); 180 paint.setShader(shaders[s])->ref(); 181 canvas->drawText(text, textLen, 0, textBase, paint); 182 canvas->restore(); 183 } 184 canvas->restore(); 185 } 186 187private: 188 typedef GM INHERITED; 189}; 190 191/////////////////////////////////////////////////////////////////////////////// 192 193static GM* MyFactory(void*) { return new ShaderTextGM; } 194static GMRegistry reg(MyFactory); 195 196} 197