
/*
 * 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 "gm.h"

namespace skiagm {

/** Create a bitmap image suitable for testing SkBitmap::scrollRect().
 *
 *  @param quarterWidth bitmap will be 4x this many pixels wide
 *  @param quarterHeight bitmap will be 4x this many pixels tall
 *  @param bitmap the bitmap data is written into this object
 */
static void make_bitmap(int quarterWidth, int quarterHeight, SkBitmap *bitmap) {
    SkPaint pRed, pWhite, pGreen, pBlue, pLine, pAlphaGray;
    pRed.setColor(0xFFFF9999);
    pWhite.setColor(0xFFFFFFFF);
    pGreen.setColor(0xFF99FF99);
    pBlue.setColor(0xFF9999FF);
    pLine.setColor(0xFF000000);
    pLine.setStyle(SkPaint::kStroke_Style);
    pAlphaGray.setColor(0x66888888);

    // Prepare bitmap, and a canvas that draws into it.
    bitmap->reset();
    bitmap->setConfig(SkBitmap::kARGB_8888_Config,
                      quarterWidth*4, quarterHeight*4);
    bitmap->allocPixels();
    SkCanvas canvas(*bitmap);

    SkScalar w = SkIntToScalar(quarterWidth);
    SkScalar h = SkIntToScalar(quarterHeight);
    canvas.drawRectCoords(  0,   0, w*2, h*2, pRed);
    canvas.drawRectCoords(w*2,   0, w*4, h*2, pGreen);
    canvas.drawRectCoords(  0, h*2, w*2, h*4, pBlue);
    canvas.drawRectCoords(w*2, h*2, w*4, h*4, pWhite);
    canvas.drawRectCoords(w, h, w*3, h*3, pAlphaGray);
    canvas.drawLine(w*2,   0, w*2, h*4, pLine);
    canvas.drawLine(  0, h*2, w*4, h*2, pLine);
    canvas.drawRectCoords(w, h, w*3, h*3, pLine);
}

class BitmapScrollGM : public GM {
public:
    BitmapScrollGM() {
        // Create the original bitmap.
        make_bitmap(quarterWidth, quarterHeight, &origBitmap);
        this->setBGColor(0xFFDDDDDD);
    }

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

    virtual SkISize onISize() {
      return make_isize(800, 600);
    }

    virtual void onDraw(SkCanvas* canvas) {
        SkIRect scrollCenterRegion = SkIRect::MakeXYWH(
            quarterWidth, quarterHeight, quarterWidth*2+1, quarterHeight*2+1);
        int x = quarterWidth;
        int y = quarterHeight;
        int xSpacing = quarterWidth * 20;
        int ySpacing = quarterHeight * 16;

        // Draw left-hand text labels.
        drawLabel(canvas, "scroll entire bitmap",
                  x, y, x, y + ySpacing);
        drawLabel(canvas, "scroll part of bitmap",
                  x, y + ySpacing, x, y + ySpacing*2);
        x += 30;

        // Draw various permutations of scrolled bitmaps, scrolling a bit
        // further each time.
        draw9(canvas, x, y, NULL, quarterWidth*1/2, quarterHeight*1/2);
        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
              quarterWidth*1/2, quarterHeight*1/2);
        x += xSpacing;
        draw9(canvas, x, y, NULL, quarterWidth*3/2, quarterHeight*3/2);
        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
              quarterWidth*3/2, quarterHeight*3/2);
        x += xSpacing;
        draw9(canvas, x, y, NULL, quarterWidth*5/2, quarterHeight*5/2);
        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
              quarterWidth*5/2, quarterHeight*5/2);
        x += xSpacing;
        draw9(canvas, x, y, NULL, quarterWidth*9/2, quarterHeight*9/2);
        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
              quarterWidth*9/2, quarterHeight*9/2);
    }

    void drawLabel(SkCanvas* canvas, const char *text, int startX, int startY,
                 int endX, int endY) {
        SkPaint paint;
        paint.setColor(0xFF000000);
        SkPath path;
        path.moveTo(SkIntToScalar(startX), SkIntToScalar(startY));
        path.lineTo(SkIntToScalar(endX), SkIntToScalar(endY));
        canvas->drawTextOnPath(text, strlen(text), path, NULL, paint);
    }

    /** Stamp out 9 copies of origBitmap, scrolled in each direction (and
     *  not scrolled at all).
     */
    void draw9(SkCanvas* canvas, int x, int y, SkIRect* subset,
               int scrollX, int scrollY) {
        for (int yMult=-1; yMult<=1; yMult++) {
            for (int xMult=-1; xMult<=1; xMult++) {
                // Figure out the (x,y) to draw this copy at
                SkScalar bitmapX = SkIntToScalar(
                    x + quarterWidth * 5 * (xMult+1));
                SkScalar bitmapY = SkIntToScalar(
                    y + quarterHeight * 5 * (yMult+1));

                // Scroll a new copy of the bitmap, and then draw it.
                // scrollRect() should always return true, even if it's a no-op
                SkBitmap scrolledBitmap;
                bool copyToReturnValue = origBitmap.copyTo(
                    &scrolledBitmap, origBitmap.config());
                SkASSERT(copyToReturnValue);
                bool scrollRectReturnValue = scrolledBitmap.scrollRect(
                    subset, scrollX * xMult, scrollY * yMult);
                SkASSERT(scrollRectReturnValue);
                canvas->drawBitmap(scrolledBitmap, bitmapX, bitmapY);
            }
        }
    }

private:
    typedef GM INHERITED;
    static const int quarterWidth = 10;
    static const int quarterHeight = 14;
    SkBitmap origBitmap;
};

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

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

}
