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