
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SampleCode.h"
#include "SkBlurMask.h"
#include "SkCanvas.h"
#include "SkView.h"
#include "Sk1DPathEffect.h"
#include "Sk2DPathEffect.h"
#include "SkAvoidXfermode.h"
#include "SkBlurMaskFilter.h"
#include "SkColorFilter.h"
#include "SkColorPriv.h"
#include "SkCornerPathEffect.h"
#include "SkDashPathEffect.h"
#include "SkDiscretePathEffect.h"
#include "SkEmbossMaskFilter.h"
#include "SkFlattenableBuffers.h"
#include "SkGradientShader.h"
#include "SkImageDecoder.h"
#include "SkLayerRasterizer.h"
#include "SkMath.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkComposeShader.h"
#include "SkCornerPathEffect.h"
#include "SkPathMeasure.h"
#include "SkPicture.h"
#include "SkRandom.h"
#include "SkTransparentShader.h"
#include "SkTypeface.h"
#include "SkUnitMappers.h"
#include "SkUtils.h"
#include "SkXfermode.h"

#include <math.h>

static inline SkPMColor rgb2gray(SkPMColor c) {
    unsigned r = SkGetPackedR32(c);
    unsigned g = SkGetPackedG32(c);
    unsigned b = SkGetPackedB32(c);

    unsigned x = (r * 5 + g * 7 + b * 4) >> 4;

    return SkPackARGB32(0, x, x, x) | (c & (SK_A32_MASK << SK_A32_SHIFT));
}

class SkGrayScaleColorFilter : public SkColorFilter {
public:
    virtual void filterSpan(const SkPMColor src[], int count,
                            SkPMColor result[]) const SK_OVERRIDE {
        for (int i = 0; i < count; i++)
            result[i] = rgb2gray(src[i]);
    }
};

class SkChannelMaskColorFilter : public SkColorFilter {
public:
    SkChannelMaskColorFilter(U8CPU redMask, U8CPU greenMask, U8CPU blueMask) {
        fMask = SkPackARGB32(0xFF, redMask, greenMask, blueMask);
    }

    virtual void filterSpan(const SkPMColor src[], int count,
                            SkPMColor result[]) const SK_OVERRIDE {
        SkPMColor mask = fMask;
        for (int i = 0; i < count; i++) {
            result[i] = src[i] & mask;
        }
    }

private:
    SkPMColor   fMask;
};

///////////////////////////////////////////////////////////

static void r0(SkLayerRasterizer* rast, SkPaint& p) {
    p.setMaskFilter(SkBlurMaskFilter::Create(SkBlurMaskFilter::kNormal_BlurStyle,
                                             SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)),
                                             SkBlurMaskFilter::kNone_BlurFlag))->unref();
    rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));

    p.setMaskFilter(NULL);
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(SK_Scalar1);
    rast->addLayer(p);

    p.setAlpha(0x11);
    p.setStyle(SkPaint::kFill_Style);
    p.setXfermodeMode(SkXfermode::kSrc_Mode);
    rast->addLayer(p);
}

static void r1(SkLayerRasterizer* rast, SkPaint& p) {
    rast->addLayer(p);

    p.setAlpha(0x40);
    p.setXfermodeMode(SkXfermode::kSrc_Mode);
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(SK_Scalar1*2);
    rast->addLayer(p);
}

static void r2(SkLayerRasterizer* rast, SkPaint& p) {
    p.setStyle(SkPaint::kStrokeAndFill_Style);
    p.setStrokeWidth(SK_Scalar1*4);
    rast->addLayer(p);

    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(SK_Scalar1*3/2);
    p.setXfermodeMode(SkXfermode::kClear_Mode);
    rast->addLayer(p);
}

static void r3(SkLayerRasterizer* rast, SkPaint& p) {
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(SK_Scalar1*3);
    rast->addLayer(p);

    p.setAlpha(0x20);
    p.setStyle(SkPaint::kFill_Style);
    p.setXfermodeMode(SkXfermode::kSrc_Mode);
    rast->addLayer(p);
}

