SampleShaderText.cpp revision e2b193ca5c76f01f8e12b4a92e9bd6ccb3ed4280
1 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8#include "SampleCode.h" 9#include "SkView.h" 10#include "SkCanvas.h" 11#include "SkGradientShader.h" 12#include "SkUnitMappers.h" 13 14static void makebm(SkBitmap* bm, int w, int h) { 15 bm->allocN32Pixels(w, h); 16 bm->eraseColor(SK_ColorTRANSPARENT); 17 18 SkCanvas canvas(*bm); 19 SkScalar s = SkIntToScalar(w < h ? w : h); 20 SkPoint pts[] = { { 0, 0 }, { s, s } }; 21 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE }; 22 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 }; 23 SkPaint paint; 24 25 SkUnitMapper* um = NULL; 26 27 um = new SkCosineMapper; 28 29 SkAutoUnref au(um); 30 31 paint.setDither(true); 32 paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos, 33 SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode, um))->unref(); 34 canvas.drawPaint(paint); 35} 36 37static SkShader* MakeBitmapShader(SkShader::TileMode tx, SkShader::TileMode ty, 38 int w, int h) { 39 static SkBitmap bmp; 40 if (bmp.isNull()) { 41 makebm(&bmp, w/2, h/4); 42 } 43 return SkShader::CreateBitmapShader(bmp, tx, ty); 44} 45 46/////////////////////////////////////////////////////////////////////////////// 47 48struct GradData { 49 int fCount; 50 const SkColor* fColors; 51 const SkScalar* fPos; 52}; 53 54static const SkColor gColors[] = { 55 SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK 56}; 57 58static const GradData gGradData[] = { 59 { 2, gColors, NULL }, 60 { 5, gColors, NULL }, 61}; 62 63static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, 64 SkShader::TileMode tm, SkUnitMapper* mapper) { 65 return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, 66 data.fCount, tm, mapper); 67} 68 69static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data, 70 SkShader::TileMode tm, SkUnitMapper* mapper) { 71 SkPoint center; 72 center.set(SkScalarAve(pts[0].fX, pts[1].fX), 73 SkScalarAve(pts[0].fY, pts[1].fY)); 74 return SkGradientShader::CreateRadial(center, center.fX, data.fColors, 75 data.fPos, data.fCount, tm, mapper); 76} 77 78static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, 79 SkShader::TileMode tm, SkUnitMapper* mapper) { 80 SkPoint center; 81 center.set(SkScalarAve(pts[0].fX, pts[1].fX), 82 SkScalarAve(pts[0].fY, pts[1].fY)); 83 return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, 84 data.fPos, data.fCount, mapper); 85} 86 87static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, 88 SkShader::TileMode tm, SkUnitMapper* mapper) { 89 SkPoint center0, center1; 90 center0.set(SkScalarAve(pts[0].fX, pts[1].fX), 91 SkScalarAve(pts[0].fY, pts[1].fY)); 92 center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5), 93 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4)); 94 return SkGradientShader::CreateTwoPointRadial( 95 center1, (pts[1].fX - pts[0].fX) / 7, 96 center0, (pts[1].fX - pts[0].fX) / 2, 97 data.fColors, data.fPos, data.fCount, tm, mapper); 98} 99 100typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, 101 SkShader::TileMode tm, SkUnitMapper* mapper); 102static const GradMaker gGradMakers[] = { 103 MakeLinear, MakeRadial, MakeSweep, Make2Radial 104}; 105 106/////////////////////////////////////////////////////////////////////////////// 107 108class ShaderTextView : public SampleView { 109public: 110 ShaderTextView() { 111 this->setBGColor(0xFFDDDDDD); 112 } 113 114protected: 115 // overrides from SkEventSink 116 virtual bool onQuery(SkEvent* evt) { 117 if (SampleCode::TitleQ(*evt)) { 118 SampleCode::TitleR(evt, "Shader Text"); 119 return true; 120 } 121 return this->INHERITED::onQuery(evt); 122 } 123 124 virtual void onDrawContent(SkCanvas* canvas) { 125 const char text[] = "Shaded Text"; 126 const int textLen = SK_ARRAY_COUNT(text) - 1; 127 static int pointSize = 36; 128 129 int w = pointSize * textLen; 130 int h = pointSize; 131 132 SkPoint pts[2] = { 133 { 0, 0 }, 134 { SkIntToScalar(w), SkIntToScalar(h) } 135 }; 136 SkScalar textBase = SkIntToScalar(h/2); 137 138 SkShader::TileMode tileModes[] = { 139 SkShader::kClamp_TileMode, 140 SkShader::kRepeat_TileMode, 141 SkShader::kMirror_TileMode 142 }; 143 144 static const int gradCount = SK_ARRAY_COUNT(gGradData) * 145 SK_ARRAY_COUNT(gGradMakers); 146 static const int bmpCount = SK_ARRAY_COUNT(tileModes) * 147 SK_ARRAY_COUNT(tileModes); 148 SkShader* shaders[gradCount + bmpCount]; 149 150 int shdIdx = 0; 151 for (size_t d = 0; d < SK_ARRAY_COUNT(gGradData); ++d) { 152 for (size_t m = 0; m < SK_ARRAY_COUNT(gGradMakers); ++m) { 153 shaders[shdIdx++] = gGradMakers[m](pts, 154 gGradData[d], 155 SkShader::kClamp_TileMode, 156 NULL); 157 } 158 } 159 for (size_t tx = 0; tx < SK_ARRAY_COUNT(tileModes); ++tx) { 160 for (size_t ty = 0; ty < SK_ARRAY_COUNT(tileModes); ++ty) { 161 shaders[shdIdx++] = MakeBitmapShader(tileModes[tx], 162 tileModes[ty], 163 w/8, h); 164 } 165 } 166 167 SkPaint paint; 168 paint.setDither(true); 169 paint.setAntiAlias(true); 170 paint.setTextSize(SkIntToScalar(pointSize)); 171 172 canvas->save(); 173 canvas->translate(SkIntToScalar(20), SkIntToScalar(10)); 174 175 SkPath path; 176 path.arcTo(SkRect::MakeXYWH(SkIntToScalar(-40), SkIntToScalar(15), 177 SkIntToScalar(300), SkIntToScalar(90)), 178 SkIntToScalar(225), SkIntToScalar(90), 179 false); 180 path.close(); 181 182 static const int testsPerCol = 8; 183 static const int rowHeight = 60; 184 static const int colWidth = 300; 185 canvas->save(); 186 for (size_t s = 0; s < SK_ARRAY_COUNT(shaders); s++) { 187 canvas->save(); 188 size_t i = 2*s; 189 canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth), 190 SkIntToScalar((i % testsPerCol) * rowHeight)); 191 paint.setShader(shaders[s])->unref(); 192 canvas->drawText(text, textLen, 0, textBase, paint); 193 canvas->restore(); 194 canvas->save(); 195 ++i; 196 canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth), 197 SkIntToScalar((i % testsPerCol) * rowHeight)); 198 canvas->drawTextOnPath(text, textLen, path, NULL, paint); 199 canvas->restore(); 200 } 201 canvas->restore(); 202 203 canvas->translate(0, SkIntToScalar(370)); 204 this->inval(NULL); 205 } 206 207private: 208 typedef SampleView INHERITED; 209}; 210 211/////////////////////////////////////////////////////////////////////////////// 212 213static SkView* MyFactory() { return new ShaderTextView; } 214static SkViewRegister reg(MyFactory); 215