
/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "gm.h"
#include "SkBitmap.h"
#include "SkBlurMaskFilter.h"
#include "SkCanvas.h"
#include "SkColor.h"
#include "SkMatrix.h"
#include "SkPath.h"
#include "SkRect.h"
#include "SkSize.h"
#include "SkString.h"

namespace skiagm {

class DrawBitmapMatrixGM : public GM {
public:
    DrawBitmapMatrixGM() {}

protected:
    virtual SkString onShortName() SK_OVERRIDE {
        return SkString("drawbitmapmatrix");
    }

    virtual SkISize onISize() SK_OVERRIDE { return make_isize(1024, 256); }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        SkBitmap bm;
        this->setupBitmap(&bm);

        // Draw normally.
        SkMatrix matrix;
        matrix.reset();
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setDither(true);
        canvas->drawBitmapMatrix(bm, matrix, &paint);

        // Draw stretched horizontally and squished vertically.
        canvas->translate(SkIntToScalar(bm.width() + 5), 0);
        matrix.setScale(SkIntToScalar(2), SK_ScalarHalf);
        canvas->drawBitmapMatrix(bm, matrix, &paint);

        // Draw rotated
        canvas->translate(SkIntToScalar(bm.width()*2 + 5), 0);
        matrix.reset();
        matrix.setRotate(SkIntToScalar(45), SkIntToScalar(bm.width() / 2),
                         SkIntToScalar(bm.height() / 2));
        canvas->save();
        canvas->translate(0, SkIntToScalar(10));
        canvas->drawBitmapMatrix(bm, matrix, &paint);
        canvas->restore();

        // Draw with perspective
        canvas->translate(SkIntToScalar(bm.width() + 15), 0);
        matrix.reset();
        matrix.setPerspX(SkScalarDiv(SK_Scalar1, SkIntToScalar(1000)));
        matrix.setPerspY(SkScalarDiv(SK_Scalar1, SkIntToScalar(1000)));
        canvas->drawBitmapMatrix(bm, matrix, &paint);

        // Draw with skew
        canvas->translate(SkIntToScalar(bm.width() + 5), 0);
        matrix.reset();
        matrix.setSkew(SkIntToScalar(2), SkIntToScalar(2));
        canvas->drawBitmapMatrix(bm, matrix, &paint);

        // Draw with sin/cos
        canvas->translate(SkIntToScalar(bm.width() * 4), 0);
        matrix.reset();
        matrix.setSinCos(SK_ScalarHalf, SkIntToScalar(2));
        canvas->drawBitmapMatrix(bm, matrix, &paint);

        {
            // test the following code path:
            // SkGpuDevice::drawPath() -> SkGpuDevice::drawWithMaskFilter()
            SkPaint paint;

            paint.setFilterBitmap(true);

            SkMaskFilter* mf = SkBlurMaskFilter::Create(
                5,
                SkBlurMaskFilter::kNormal_BlurStyle,
                SkBlurMaskFilter::kHighQuality_BlurFlag |
                SkBlurMaskFilter::kIgnoreTransform_BlurFlag);
            paint.setMaskFilter(mf)->unref();

            canvas->translate(SkIntToScalar(bm.width()*2 + 20), 0);

            matrix.reset();
            matrix.setRotate(SkIntToScalar(45), SkIntToScalar(bm.width() / 2),
                             SkIntToScalar(bm.height() / 2));

            canvas->save();
            canvas->translate(0, SkIntToScalar(20));
            canvas->drawBitmapMatrix(bm, matrix, &paint);
            canvas->restore();
        }

    }
private:
    void setupBitmap(SkBitmap* bm) {
        SkASSERT(bm);
        static const int SIZE = 64;
        bm->setConfig(SkBitmap::kARGB_8888_Config, SIZE, SIZE);
        bm->allocPixels();
        SkCanvas canvas(*bm);

        SkPaint paint;
        paint.setColor(SK_ColorGREEN);
        canvas.drawPaint(paint);

        paint.setColor(SK_ColorBLUE);
        paint.setAntiAlias(true);
        SkRect rect = SkRect::MakeWH(SkIntToScalar(SIZE), SkIntToScalar(SIZE));
        SkPath path;
        path.addOval(rect);
        canvas.drawPath(path, paint);
    }
};

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

static GM* MyFactory(void*) { return new DrawBitmapMatrixGM; }
static GMRegistry reg(MyFactory);

}