static void r4(SkLayerRasterizer* rast, SkPaint& p) {
    p.setAlpha(0x60);
    rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));

    p.setAlpha(0xFF);
    p.setXfermodeMode(SkXfermode::kClear_Mode);
    rast->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2);

    p.setXfermode(NULL);
    rast->addLayer(p);
}

static void r5(SkLayerRasterizer* rast, SkPaint& p) {
    rast->addLayer(p);

    p.setPathEffect(new SkDiscretePathEffect(SK_Scalar1*4, SK_Scalar1*3))->unref();
    p.setXfermodeMode(SkXfermode::kSrcOut_Mode);
    rast->addLayer(p);
}

static void r6(SkLayerRasterizer* rast, SkPaint& p) {
    rast->addLayer(p);

    p.setAntiAlias(false);
    SkLayerRasterizer* rast2 = new SkLayerRasterizer;
    r5(rast2, p);
    p.setRasterizer(rast2)->unref();
    p.setXfermodeMode(SkXfermode::kClear_Mode);
    rast->addLayer(p);
}

class Dot2DPathEffect : public Sk2DPathEffect {
public:
    Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix)
        : Sk2DPathEffect(matrix), fRadius(radius) {}

    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Dot2DPathEffect)

protected:
    virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) const SK_OVERRIDE {
        dst->addCircle(loc.fX, loc.fY, fRadius);
    }

    Dot2DPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
        fRadius = buffer.readScalar();
    }
    virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
        this->INHERITED::flatten(buffer);
        buffer.writeScalar(fRadius);
    }

private:
    SkScalar fRadius;

    typedef Sk2DPathEffect INHERITED;
};

static void r7(SkLayerRasterizer* rast, SkPaint& p) {
    SkMatrix    lattice;
    lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
    lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
    p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*4, lattice))->unref();
    rast->addLayer(p);
}

static void r8(SkLayerRasterizer* rast, SkPaint& p) {
    rast->addLayer(p);

    SkMatrix    lattice;
    lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
    lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
    p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*2, lattice))->unref();
    p.setXfermodeMode(SkXfermode::kClear_Mode);
    rast->addLayer(p);

    p.setPathEffect(NULL);
    p.setXfermode(NULL);
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(SK_Scalar1);
    rast->addLayer(p);
}

static void r9(SkLayerRasterizer* rast, SkPaint& p) {
    rast->addLayer(p);

    SkMatrix    lattice;
    lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0);
    lattice.postRotate(SkIntToScalar(30), 0, 0);
    p.setPathEffect(new SkLine2DPathEffect(SK_Scalar1*2, lattice))->unref();
    p.setXfermodeMode(SkXfermode::kClear_Mode);
    rast->addLayer(p);

    p.setPathEffect(NULL);
    p.setXfermode(NULL);
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(SK_Scalar1);
    rast->addLayer(p);
}

typedef void (*raster_proc)(SkLayerRasterizer*, SkPaint&);

static const raster_proc gRastProcs[] = {
    r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
};

static const struct {
    SkColor fMul, fAdd;
} gLightingColors[] = {
    { 0x808080, 0x800000 }, // general case
    { 0x707070, 0x707070 }, // no-pin case
    { 0xFFFFFF, 0x800000 }, // just-add case
    { 0x808080, 0x000000 }, // just-mul case
    { 0xFFFFFF, 0x000000 }  // identity case
};

static void apply_shader(SkPaint* paint, int index) {
    raster_proc proc = gRastProcs[index];
    if (proc) {
        SkPaint p;
        SkLayerRasterizer*  rast = new SkLayerRasterizer;

        p.setAntiAlias(true);
        proc(rast, p);
        paint->setRasterizer(rast)->unref();
    }

#if 1
    SkScalar dir[] = { SK_Scalar1, SK_Scalar1, SK_Scalar1 };
    paint->setMaskFilter(SkBlurMaskFilter::CreateEmboss(
                SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)), dir,
                SK_Scalar1/4, SkIntToScalar(4)))->unref();
    paint->setColor(SK_ColorBLUE);
#endif
}

