180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gm.h"
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace skiagm {
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** Create a bitmap image suitable for testing SkBitmap::scrollRect().
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  @param quarterWidth bitmap will be 4x this many pixels wide
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  @param quarterHeight bitmap will be 4x this many pixels tall
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  @param bitmap the bitmap data is written into this object
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void make_bitmap(int quarterWidth, int quarterHeight, SkBitmap *bitmap) {
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint pRed, pWhite, pGreen, pBlue, pLine, pAlphaGray;
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pRed.setColor(0xFFFF9999);
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pWhite.setColor(0xFFFFFFFF);
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pGreen.setColor(0xFF99FF99);
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pBlue.setColor(0xFF9999FF);
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pLine.setColor(0xFF000000);
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pLine.setStyle(SkPaint::kStroke_Style);
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pAlphaGray.setColor(0x66888888);
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // Prepare bitmap, and a canvas that draws into it.
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bitmap->reset();
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bitmap->setConfig(SkBitmap::kARGB_8888_Config,
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                      quarterWidth*4, quarterHeight*4);
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bitmap->allocPixels();
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkCanvas canvas(*bitmap);
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar w = SkIntToScalar(quarterWidth);
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar h = SkIntToScalar(quarterHeight);
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas.drawRectCoords(  0,   0, w*2, h*2, pRed);
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas.drawRectCoords(w*2,   0, w*4, h*2, pGreen);
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas.drawRectCoords(  0, h*2, w*2, h*4, pBlue);
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas.drawRectCoords(w*2, h*2, w*4, h*4, pWhite);
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas.drawRectCoords(w, h, w*3, h*3, pAlphaGray);
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas.drawLine(w*2,   0, w*2, h*4, pLine);
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas.drawLine(  0, h*2, w*4, h*2, pLine);
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas.drawRectCoords(w, h, w*3, h*3, pLine);
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass BitmapScrollGM : public GM {
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool fInited;
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void init() {
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (fInited) {
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return;
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fInited = true;
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // Create the original bitmap.
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        make_bitmap(quarterWidth, quarterHeight, &origBitmap);
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    BitmapScrollGM() {
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fInited = false;
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->setBGColor(0xFFDDDDDD);
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected:
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual SkString onShortName() {
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return SkString("bitmapscroll");
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual SkISize onISize() {
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru      return make_isize(800, 600);
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void onDraw(SkCanvas* canvas) {
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->init();
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkIRect scrollCenterRegion = SkIRect::MakeXYWH(
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            quarterWidth, quarterHeight, quarterWidth*2+1, quarterHeight*2+1);
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int x = quarterWidth;
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int y = quarterHeight;
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int xSpacing = quarterWidth * 20;
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int ySpacing = quarterHeight * 16;
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // Draw left-hand text labels.
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        drawLabel(canvas, "scroll entire bitmap",
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  x, y, x, y + ySpacing);
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        drawLabel(canvas, "scroll part of bitmap",
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  x, y + ySpacing, x, y + ySpacing*2);
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        x += 30;
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // Draw various permutations of scrolled bitmaps, scrolling a bit
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // further each time.
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        draw9(canvas, x, y, NULL, quarterWidth*1/2, quarterHeight*1/2);
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru              quarterWidth*1/2, quarterHeight*1/2);
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        x += xSpacing;
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        draw9(canvas, x, y, NULL, quarterWidth*3/2, quarterHeight*3/2);
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru              quarterWidth*3/2, quarterHeight*3/2);
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        x += xSpacing;
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        draw9(canvas, x, y, NULL, quarterWidth*5/2, quarterHeight*5/2);
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru              quarterWidth*5/2, quarterHeight*5/2);
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        x += xSpacing;
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        draw9(canvas, x, y, NULL, quarterWidth*9/2, quarterHeight*9/2);
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru              quarterWidth*9/2, quarterHeight*9/2);
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void drawLabel(SkCanvas* canvas, const char *text, int startX, int startY,
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                 int endX, int endY) {
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkPaint paint;
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        paint.setColor(0xFF000000);
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkPath path;
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        path.moveTo(SkIntToScalar(startX), SkIntToScalar(startY));
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        path.lineTo(SkIntToScalar(endX), SkIntToScalar(endY));
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        canvas->drawTextOnPath(text, strlen(text), path, NULL, paint);
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /** Stamp out 9 copies of origBitmap, scrolled in each direction (and
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  not scrolled at all).
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void draw9(SkCanvas* canvas, int x, int y, SkIRect* subset,
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru               int scrollX, int scrollY) {
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int yMult=-1; yMult<=1; yMult++) {
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (int xMult=-1; xMult<=1; xMult++) {
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // Figure out the (x,y) to draw this copy at
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar bitmapX = SkIntToScalar(
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    x + quarterWidth * 5 * (xMult+1));
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar bitmapY = SkIntToScalar(
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    y + quarterHeight * 5 * (yMult+1));
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // Scroll a new copy of the bitmap, and then draw it.
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // scrollRect() should always return true, even if it's a no-op
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkBitmap scrolledBitmap;
134d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                SkDEBUGCODE(bool copyToReturnValue = )origBitmap.copyTo(
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    &scrolledBitmap, origBitmap.config());
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkASSERT(copyToReturnValue);
137d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                SkDEBUGCODE(bool scrollRectReturnValue = )scrolledBitmap.scrollRect(
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    subset, scrollX * xMult, scrollY * yMult);
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkASSERT(scrollRectReturnValue);
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas->drawBitmap(scrolledBitmap, bitmapX, bitmapY);
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    typedef GM INHERITED;
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const int quarterWidth = 10;
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const int quarterHeight = 14;
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBitmap origBitmap;
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GM* MyFactory(void*) { return new BitmapScrollGM; }
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic GMRegistry reg(MyFactory);
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
158