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