class DemoView : public SampleView {
public:
    DemoView() {}

protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt) {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "Demo");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    virtual bool onClick(Click* click) {
        return this->INHERITED::onClick(click);
    }

    void makePath(SkPath& path) {
        path.addCircle(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(20),
            SkPath::kCCW_Direction);
        for (int index = 0; index < 10; index++) {
            SkScalar x = (float) cos(index / 10.0f * 2 * 3.1415925358f);
            SkScalar y = (float) sin(index / 10.0f * 2 * 3.1415925358f);
            x *= index & 1 ? 7 : 14;
            y *= index & 1 ? 7 : 14;
            x += SkIntToScalar(20);
            y += SkIntToScalar(20);
            if (index == 0)
                path.moveTo(x, y);
            else
                path.lineTo(x, y);
        }
        path.close();
    }

    virtual void onDrawContent(SkCanvas* canvas) {
        canvas->save();
        drawPicture(canvas, 0);
        canvas->restore();

        {
            SkPicture picture;
            SkCanvas* record = picture.beginRecording(320, 480);
            drawPicture(record, 120);
            canvas->translate(0, SkIntToScalar(120));

            SkRect clip;
            clip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
            do {
                canvas->save();
                canvas->clipRect(clip);
                picture.draw(canvas);
                canvas->restore();
                if (clip.fRight < SkIntToScalar(320))
                    clip.offset(SkIntToScalar(160), 0);
                else if (clip.fBottom < SkIntToScalar(480))
                    clip.offset(-SkIntToScalar(320), SkIntToScalar(160));
                else
                    break;
            } while (true);
        }
    }

    void drawPicture(SkCanvas* canvas, int spriteOffset) {
        SkMatrix matrix; matrix.reset();
        SkPaint paint;
        SkPath path;
        SkPoint start = {0, 0};
        SkPoint stop = { SkIntToScalar(40), SkIntToScalar(40) };
        SkRect rect = {0, 0, SkIntToScalar(40), SkIntToScalar(40) };
        SkRect rect2 = {0, 0, SkIntToScalar(65), SkIntToScalar(20) };
        SkScalar left = 0, top = 0, x = 0, y = 0;
        size_t index;

        char ascii[] = "ascii...";
        size_t asciiLength = sizeof(ascii) - 1;
        char utf8[] = "utf8" "\xe2\x80\xa6";
        short utf16[] = {'u', 't', 'f', '1', '6', 0x2026 };
        short utf16simple[] = {'u', 't', 'f', '1', '6', '!' };

        makePath(path);
        SkTDArray<SkPoint>(pos);
        pos.setCount(asciiLength);
        for (index = 0;  index < asciiLength; index++)
            pos[index].set(SkIntToScalar((unsigned int)index * 10),
                                       SkIntToScalar((unsigned int)index * 2));
        SkTDArray<SkPoint>(pos2);
        pos2.setCount(asciiLength);
        for (index = 0;  index < asciiLength; index++)
            pos2[index].set(SkIntToScalar((unsigned int)index * 10),
                                        SkIntToScalar(20));

        // shaders
        SkPoint linearPoints[] = { { 0, 0, }, { SkIntToScalar(40), SkIntToScalar(40) } };
        SkColor linearColors[] = { SK_ColorRED, SK_ColorBLUE };
        SkScalar* linearPos = NULL;
        int linearCount = 2;
        SkShader::TileMode linearMode = SkShader::kMirror_TileMode;
        SkUnitMapper* linearMapper = new SkDiscreteMapper(3);
        SkAutoUnref unmapLinearMapper(linearMapper);
        SkShader* linear = SkGradientShader::CreateLinear(linearPoints,
            linearColors, linearPos, linearCount, linearMode, linearMapper);

        SkPoint radialCenter = { SkIntToScalar(25), SkIntToScalar(25) };
        SkScalar radialRadius = SkIntToScalar(25);
        SkColor radialColors[] = { SK_ColorGREEN, SK_ColorGRAY, SK_ColorRED };
        SkScalar radialPos[] = { 0, SkIntToScalar(3) / 5, SkIntToScalar(1)};
        int radialCount = 3;
        SkShader::TileMode radialMode = SkShader::kRepeat_TileMode;
        SkUnitMapper* radialMapper = new SkCosineMapper();
        SkAutoUnref unmapRadialMapper(radialMapper);
        SkShader* radial = SkGradientShader::CreateRadial(radialCenter,
            radialRadius, radialColors, radialPos, radialCount,
            radialMode, radialMapper);

        SkTransparentShader* transparentShader = new SkTransparentShader();
        SkEmbossMaskFilter::Light light;
        light.fDirection[0] = SK_Scalar1/2;
        light.fDirection[1] = SK_Scalar1/2;
        light.fDirection[2] = SK_Scalar1/3;
        light.fAmbient        = 0x48;
        light.fSpecular        = 0x80;
        SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(12)/5);
        SkEmbossMaskFilter* embossFilter = new SkEmbossMaskFilter(sigma, light);

        SkXfermode* xfermode = SkXfermode::Create(SkXfermode::kXor_Mode);
        SkColorFilter* lightingFilter = SkColorFilter::CreateLightingFilter(
            0xff89bc45, 0xff112233);

        canvas->save();
        canvas->translate(SkIntToScalar(0), SkIntToScalar(5));
        paint.setAntiAlias(true);
        paint.setFilterLevel(SkPaint::kLow_FilterLevel);
        // !!! draw through a clip
        paint.setColor(SK_ColorLTGRAY);
        paint.setStyle(SkPaint::kFill_Style);
        SkRect clip = {0, 0, SkIntToScalar(320), SkIntToScalar(120)};
        canvas->clipRect(clip);
        paint.setShader(SkShader::CreateBitmapShader(fTx,
            SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode))->unref();
        canvas->drawPaint(paint);
        canvas->save();

        // line (exercises xfermode, colorShader, colorFilter, filterShader)
        paint.setColor(SK_ColorGREEN);
        paint.setStrokeWidth(SkIntToScalar(10));
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setXfermode(xfermode)->unref();
        paint.setColorFilter(lightingFilter)->unref();
        canvas->drawLine(start.fX, start.fY, stop.fX, stop.fY, paint); // should not be green
        paint.setXfermode(NULL);
        paint.setColorFilter(NULL);

        // rectangle
        paint.setStyle(SkPaint::kFill_Style);
        canvas->translate(SkIntToScalar(50), 0);
        paint.setColor(SK_ColorYELLOW);
        paint.setShader(linear)->unref();
        paint.setPathEffect(pathEffectTest())->unref();
        canvas->drawRect(rect, paint);
        paint.setPathEffect(NULL);

        // circle w/ emboss & transparent (exercises 3dshader)
        canvas->translate(SkIntToScalar(50), 0);
        paint.setMaskFilter(embossFilter)->unref();
        canvas->drawOval(rect, paint);
        canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
        paint.setShader(transparentShader)->unref();
        canvas->drawOval(rect, paint);
        canvas->translate(0, SkIntToScalar(-10));

        // path
        canvas->translate(SkIntToScalar(50), 0);
        paint.setColor(SK_ColorRED);
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setStrokeWidth(SkIntToScalar(5));
        paint.setShader(radial)->unref();
        paint.setMaskFilter(NULL);
        canvas->drawPath(path, paint);

        paint.setShader(NULL);
        // bitmap, sprite
        canvas->translate(SkIntToScalar(50), 0);
        paint.setStyle(SkPaint::kFill_Style);
        canvas->drawBitmap(fBug, left, top, &paint);
        canvas->translate(SkIntToScalar(30), 0);
        canvas->drawSprite(fTb,
            SkScalarRound(canvas->getTotalMatrix().getTranslateX()),
            spriteOffset + 10, &paint);

        canvas->translate(-SkIntToScalar(30), SkIntToScalar(30));
        paint.setShader(shaderTest())->unref(); // test compose shader
        canvas->drawRect(rect2, paint);
        paint.setShader(NULL);

        canvas->restore();
        // text
        canvas->translate(0, SkIntToScalar(60));
        canvas->save();
        paint.setColor(SK_ColorGRAY);
        canvas->drawPosText(ascii, asciiLength, pos.begin(), paint);
        canvas->drawPosText(ascii, asciiLength, pos2.begin(), paint);

        canvas->translate(SkIntToScalar(50), 0);
        paint.setColor(SK_ColorCYAN);
        canvas->drawText(utf8, sizeof(utf8) - 1, x, y, paint);

        canvas->translate(SkIntToScalar(30), 0);
        paint.setColor(SK_ColorMAGENTA);
        paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
        matrix.setTranslate(SkIntToScalar(10), SkIntToScalar(10));
        canvas->drawTextOnPath((void*) utf16, sizeof(utf16), path, &matrix, paint);
        canvas->translate(0, SkIntToScalar(20));
        canvas->drawTextOnPath((void*) utf16simple, sizeof(utf16simple), path, &matrix, paint);
        canvas->restore();

        canvas->translate(0, SkIntToScalar(60));
        paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
        canvas->restore();
    }

    /*
./SkColorFilter.h:25:class SkColorFilter : public SkFlattenable { -- abstract
    static SkColorFilter* CreatXfermodeFilter() *** untested ***
    static SkColorFilter* CreatePorterDuffFilter() *** untested ***
    static SkColorFilter* CreateLightingFilter() -- tested
./SkDrawLooper.h:9:class SkDrawLooper : public SkFlattenable { -- virtually abstract
    ./SkBlurDrawLooper.h:9:class SkBlurDrawLooper : public SkDrawLooper { *** untested ***
./SkMaskFilter.h:41:class SkMaskFilter : public SkFlattenable { -- abstract chmod +w .h
    ./SkEmbossMaskFilter.h:27:class SkEmbossMaskFilter : public SkMaskFilter { -- tested
./SkPathEffect.h:33:class SkPathEffect : public SkFlattenable { -- abstract
    ./Sk1DPathEffect.h:27:class Sk1DPathEffect : public SkPathEffect { -- abstract
        ./Sk1DPathEffect.h:48:class SkPath1DPathEffect : public Sk1DPathEffect { -- tested
    ./Sk2DPathEffect.h:25:class Sk2DPathEffect : public SkPathEffect { *** untested ***
    ./SkCornerPathEffect.h:28:class SkCornerPathEffect : public SkPathEffect { *** untested ***
    ./SkDashPathEffect.h:27:class SkDashPathEffect : public SkPathEffect {
    ./SkDiscretePathEffect.h:27:class SkDiscretePathEffect : public SkPathEffect {
    ./SkPaint.h:760:class SkStrokePathEffect : public SkPathEffect {
    ./SkPathEffect.h:58:class SkPairPathEffect : public SkPathEffect {
        ./SkPathEffect.h:78:class SkComposePathEffect : public SkPairPathEffect {
        ./SkPathEffect.h:114:class SkSumPathEffect : public SkPairPathEffect {
./SkRasterizer.h:29:class SkRasterizer : public SkFlattenable {
    ./SkLayerRasterizer.h:27:class SkLayerRasterizer : public SkRasterizer {
./SkShader.h:36:class SkShader : public SkFlattenable {
    ./SkColorFilter.h:59:class SkFilterShader : public SkShader {
    ./SkColorShader.h:26:class SkColorShader : public SkShader {
    ./SkShaderExtras.h:31:class SkComposeShader : public SkShader {
    ./SkTransparentShader.h:23:class SkTransparentShader : public SkShader {
./SkUnitMapper.h:24:class SkUnitMapper : public SkFlattenable {
    ./SkUnitMapper.h:33:class SkDiscreteMapper : public SkUnitMapper {
    ./SkUnitMapper.h:51:class SkFlipCosineMapper : public SkUnitMapper {
./SkXfermode.h:32:class SkXfermode : public SkFlattenable {
    ./SkAvoidXfermode.h:28:class SkAvoidXfermode : public SkXfermode { *** not done *** chmod +w .h .cpp
    ./SkXfermode.h:54:class SkProcXfermode : public SkXfermode {
    */

    /*
./SkBlurMaskFilter.h:25:class SkBlurMaskFilter {
    chmod +w SkBlurMaskFilter.cpp
./SkGradientShader.h:30:class SkGradientShader {
    */
        // save layer, bounder, looper
        // matrix
        // clip /path/region
        // bitmap proc shader ?

