1 #include "gm.h" 2 #include "SkCanvas.h" 3 #include "SkGradientShader.h" 4 #include "SkUnitMappers.h" 5 6 namespace skiagm { 7 8 static 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 32 SkShader* 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 43 struct GradData { 44 int fCount; 45 const SkColor* fColors; 46 const SkScalar* fPos; 47 }; 48 49 static const SkColor gColors[] = { 50 SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK 51 }; 52 53 static const GradData gGradData[] = { 54 { 2, gColors, NULL }, 55 { 5, gColors, NULL }, 56 }; 57 58 static 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 64 static 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 73 static 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 82 static 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 95 typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, 96 SkShader::TileMode tm, SkUnitMapper* mapper); 97 static const GradMaker gGradMakers[] = { 98 MakeLinear, MakeRadial, MakeSweep, Make2Radial 99 }; 100 101 /////////////////////////////////////////////////////////////////////////////// 102 103 class ShaderTextGM : public GM { 104 public: 105 ShaderTextGM() {} 106 107 protected: 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 187 private: 188 typedef GM INHERITED; 189 }; 190 191 /////////////////////////////////////////////////////////////////////////////// 192 193 static GM* MyFactory(void*) { return new ShaderTextGM; } 194 static GMRegistry reg(MyFactory); 195 196 } 197