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 #include "SampleCode.h"
      8 #include "SkBlurMask.h"
      9 #include "SkCanvas.h"
     10 #include "SkView.h"
     11 #include "Sk1DPathEffect.h"
     12 #include "Sk2DPathEffect.h"
     13 #include "SkBlurMaskFilter.h"
     14 #include "SkColorMatrixFilter.h"
     15 #include "SkColorPriv.h"
     16 #include "SkCornerPathEffect.h"
     17 #include "SkDashPathEffect.h"
     18 #include "SkDiscretePathEffect.h"
     19 #include "SkEmbossMaskFilter.h"
     20 #include "SkReadBuffer.h"
     21 #include "SkWriteBuffer.h"
     22 #include "SkGradientShader.h"
     23 #include "SkLayerRasterizer.h"
     24 #include "SkMath.h"
     25 #include "SkPath.h"
     26 #include "SkPictureRecorder.h"
     27 #include "SkRegion.h"
     28 #include "SkShader.h"
     29 #include "SkCornerPathEffect.h"
     30 #include "SkPathMeasure.h"
     31 #include "SkPicture.h"
     32 #include "SkRandom.h"
     33 #include "SkTypeface.h"
     34 #include "SkUtils.h"
     35 
     36 #include <math.h>
     37 #include "DecodeFile.h"
     38 
     39 static inline SkPMColor rgb2gray(SkPMColor c) {
     40     unsigned r = SkGetPackedR32(c);
     41     unsigned g = SkGetPackedG32(c);
     42     unsigned b = SkGetPackedB32(c);
     43 
     44     unsigned x = (r * 5 + g * 7 + b * 4) >> 4;
     45 
     46     return SkPackARGB32(0, x, x, x) | (c & (SK_A32_MASK << SK_A32_SHIFT));
     47 }
     48 
     49 class SkGrayScaleColorFilter : public SkColorFilter {
     50 public:
     51     virtual void filterSpan(const SkPMColor src[], int count,
     52                             SkPMColor result[]) const override {
     53         for (int i = 0; i < count; i++)
     54             result[i] = rgb2gray(src[i]);
     55     }
     56 };
     57 
     58 class SkChannelMaskColorFilter : public SkColorFilter {
     59 public:
     60     SkChannelMaskColorFilter(U8CPU redMask, U8CPU greenMask, U8CPU blueMask) {
     61         fMask = SkPackARGB32(0xFF, redMask, greenMask, blueMask);
     62     }
     63 
     64     virtual void filterSpan(const SkPMColor src[], int count,
     65                             SkPMColor result[]) const override {
     66         SkPMColor mask = fMask;
     67         for (int i = 0; i < count; i++) {
     68             result[i] = src[i] & mask;
     69         }
     70     }
     71 
     72 private:
     73     SkPMColor   fMask;
     74 };
     75 
     76 ///////////////////////////////////////////////////////////
     77 
     78 static void r0(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
     79     p.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
     80                                            SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)),
     81                                            SkBlurMaskFilter::kNone_BlurFlag));
     82     rastBuilder->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
     83 
     84     p.setMaskFilter(nullptr);
     85     p.setStyle(SkPaint::kStroke_Style);
     86     p.setStrokeWidth(SK_Scalar1);
     87     rastBuilder->addLayer(p);
     88 
     89     p.setAlpha(0x11);
     90     p.setStyle(SkPaint::kFill_Style);
     91     p.setBlendMode(SkBlendMode::kSrc);
     92     rastBuilder->addLayer(p);
     93 }
     94 
     95 static void r1(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
     96     rastBuilder->addLayer(p);
     97 
     98     p.setAlpha(0x40);
     99     p.setBlendMode(SkBlendMode::kSrc);
    100     p.setStyle(SkPaint::kStroke_Style);
    101     p.setStrokeWidth(SK_Scalar1*2);
    102     rastBuilder->addLayer(p);
    103 }
    104 
    105 static void r2(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
    106     p.setStyle(SkPaint::kStrokeAndFill_Style);
    107     p.setStrokeWidth(SK_Scalar1*4);
    108     rastBuilder->addLayer(p);
    109 
    110     p.setStyle(SkPaint::kStroke_Style);
    111     p.setStrokeWidth(SK_Scalar1*3/2);
    112     p.setBlendMode(SkBlendMode::kClear);
    113     rastBuilder->addLayer(p);
    114 }
    115 
    116 static void r3(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
    117     p.setStyle(SkPaint::kStroke_Style);
    118     p.setStrokeWidth(SK_Scalar1*3);
    119     rastBuilder->addLayer(p);
    120 
    121     p.setAlpha(0x20);
    122     p.setStyle(SkPaint::kFill_Style);
    123     p.setBlendMode(SkBlendMode::kSrc);
    124     rastBuilder->addLayer(p);
    125 }
    126 
    127 static void r4(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
    128     p.setAlpha(0x60);
    129     rastBuilder->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
    130 
    131     p.setAlpha(0xFF);
    132     p.setBlendMode(SkBlendMode::kClear);
    133     rastBuilder->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2);
    134 
    135     p.setBlendMode(SkBlendMode::kSrcOver);
    136     rastBuilder->addLayer(p);
    137 }
    138 
    139 static void r5(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
    140     rastBuilder->addLayer(p);
    141 
    142     p.setPathEffect(SkDiscretePathEffect::Make(SK_Scalar1*4, SK_Scalar1*3));
    143     p.setBlendMode(SkBlendMode::kSrcOut);
    144     rastBuilder->addLayer(p);
    145 }
    146 
    147 static void r6(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
    148     rastBuilder->addLayer(p);
    149 
    150     p.setAntiAlias(false);
    151     SkLayerRasterizer::Builder rastBuilder2;
    152     r5(&rastBuilder2, p);
    153     p.setRasterizer(rastBuilder2.detach());
    154     p.setBlendMode(SkBlendMode::kClear);
    155     rastBuilder->addLayer(p);
    156 }
    157 
    158 class Dot2DPathEffect : public Sk2DPathEffect {
    159 public:
    160     Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix)
    161         : Sk2DPathEffect(matrix), fRadius(radius) {}
    162 
    163     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Dot2DPathEffect)
    164 
    165 protected:
    166     void next(const SkPoint& loc, int u, int v, SkPath* dst) const override {
    167         dst->addCircle(loc.fX, loc.fY, fRadius);
    168     }
    169 
    170     void flatten(SkWriteBuffer& buffer) const override {
    171         this->INHERITED::flatten(buffer);
    172         buffer.writeScalar(fRadius);
    173     }
    174 
    175 private:
    176     SkScalar fRadius;
    177 
    178     typedef Sk2DPathEffect INHERITED;
    179 };
    180 
    181 static void r7(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
    182     SkMatrix    lattice;
    183     lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
    184     lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
    185     p.setPathEffect(sk_make_sp<Dot2DPathEffect>(SK_Scalar1*4, lattice));
    186     rastBuilder->addLayer(p);
    187 }
    188 
    189 static void r8(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
    190     rastBuilder->addLayer(p);
    191 
    192     SkMatrix    lattice;
    193     lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
    194     lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
    195     p.setPathEffect(sk_make_sp<Dot2DPathEffect>(SK_Scalar1*2, lattice));
    196     p.setBlendMode(SkBlendMode::kClear);
    197     rastBuilder->addLayer(p);
    198 
    199     p.setPathEffect(nullptr);
    200     p.setBlendMode(SkBlendMode::kSrcOver);
    201     p.setStyle(SkPaint::kStroke_Style);
    202     p.setStrokeWidth(SK_Scalar1);
    203     rastBuilder->addLayer(p);
    204 }
    205 
    206 static void r9(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
    207     rastBuilder->addLayer(p);
    208 
    209     SkMatrix    lattice;
    210     lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0);
    211     lattice.postRotate(SkIntToScalar(30), 0, 0);
    212     p.setPathEffect(SkLine2DPathEffect::Make(SK_Scalar1*2, lattice));
    213     p.setBlendMode(SkBlendMode::kClear);
    214     rastBuilder->addLayer(p);
    215 
    216     p.setPathEffect(nullptr);
    217     p.setBlendMode(SkBlendMode::kSrcOver);
    218     p.setStyle(SkPaint::kStroke_Style);
    219     p.setStrokeWidth(SK_Scalar1);
    220     rastBuilder->addLayer(p);
    221 }
    222 
    223 typedef void (*raster_proc)(SkLayerRasterizer::Builder*, SkPaint&);
    224 
    225 static const raster_proc gRastProcs[] = {
    226     r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
    227 };
    228 
    229 static const struct {
    230     SkColor fMul, fAdd;
    231 } gLightingColors[] = {
    232     { 0x808080, 0x800000 }, // general case
    233     { 0x707070, 0x707070 }, // no-pin case
    234     { 0xFFFFFF, 0x800000 }, // just-add case
    235     { 0x808080, 0x000000 }, // just-mul case
    236     { 0xFFFFFF, 0x000000 }  // identity case
    237 };
    238 
    239 static void apply_shader(SkPaint* paint, int index) {
    240     raster_proc proc = gRastProcs[index];
    241     if (proc) {
    242         SkPaint p;
    243         SkLayerRasterizer::Builder rastBuilder;
    244 
    245         p.setAntiAlias(true);
    246         proc(&rastBuilder, p);
    247         paint->setRasterizer(rastBuilder.detach());
    248     }
    249 
    250 #ifdef SK_SUPPORT_LEGACY_EMBOSSMASKFILTER
    251     SkScalar dir[] = { SK_Scalar1, SK_Scalar1, SK_Scalar1 };
    252     paint->setMaskFilter(SkBlurMaskFilter::MakeEmboss(
    253                 SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)), dir,
    254                 SK_Scalar1/4, SkIntToScalar(4)));
    255     paint->setColor(SK_ColorBLUE);
    256 #endif
    257 }
    258 
    259 class DemoView : public SampleView {
    260 public:
    261     DemoView() {}
    262 
    263 protected:
    264     // overrides from SkEventSink
    265     virtual bool onQuery(SkEvent* evt) {
    266         if (SampleCode::TitleQ(*evt)) {
    267             SampleCode::TitleR(evt, "Demo");
    268             return true;
    269         }
    270         return this->INHERITED::onQuery(evt);
    271     }
    272 
    273     virtual bool onClick(Click* click) {
    274         return this->INHERITED::onClick(click);
    275     }
    276 
    277     void makePath(SkPath& path) {
    278         path.addCircle(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(20),
    279             SkPath::kCCW_Direction);
    280         for (int index = 0; index < 10; index++) {
    281             SkScalar x = (float) cos(index / 10.0f * 2 * 3.1415925358f);
    282             SkScalar y = (float) sin(index / 10.0f * 2 * 3.1415925358f);
    283             x *= index & 1 ? 7 : 14;
    284             y *= index & 1 ? 7 : 14;
    285             x += SkIntToScalar(20);
    286             y += SkIntToScalar(20);
    287             if (index == 0)
    288                 path.moveTo(x, y);
    289             else
    290                 path.lineTo(x, y);
    291         }
    292         path.close();
    293     }
    294 
    295     virtual void onDrawContent(SkCanvas* canvas) {
    296         canvas->save();
    297         this->drawPicture(canvas, 0);
    298         canvas->restore();
    299 
    300         {
    301             SkPictureRecorder recorder;
    302             {
    303                 SkCanvas* record = recorder.beginRecording(320, 480, nullptr, 0);
    304                 this->drawPicture(record, 120);
    305             }
    306             sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
    307 
    308             canvas->translate(0, SkIntToScalar(120));
    309 
    310             SkRect clip;
    311             clip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
    312             do {
    313                 canvas->save();
    314                 canvas->clipRect(clip);
    315                 picture->playback(canvas);
    316                 canvas->restore();
    317                 if (clip.fRight < SkIntToScalar(320))
    318                     clip.offset(SkIntToScalar(160), 0);
    319                 else if (clip.fBottom < SkIntToScalar(480))
    320                     clip.offset(-SkIntToScalar(320), SkIntToScalar(160));
    321                 else
    322                     break;
    323             } while (true);
    324         }
    325     }
    326 
    327     void drawPicture(SkCanvas* canvas, int spriteOffset) {
    328         SkMatrix matrix; matrix.reset();
    329         SkPaint paint;
    330         SkPath path;
    331         SkPoint start = {0, 0};
    332         SkPoint stop = { SkIntToScalar(40), SkIntToScalar(40) };
    333         SkRect rect = {0, 0, SkIntToScalar(40), SkIntToScalar(40) };
    334         SkRect rect2 = {0, 0, SkIntToScalar(65), SkIntToScalar(20) };
    335         SkScalar left = 0, top = 0, x = 0, y = 0;
    336         int index;
    337 
    338         char ascii[] = "ascii...";
    339         int asciiLength = sizeof(ascii) - 1;
    340         char utf8[] = "utf8" "\xe2\x80\xa6";
    341         short utf16[] = {'u', 't', 'f', '1', '6', 0x2026 };
    342         short utf16simple[] = {'u', 't', 'f', '1', '6', '!' };
    343 
    344         makePath(path);
    345         SkTDArray<SkPoint>(pos);
    346         pos.setCount(asciiLength);
    347         for (index = 0;  index < asciiLength; index++)
    348             pos[index].set(SkIntToScalar((unsigned int)index * 10),
    349                                        SkIntToScalar((unsigned int)index * 2));
    350         SkTDArray<SkPoint>(pos2);
    351         pos2.setCount(asciiLength);
    352         for (index = 0;  index < asciiLength; index++)
    353             pos2[index].set(SkIntToScalar((unsigned int)index * 10),
    354                                         SkIntToScalar(20));
    355 
    356         // shaders
    357         SkPoint linearPoints[] = { { 0, 0, }, { SkIntToScalar(40), SkIntToScalar(40) } };
    358         SkColor linearColors[] = { SK_ColorRED, SK_ColorBLUE };
    359         SkScalar* linearPos = nullptr;
    360         int linearCount = 2;
    361         SkShader::TileMode linearMode = SkShader::kMirror_TileMode;
    362         auto linear = SkGradientShader::MakeLinear(linearPoints,
    363             linearColors, linearPos, linearCount, linearMode);
    364 
    365         SkPoint radialCenter = { SkIntToScalar(25), SkIntToScalar(25) };
    366         SkScalar radialRadius = SkIntToScalar(25);
    367         SkColor radialColors[] = { SK_ColorGREEN, SK_ColorGRAY, SK_ColorRED };
    368         SkScalar radialPos[] = { 0, SkIntToScalar(3) / 5, SkIntToScalar(1)};
    369         int radialCount = 3;
    370         SkShader::TileMode radialMode = SkShader::kRepeat_TileMode;
    371         auto radial = SkGradientShader::MakeRadial(radialCenter,
    372             radialRadius, radialColors, radialPos, radialCount,
    373             radialMode);
    374 
    375         SkEmbossMaskFilter::Light light;
    376         light.fDirection[0] = SK_Scalar1/2;
    377         light.fDirection[1] = SK_Scalar1/2;
    378         light.fDirection[2] = SK_Scalar1/3;
    379         light.fAmbient        = 0x48;
    380         light.fSpecular        = 0x80;
    381 
    382         auto lightingFilter = SkColorMatrixFilter::MakeLightingFilter(
    383             0xff89bc45, 0xff112233);
    384 
    385         canvas->save();
    386         canvas->translate(SkIntToScalar(0), SkIntToScalar(5));
    387         paint.setAntiAlias(true);
    388         paint.setFilterQuality(kLow_SkFilterQuality);
    389         // !!! draw through a clip
    390         paint.setColor(SK_ColorLTGRAY);
    391         paint.setStyle(SkPaint::kFill_Style);
    392         SkRect clip = {0, 0, SkIntToScalar(320), SkIntToScalar(120)};
    393         canvas->clipRect(clip);
    394         paint.setShader(SkShader::MakeBitmapShader(fTx,
    395             SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode));
    396         canvas->drawPaint(paint);
    397         canvas->save();
    398 
    399         // line (exercises xfermode, colorShader, colorFilter, filterShader)
    400         paint.setColor(SK_ColorGREEN);
    401         paint.setStrokeWidth(SkIntToScalar(10));
    402         paint.setStyle(SkPaint::kStroke_Style);
    403         paint.setBlendMode(SkBlendMode::kXor);
    404         paint.setColorFilter(lightingFilter);
    405         canvas->drawLine(start.fX, start.fY, stop.fX, stop.fY, paint); // should not be green
    406         paint.setBlendMode(SkBlendMode::kSrcOver);
    407         paint.setColorFilter(nullptr);
    408 
    409         // rectangle
    410         paint.setStyle(SkPaint::kFill_Style);
    411         canvas->translate(SkIntToScalar(50), 0);
    412         paint.setColor(SK_ColorYELLOW);
    413         paint.setShader(linear);
    414         paint.setPathEffect(pathEffectTest());
    415         canvas->drawRect(rect, paint);
    416         paint.setPathEffect(nullptr);
    417 
    418         // circle w/ emboss & transparent (exercises 3dshader)
    419         canvas->translate(SkIntToScalar(50), 0);
    420         paint.setMaskFilter(SkEmbossMaskFilter::Make(
    421                                      SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(12)/5), light));
    422         canvas->drawOval(rect, paint);
    423         canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
    424 //        paint.setShader(transparentShader)->unref();
    425         canvas->drawOval(rect, paint);
    426         canvas->translate(0, SkIntToScalar(-10));
    427 
    428         // path
    429         canvas->translate(SkIntToScalar(50), 0);
    430         paint.setColor(SK_ColorRED);
    431         paint.setStyle(SkPaint::kStroke_Style);
    432         paint.setStrokeWidth(SkIntToScalar(5));
    433         paint.setShader(radial);
    434         paint.setMaskFilter(nullptr);
    435         canvas->drawPath(path, paint);
    436 
    437         paint.setShader(nullptr);
    438         // bitmap
    439         canvas->translate(SkIntToScalar(50), 0);
    440         paint.setStyle(SkPaint::kFill_Style);
    441         canvas->drawBitmap(fBug, left, top, &paint);
    442 
    443         canvas->translate(-SkIntToScalar(30), SkIntToScalar(30));
    444         paint.setShader(shaderTest()); // test compose shader
    445         canvas->drawRect(rect2, paint);
    446         paint.setShader(nullptr);
    447 
    448         canvas->restore();
    449         // text
    450         canvas->translate(0, SkIntToScalar(60));
    451         canvas->save();
    452         paint.setColor(SK_ColorGRAY);
    453         canvas->drawPosText(ascii, asciiLength, pos.begin(), paint);
    454         canvas->drawPosText(ascii, asciiLength, pos2.begin(), paint);
    455 
    456         canvas->translate(SkIntToScalar(50), 0);
    457         paint.setColor(SK_ColorCYAN);
    458         canvas->drawText(utf8, sizeof(utf8) - 1, x, y, paint);
    459 
    460         canvas->translate(SkIntToScalar(30), 0);
    461         paint.setColor(SK_ColorMAGENTA);
    462         paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
    463         matrix.setTranslate(SkIntToScalar(10), SkIntToScalar(10));
    464         canvas->drawTextOnPath((void*) utf16, sizeof(utf16), path, &matrix, paint);
    465         canvas->translate(0, SkIntToScalar(20));
    466         canvas->drawTextOnPath((void*) utf16simple, sizeof(utf16simple), path, &matrix, paint);
    467         canvas->restore();
    468 
    469         canvas->translate(0, SkIntToScalar(60));
    470         paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
    471         canvas->restore();
    472     }
    473 
    474     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
    475         fClickPt.set(x, y);
    476         this->inval(nullptr);
    477         return this->INHERITED::onFindClickHandler(x, y, modi);
    478     }
    479 
    480     sk_sp<SkPathEffect> pathEffectTest() {
    481         static const int gXY[] = { 1, 0, 0, -1, 2, -1, 3, 0, 2, 1, 0, 1 };
    482         SkScalar gPhase = 0;
    483         SkPath path;
    484         path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
    485         for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
    486             path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
    487         path.close();
    488         path.offset(SkIntToScalar(-6), 0);
    489         auto outer = SkPath1DPathEffect::Make(path, SkIntToScalar(12),
    490             gPhase, SkPath1DPathEffect::kRotate_Style);
    491         auto inner = SkDiscretePathEffect::Make(SkIntToScalar(2),
    492             SkIntToScalar(1)/10); // SkCornerPathEffect(SkIntToScalar(2));
    493         return SkPathEffect::MakeCompose(outer, inner);
    494     }
    495 
    496     sk_sp<SkShader> shaderTest() {
    497         SkPoint pts[] = { { 0, 0, }, { SkIntToScalar(100), 0 } };
    498         SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
    499         auto shaderA = SkGradientShader::MakeLinear(pts, colors, nullptr,
    500             2, SkShader::kClamp_TileMode);
    501         pts[1].set(0, SkIntToScalar(100));
    502         SkColor colors2[] = {SK_ColorBLACK,  SkColorSetARGB(0x80, 0, 0, 0)};
    503         auto shaderB = SkGradientShader::MakeLinear(pts, colors2, nullptr,
    504             2, SkShader::kClamp_TileMode);
    505         return SkShader::MakeComposeShader(std::move(shaderA), std::move(shaderB),
    506                                            SkBlendMode::kDstIn);
    507     }
    508 
    509     virtual void startTest() {
    510         decode_file("/Users/caryclark/Desktop/bugcirc.gif", &fBug);
    511         decode_file("/Users/caryclark/Desktop/tbcirc.gif", &fTb);
    512         decode_file("/Users/caryclark/Desktop/05psp04.gif", &fTx);
    513     }
    514 
    515     void drawRaster(SkCanvas* canvas)  {
    516         for (size_t index = 0; index < SK_ARRAY_COUNT(gRastProcs); index++)
    517             drawOneRaster(canvas);
    518     }
    519 
    520     void drawOneRaster(SkCanvas* canvas) {
    521         canvas->save();
    522 
    523         SkScalar    x = SkIntToScalar(20);
    524         SkScalar    y = SkIntToScalar(40);
    525         SkPaint     paint;
    526 
    527         paint.setAntiAlias(true);
    528         paint.setTextSize(SkIntToScalar(48));
    529         paint.setTypeface(SkTypeface::MakeFromName("sans-serif",
    530                                                    SkFontStyle::FromOldStyle(SkTypeface::kBold)));
    531 
    532         SkString str("GOOGLE");
    533 
    534         for (size_t i = 0; i < SK_ARRAY_COUNT(gRastProcs); i++) {
    535             apply_shader(&paint, (int)i);
    536 
    537           //  paint.setMaskFilter(nullptr);
    538           //  paint.setColor(SK_ColorBLACK);
    539 
    540 #if 01
    541             int index = i % SK_ARRAY_COUNT(gLightingColors);
    542             paint.setColorFilter(SkColorMatrixFilter::MakeLightingFilter(
    543                                     gLightingColors[index].fMul,
    544                                     gLightingColors[index].fAdd));
    545 #endif
    546 
    547             canvas->drawText(str.c_str(), str.size(), x, y, paint);
    548             SkRect  oval = { x, y - SkIntToScalar(40), x + SkIntToScalar(40), y };
    549             paint.setStyle(SkPaint::kStroke_Style);
    550             canvas->drawOval(oval, paint);
    551             paint.setStyle(SkPaint::kFill_Style);
    552 
    553             y += paint.getFontSpacing();
    554         }
    555 
    556         canvas->restore();
    557     }
    558 
    559 private:
    560     SkPoint fClickPt;
    561     SkBitmap fBug, fTb, fTx;
    562     typedef SampleView INHERITED;
    563 };
    564 
    565 //////////////////////////////////////////////////////////////////////////////
    566 
    567 static SkView* MyFactory() { return new DemoView; }
    568 static SkViewRegister reg(MyFactory);
    569