Add shaded text sample and gm test.



git-svn-id: http://skia.googlecode.com/svn/trunk@725 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/samplecode/SampleShaderText.cpp b/samplecode/SampleShaderText.cpp
new file mode 100644
index 0000000..36692d2
--- /dev/null
+++ b/samplecode/SampleShaderText.cpp
@@ -0,0 +1,199 @@
+#include "SampleCode.h"
+#include "SkView.h"
+#include "SkCanvas.h"
+#include "SkGradientShader.h"
+#include "SkUnitMappers.h"
+
+static void makebm(SkBitmap* bm, SkBitmap::Config config, int w, int h) {
+    bm->setConfig(config, w, h);
+    bm->allocPixels();
+    bm->eraseColor(0);
+
+    SkCanvas    canvas(*bm);
+    SkScalar s = w < h ? w : h;
+    SkPoint     pts[] = { 0, 0, s, s };
+    SkColor     colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
+    SkScalar    pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
+    SkPaint     paint;
+
+    SkUnitMapper*   um = NULL;
+
+    um = new SkCosineMapper;
+
+    SkAutoUnref au(um);
+
+    paint.setDither(true);
+    paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos,
+                SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode, um))->unref();
+    canvas.drawPaint(paint);
+}
+
+SkShader* MakeBitmapShader(SkShader::TileMode tx, SkShader::TileMode ty,
+                           int w, int h) {
+    static SkBitmap bmp;
+    if (bmp.isNull()) {
+        makebm(&bmp, SkBitmap::kARGB_8888_Config, w/2, h/4);
+    }
+    return SkShader::CreateBitmapShader(bmp, tx, ty);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+struct GradData {
+    int             fCount;
+    const SkColor*  fColors;
+    const SkScalar* fPos;
+};
+
+static const SkColor gColors[] = {
+    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
+};
+
+static const GradData gGradData[] = {
+    { 2, gColors, NULL },
+    { 5, gColors, NULL },
+};
+
+static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data,
+                            SkShader::TileMode tm, SkUnitMapper* mapper) {
+    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos,
+                                          data.fCount, tm, mapper);
+}
+
+static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data,
+                            SkShader::TileMode tm, SkUnitMapper* mapper) {
+    SkPoint center;
+    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
+               SkScalarAve(pts[0].fY, pts[1].fY));
+    return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
+                                          data.fPos, data.fCount, tm, mapper);
+}
+
+static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
+                           SkShader::TileMode tm, SkUnitMapper* mapper) {
+    SkPoint center;
+    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
+               SkScalarAve(pts[0].fY, pts[1].fY));
+    return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors,
+                                         data.fPos, data.fCount, mapper);
+}
+
+static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data,
+                           SkShader::TileMode tm, SkUnitMapper* mapper) {
+    SkPoint center0, center1;
+    center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
+                SkScalarAve(pts[0].fY, pts[1].fY));
+    center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
+                SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
+    return SkGradientShader::CreateTwoPointRadial(
+                            center1, (pts[1].fX - pts[0].fX) / 7,
+                            center0, (pts[1].fX - pts[0].fX) / 2,
+                            data.fColors, data.fPos, data.fCount, tm, mapper);
+}
+
+typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data,
+                     SkShader::TileMode tm, SkUnitMapper* mapper);
+static const GradMaker gGradMakers[] = {
+    MakeLinear, MakeRadial, MakeSweep, Make2Radial
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class ShaderTextView : public SkView {
+public:
+	ShaderTextView() {}
+
+protected:
+    // overrides from SkEventSink
+    virtual bool onQuery(SkEvent* evt) {
+        if (SampleCode::TitleQ(*evt)) {
+            SampleCode::TitleR(evt, "Shader Text");
+            return true;
+        }
+        return this->INHERITED::onQuery(evt);
+    }
+
+    void drawBG(SkCanvas* canvas) {
+        canvas->drawColor(0xFFDDDDDD);
+    }
+
+    virtual void onDraw(SkCanvas* canvas) {
+        this->drawBG(canvas);
+
+        const char text[] = "Shaded Text";
+        const int textLen = SK_ARRAY_COUNT(text) - 1;
+        static int pointSize = SkIntToScalar(48);
+
+        int w = pointSize * textLen;
+        int h = pointSize;
+
+        SkPoint pts[2] = {
+            { 0, 0 },
+            { SkIntToScalar(w), SkIntToScalar(h) }
+        };
+        SkScalar textBase = SkIntToScalar(h/2);
+
+        SkShader::TileMode tileModes[] = {
+            SkShader::kClamp_TileMode,
+            SkShader::kRepeat_TileMode,
+            SkShader::kMirror_TileMode
+        };
+
+        static const int gradCount = SK_ARRAY_COUNT(gGradData) *
+                                     SK_ARRAY_COUNT(gGradMakers);
+        static const int bmpCount = SK_ARRAY_COUNT(tileModes) *
+                                    SK_ARRAY_COUNT(tileModes);
+        SkShader* shaders[gradCount + bmpCount];
+
+        int shdIdx = 0;
+        for (size_t d = 0; d < SK_ARRAY_COUNT(gGradData); ++d) {
+            for (size_t m = 0; m < SK_ARRAY_COUNT(gGradMakers); ++m) {
+                shaders[shdIdx++] = gGradMakers[m](pts,
+                                                   gGradData[d],
+                                                   SkShader::kClamp_TileMode,
+                                                   NULL);
+            }
+        }
+        for (size_t tx = 0; tx < SK_ARRAY_COUNT(tileModes); ++tx) {
+            for (size_t ty = 0; ty < SK_ARRAY_COUNT(tileModes); ++ty) {
+                shaders[shdIdx++] = MakeBitmapShader(tileModes[tx],
+                                                     tileModes[ty],
+                                                     w/8, h);
+            }
+        }
+
+        SkPaint paint;
+        paint.setDither(true);
+        paint.setAntiAlias(true);
+        paint.setTextSize(SkIntToScalar(pointSize));
+
+        canvas->save();
+        canvas->translate(SkIntToScalar(20), SkIntToScalar(10));
+
+        static const int testsPerCol = 8;
+        static const int rowHeight = 60;
+        static const int colWidth = 300;
+        canvas->save();
+        for (size_t s = 0; s < SK_ARRAY_COUNT(shaders); s++) {
+            canvas->save();
+            canvas->translate(SkIntToScalar((s / testsPerCol) * colWidth),
+                              SkIntToScalar((s % testsPerCol) * rowHeight));
+                              paint.setShader(shaders[s])->ref();
+            canvas->drawText(text, textLen, 0, textBase, paint);
+            canvas->restore();
+        }
+        canvas->restore();
+
+        canvas->translate(0, SkIntToScalar(370));
+        this->inval(NULL);
+    }
+
+private:
+    typedef SkView INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new ShaderTextView; }
+static SkViewRegister reg(MyFactory);
+