
/*
 * Copyright 2013 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 "SkRandom.h"
#include "SkShader.h"
#include "SkXfermode.h"

namespace skiagm {

/**
 * Renders overlapping shapes with random SkXfermode::Modes against a checkerboard.
 */
class MixedXfermodesGM : public GM {
public:
    MixedXfermodesGM() {
    }

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

    virtual SkISize onISize() SK_OVERRIDE {
        return SkISize::Make(790, 640);
    }

    void drawShape(SkCanvas* canvas,
                   const SkPaint& paint,
                   SkRandom* random) {
        static const SkRect kRect = SkRect::MakeXYWH(SkIntToScalar(-50), SkIntToScalar(-50),
                                                     SkIntToScalar(75), SkIntToScalar(105));
        int shape = random->nextULessThan(5);
        switch (shape) {
        case 0:
            canvas->drawCircle(0, 0, 50, paint);
            break;
        case 1:
            canvas->drawRoundRect(kRect, SkIntToScalar(10), SkIntToScalar(20), paint);
            break;
        case 2:
            canvas->drawRect(kRect, paint);
            break;
        case 3:
            if (fConvexPath.isEmpty()) {
                SkPoint points[4];
                kRect.toQuad(points);
                fConvexPath.moveTo(points[0]);
                fConvexPath.quadTo(points[1], points[2]);
                fConvexPath.quadTo(points[3], points[0]);
                SkASSERT(fConvexPath.isConvex());
            }
            canvas->drawPath(fConvexPath, paint);
            break;
        case 4:
            if (fConcavePath.isEmpty()) {
                SkPoint points[5] = {{0, SkIntToScalar(-50)} };
                SkMatrix rot;
                rot.setRotate(SkIntToScalar(360) / 5);
                for (int i = 1; i < 5; ++i) {
                    rot.mapPoints(points + i, points + i - 1, 1);
                }
                fConcavePath.moveTo(points[0]);
                for (int i = 0; i < 5; ++i) {
                    fConcavePath.lineTo(points[(2 * i) % 5]);
                }
                fConcavePath.setFillType(SkPath::kEvenOdd_FillType);
                SkASSERT(!fConcavePath.isConvex());
            }
            canvas->drawPath(fConcavePath, paint);
            break;
        }
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        if (NULL == fBG.get()) {
            static uint32_t kCheckerPixelData[] = { 0xFFFFFFFF,
                                                    0xFFCCCCCC,
                                                    0xFFCCCCCC,
                                                    0xFFFFFFFF };
            SkBitmap bitmap;
            bitmap.allocN32Pixels(2, 2);
            memcpy(bitmap.getPixels(), kCheckerPixelData, sizeof(kCheckerPixelData));
            SkMatrix lm;
            lm.setScale(SkIntToScalar(20), SkIntToScalar(20));
            fBG.reset(SkShader::CreateBitmapShader(bitmap,
                                                   SkShader::kRepeat_TileMode,
                                                   SkShader::kRepeat_TileMode,
                                                   &lm));
        }

        SkPaint bgPaint;
        bgPaint.setShader(fBG.get());
        canvas->drawPaint(bgPaint);
        SkISize size = canvas->getDeviceSize();
        SkScalar maxScale = SkScalarSqrt((SkIntToScalar(size.fWidth * size.fHeight))) / 300;
        SkRandom random;
        for (int i = 0; i < kNumShapes; ++i) {
            SkScalar s = random.nextRangeScalar(SK_Scalar1 / 8, SK_Scalar1) * maxScale;
            SkScalar r = random.nextRangeScalar(0, SkIntToScalar(360));
            SkScalar dx = random.nextRangeScalar(0, SkIntToScalar(size.fWidth));
            SkScalar dy = random.nextRangeScalar(0, SkIntToScalar(size.fHeight));
            SkColor color = random.nextU();
            SkXfermode::Mode mode =
                static_cast<SkXfermode::Mode>(random.nextULessThan(SkXfermode::kLastMode + 1));

            SkPaint p;
            p.setAntiAlias(true);
            p.setColor(color);
            p.setXfermodeMode(mode);
            canvas->save();
            canvas->translate(dx, dy);
            canvas->scale(s, s);
            canvas->rotate(r);
            this->drawShape(canvas, p, &random);
            canvas->restore();
        }
    }

    virtual uint32_t onGetFlags() const {
        // Skip PDF rasterization since rendering this PDF takes forever.
        return kSkipPDFRasterization_Flag | kSkipTiled_Flag;
    }

private:
    enum {
        kNumShapes = 100,
    };
    SkAutoTUnref<SkShader> fBG;
    SkPath                 fConcavePath;
    SkPath                 fConvexPath;
    typedef GM INHERITED;
};

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

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

}
