1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com#include "gm.h"
9d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
10d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.comnamespace skiagm {
11d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
12d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com/** Create a bitmap image suitable for testing SkBitmap::scrollRect().
13d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com *
14d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com *  @param quarterWidth bitmap will be 4x this many pixels wide
15d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com *  @param quarterHeight bitmap will be 4x this many pixels tall
16d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com *  @param bitmap the bitmap data is written into this object
17d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com */
18d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.comstatic void make_bitmap(int quarterWidth, int quarterHeight, SkBitmap *bitmap) {
194067d7d5cdbf6d052cf1519c79db82bad9e47b7eepoger@google.com    SkPaint pRed, pWhite, pGreen, pBlue, pLine, pAlphaGray;
20d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    pRed.setColor(0xFFFF9999);
21d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    pWhite.setColor(0xFFFFFFFF);
22d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    pGreen.setColor(0xFF99FF99);
23d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    pBlue.setColor(0xFF9999FF);
24d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    pLine.setColor(0xFF000000);
25d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    pLine.setStyle(SkPaint::kStroke_Style);
264067d7d5cdbf6d052cf1519c79db82bad9e47b7eepoger@google.com    pAlphaGray.setColor(0x66888888);
27d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
28d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    // Prepare bitmap, and a canvas that draws into it.
29eb9a46cbbb475e862a084aa2224ec18d4ac5e95breed@google.com    bitmap->allocN32Pixels(quarterWidth*4, quarterHeight*4);
30d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    SkCanvas canvas(*bitmap);
31d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
32d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    SkScalar w = SkIntToScalar(quarterWidth);
33d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    SkScalar h = SkIntToScalar(quarterHeight);
34d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    canvas.drawRectCoords(  0,   0, w*2, h*2, pRed);
35d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    canvas.drawRectCoords(w*2,   0, w*4, h*2, pGreen);
36d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    canvas.drawRectCoords(  0, h*2, w*2, h*4, pBlue);
37d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    canvas.drawRectCoords(w*2, h*2, w*4, h*4, pWhite);
384067d7d5cdbf6d052cf1519c79db82bad9e47b7eepoger@google.com    canvas.drawRectCoords(w, h, w*3, h*3, pAlphaGray);
39d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    canvas.drawLine(w*2,   0, w*2, h*4, pLine);
40d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    canvas.drawLine(  0, h*2, w*4, h*2, pLine);
41d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    canvas.drawRectCoords(w, h, w*3, h*3, pLine);
42d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com}
43d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
44d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.comclass BitmapScrollGM : public GM {
459afc656df6e81a17ab591b607a92755a5a2e06ccreed@google.com    bool fInited;
469afc656df6e81a17ab591b607a92755a5a2e06ccreed@google.com    void init() {
479afc656df6e81a17ab591b607a92755a5a2e06ccreed@google.com        if (fInited) {
489afc656df6e81a17ab591b607a92755a5a2e06ccreed@google.com            return;
499afc656df6e81a17ab591b607a92755a5a2e06ccreed@google.com        }
509afc656df6e81a17ab591b607a92755a5a2e06ccreed@google.com        fInited = true;
51d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        // Create the original bitmap.
52d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        make_bitmap(quarterWidth, quarterHeight, &origBitmap);
539afc656df6e81a17ab591b607a92755a5a2e06ccreed@google.com    }
549afc656df6e81a17ab591b607a92755a5a2e06ccreed@google.com
559afc656df6e81a17ab591b607a92755a5a2e06ccreed@google.compublic:
569afc656df6e81a17ab591b607a92755a5a2e06ccreed@google.com    BitmapScrollGM() {
579afc656df6e81a17ab591b607a92755a5a2e06ccreed@google.com        fInited = false;
5848dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        this->setBGColor(0xFFDDDDDD);
59d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    }
60d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
61d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.comprotected:
62a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org    virtual uint32_t onGetFlags() const SK_OVERRIDE {
63a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org        return kSkipTiled_Flag;
64a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org    }
65a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org
66d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    virtual SkString onShortName() {
67d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        return SkString("bitmapscroll");
68d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    }
69d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
70d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    virtual SkISize onISize() {
71f539318f0d3dba743ec1886d5d9df0fb1be628a1tfarina      return SkISize::Make(800, 600);
72d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    }
73d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
74d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    virtual void onDraw(SkCanvas* canvas) {
759afc656df6e81a17ab591b607a92755a5a2e06ccreed@google.com        this->init();
76d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        SkIRect scrollCenterRegion = SkIRect::MakeXYWH(
774067d7d5cdbf6d052cf1519c79db82bad9e47b7eepoger@google.com            quarterWidth, quarterHeight, quarterWidth*2+1, quarterHeight*2+1);
78d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        int x = quarterWidth;
79d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        int y = quarterHeight;
80d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        int xSpacing = quarterWidth * 20;
81d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        int ySpacing = quarterHeight * 16;
82d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
8348dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        // Draw left-hand text labels.
84d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        drawLabel(canvas, "scroll entire bitmap",
85d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                  x, y, x, y + ySpacing);
86d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        drawLabel(canvas, "scroll part of bitmap",
87d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                  x, y + ySpacing, x, y + ySpacing*2);
88d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        x += 30;
89d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
90d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        // Draw various permutations of scrolled bitmaps, scrolling a bit
91d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        // further each time.
92d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y, NULL, quarterWidth*1/2, quarterHeight*1/2);
93d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
94d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com              quarterWidth*1/2, quarterHeight*1/2);
95d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        x += xSpacing;
96d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y, NULL, quarterWidth*3/2, quarterHeight*3/2);
97d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
98d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com              quarterWidth*3/2, quarterHeight*3/2);
99d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        x += xSpacing;
100d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y, NULL, quarterWidth*5/2, quarterHeight*5/2);
101d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
102d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com              quarterWidth*5/2, quarterHeight*5/2);
103d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        x += xSpacing;
104d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y, NULL, quarterWidth*9/2, quarterHeight*9/2);
105d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
106d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com              quarterWidth*9/2, quarterHeight*9/2);
107d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    }
108d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
109d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    void drawLabel(SkCanvas* canvas, const char *text, int startX, int startY,
110d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                 int endX, int endY) {
111d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        SkPaint paint;
112d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        paint.setColor(0xFF000000);
113d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        SkPath path;
114d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        path.moveTo(SkIntToScalar(startX), SkIntToScalar(startY));
115d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        path.lineTo(SkIntToScalar(endX), SkIntToScalar(endY));
116d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        canvas->drawTextOnPath(text, strlen(text), path, NULL, paint);
117d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    }
118d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
119d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    /** Stamp out 9 copies of origBitmap, scrolled in each direction (and
120d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com     *  not scrolled at all).
121d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com     */
122d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    void draw9(SkCanvas* canvas, int x, int y, SkIRect* subset,
123d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com               int scrollX, int scrollY) {
124d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        for (int yMult=-1; yMult<=1; yMult++) {
125d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com            for (int xMult=-1; xMult<=1; xMult++) {
126d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                // Figure out the (x,y) to draw this copy at
127d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                SkScalar bitmapX = SkIntToScalar(
128d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                    x + quarterWidth * 5 * (xMult+1));
129d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                SkScalar bitmapY = SkIntToScalar(
130d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                    y + quarterHeight * 5 * (yMult+1));
131d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
132d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                // Scroll a new copy of the bitmap, and then draw it.
133d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                // scrollRect() should always return true, even if it's a no-op
134d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                SkBitmap scrolledBitmap;
1350e51577a14f903ffeafa117a75954baeb173ffb9humper@google.com                SkDEBUGCODE(bool copyToReturnValue = )origBitmap.copyTo(
1368a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org                    &scrolledBitmap, origBitmap.colorType());
1376b66c398f998418a001d664dce54f502c1d5e167epoger@google.com                SkASSERT(copyToReturnValue);
1380e51577a14f903ffeafa117a75954baeb173ffb9humper@google.com                SkDEBUGCODE(bool scrollRectReturnValue = )scrolledBitmap.scrollRect(
1396b66c398f998418a001d664dce54f502c1d5e167epoger@google.com                    subset, scrollX * xMult, scrollY * yMult);
1406b66c398f998418a001d664dce54f502c1d5e167epoger@google.com                SkASSERT(scrollRectReturnValue);
141d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                canvas->drawBitmap(scrolledBitmap, bitmapX, bitmapY);
142d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com            }
143d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        }
144d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    }
145d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
146d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.comprivate:
147d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    typedef GM INHERITED;
148d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    static const int quarterWidth = 10;
149d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    static const int quarterHeight = 14;
150d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    SkBitmap origBitmap;
151d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com};
152d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
153d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com//////////////////////////////////////////////////////////////////////////////
154d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
155d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.comstatic GM* MyFactory(void*) { return new BitmapScrollGM; }
156d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.comstatic GMRegistry reg(MyFactory);
157d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
158d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com}
159