/* untested:
SkCornerPathEffect.h:28:class SkCornerPathEffect : public SkPathEffect {
*/

    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
        fClickPt.set(x, y);
        this->inval(NULL);
        return this->INHERITED::onFindClickHandler(x, y, modi);
    }

    SkPathEffect* pathEffectTest() {
        static const int gXY[] = { 1, 0, 0, -1, 2, -1, 3, 0, 2, 1, 0, 1 };
        SkScalar gPhase = 0;
        SkPath path;
        path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
        for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
            path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
        path.close();
        path.offset(SkIntToScalar(-6), 0);
        SkPathEffect* outer = new SkPath1DPathEffect(path, SkIntToScalar(12),
            gPhase, SkPath1DPathEffect::kRotate_Style);
        SkPathEffect* inner = new SkDiscretePathEffect(SkIntToScalar(2),
            SkIntToScalar(1)/10); // SkCornerPathEffect(SkIntToScalar(2));
        SkPathEffect* result = new SkComposePathEffect(outer, inner);
        outer->unref();
        inner->unref();
        return result;
    }

    SkShader* shaderTest() {
        SkPoint pts[] = { { 0, 0, }, { SkIntToScalar(100), 0 } };
        SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
        SkShader* shaderA = SkGradientShader::CreateLinear(pts, colors, NULL,
            2, SkShader::kClamp_TileMode);
        pts[1].set(0, SkIntToScalar(100));
        SkColor colors2[] = {SK_ColorBLACK,  SkColorSetARGB(0x80, 0, 0, 0)};
        SkShader* shaderB = SkGradientShader::CreateLinear(pts, colors2, NULL,
            2, SkShader::kClamp_TileMode);
        SkXfermode* mode = SkXfermode::Create(SkXfermode::kDstIn_Mode);
        SkShader* result = new SkComposeShader(shaderA, shaderB, mode);
        shaderA->unref();
        shaderB->unref();
        mode->unref();
        return result;
    }

    virtual void startTest() {
        SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/bugcirc.gif", &fBug);
        SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/tbcirc.gif", &fTb);
        SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/05psp04.gif", &fTx);
    }

    void drawRaster(SkCanvas* canvas)  {
        for (size_t index = 0; index < SK_ARRAY_COUNT(gRastProcs); index++)
            drawOneRaster(canvas);
    }

    void drawOneRaster(SkCanvas* canvas) {
        canvas->save();

        SkScalar    x = SkIntToScalar(20);
        SkScalar    y = SkIntToScalar(40);
        SkPaint     paint;

        paint.setAntiAlias(true);
        paint.setTextSize(SkIntToScalar(48));
        paint.setTypeface(SkTypeface::CreateFromName("sans-serif",
                                                     SkTypeface::kBold));

        SkString str("GOOGLE");

        for (size_t i = 0; i < SK_ARRAY_COUNT(gRastProcs); i++) {
            apply_shader(&paint, i);

          //  paint.setMaskFilter(NULL);
          //  paint.setColor(SK_ColorBLACK);

#if 01
            int index = i % SK_ARRAY_COUNT(gLightingColors);
            paint.setColorFilter(SkColorFilter::CreateLightingFilter(
                                    gLightingColors[index].fMul,
                                    gLightingColors[index].fAdd))->unref();
#endif

            canvas->drawText(str.c_str(), str.size(), x, y, paint);
            SkRect  oval = { x, y - SkIntToScalar(40), x + SkIntToScalar(40), y };
            paint.setStyle(SkPaint::kStroke_Style);
            canvas->drawOval(oval, paint);
            paint.setStyle(SkPaint::kFill_Style);

            y += paint.getFontSpacing();
        }

        canvas->restore();

        if (1) {
            SkAvoidXfermode   mode(SK_ColorWHITE, 0xFF,
                                   SkAvoidXfermode::kTargetColor_Mode);
            SkPaint paint;
            x += SkIntToScalar(20);
            SkRect  r = { x, 0, x + SkIntToScalar(360), SkIntToScalar(700) };
            paint.setXfermode(&mode);
            paint.setColor(SK_ColorGREEN);
            paint.setAntiAlias(true);
            canvas->drawOval(r, paint);
        }
    }

private:
    SkPoint fClickPt;
    SkBitmap fBug, fTb, fTx;
    typedef SampleView INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

static SkView* MyFactory() { return new DemoView; }
static SkViewRegister reg(MyFactory);
