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:
6236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkString onShortName() override {
63d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        return SkString("bitmapscroll");
64d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    }
65d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
6636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkISize onISize() override {
67f539318f0d3dba743ec1886d5d9df0fb1be628a1tfarina      return SkISize::Make(800, 600);
68d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    }
69d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
7036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onDraw(SkCanvas* canvas) override {
719afc656df6e81a17ab591b607a92755a5a2e06ccreed@google.com        this->init();
72d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        SkIRect scrollCenterRegion = SkIRect::MakeXYWH(
734067d7d5cdbf6d052cf1519c79db82bad9e47b7eepoger@google.com            quarterWidth, quarterHeight, quarterWidth*2+1, quarterHeight*2+1);
74d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        int x = quarterWidth;
75d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        int y = quarterHeight;
76d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        int xSpacing = quarterWidth * 20;
77d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        int ySpacing = quarterHeight * 16;
78d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
7948dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        // Draw left-hand text labels.
80d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        drawLabel(canvas, "scroll entire bitmap",
81d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                  x, y, x, y + ySpacing);
82d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        drawLabel(canvas, "scroll part of bitmap",
83d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                  x, y + ySpacing, x, y + ySpacing*2);
84d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        x += 30;
85d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
86d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        // Draw various permutations of scrolled bitmaps, scrolling a bit
87d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        // further each time.
88d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y, NULL, quarterWidth*1/2, quarterHeight*1/2);
89d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
90d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com              quarterWidth*1/2, quarterHeight*1/2);
91d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        x += xSpacing;
92d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y, NULL, quarterWidth*3/2, quarterHeight*3/2);
93d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
94d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com              quarterWidth*3/2, quarterHeight*3/2);
95d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        x += xSpacing;
96d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y, NULL, quarterWidth*5/2, quarterHeight*5/2);
97d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
98d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com              quarterWidth*5/2, quarterHeight*5/2);
99d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        x += xSpacing;
100d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y, NULL, quarterWidth*9/2, quarterHeight*9/2);
101d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        draw9(canvas, x, y+ySpacing, &scrollCenterRegion,
102d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com              quarterWidth*9/2, quarterHeight*9/2);
103d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    }
104d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
105d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    void drawLabel(SkCanvas* canvas, const char *text, int startX, int startY,
106d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                 int endX, int endY) {
107d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        SkPaint paint;
1085fb6bd4b7e8d00b7f2543ca10ec9022b32632f29caryclark        sk_tool_utils::set_portable_typeface(&paint);
109d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        paint.setColor(0xFF000000);
110d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        SkPath path;
111d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        path.moveTo(SkIntToScalar(startX), SkIntToScalar(startY));
112d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        path.lineTo(SkIntToScalar(endX), SkIntToScalar(endY));
113d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        canvas->drawTextOnPath(text, strlen(text), path, NULL, paint);
114d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    }
115d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
116d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    /** Stamp out 9 copies of origBitmap, scrolled in each direction (and
117d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com     *  not scrolled at all).
118d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com     */
119d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    void draw9(SkCanvas* canvas, int x, int y, SkIRect* subset,
120d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com               int scrollX, int scrollY) {
121d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        for (int yMult=-1; yMult<=1; yMult++) {
122d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com            for (int xMult=-1; xMult<=1; xMult++) {
123d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                // Figure out the (x,y) to draw this copy at
124d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                SkScalar bitmapX = SkIntToScalar(
125d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                    x + quarterWidth * 5 * (xMult+1));
126d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                SkScalar bitmapY = SkIntToScalar(
127d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                    y + quarterHeight * 5 * (yMult+1));
128d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
129d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                // Scroll a new copy of the bitmap, and then draw it.
130d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                // scrollRect() should always return true, even if it's a no-op
131d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                SkBitmap scrolledBitmap;
1320e51577a14f903ffeafa117a75954baeb173ffb9humper@google.com                SkDEBUGCODE(bool copyToReturnValue = )origBitmap.copyTo(
1338a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org                    &scrolledBitmap, origBitmap.colorType());
1346b66c398f998418a001d664dce54f502c1d5e167epoger@google.com                SkASSERT(copyToReturnValue);
1350e51577a14f903ffeafa117a75954baeb173ffb9humper@google.com                SkDEBUGCODE(bool scrollRectReturnValue = )scrolledBitmap.scrollRect(
1366b66c398f998418a001d664dce54f502c1d5e167epoger@google.com                    subset, scrollX * xMult, scrollY * yMult);
1376b66c398f998418a001d664dce54f502c1d5e167epoger@google.com                SkASSERT(scrollRectReturnValue);
138d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com                canvas->drawBitmap(scrolledBitmap, bitmapX, bitmapY);
139d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com            }
140d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com        }
141d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    }
142d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
143d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.comprivate:
144d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    typedef GM INHERITED;
145d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    static const int quarterWidth = 10;
146d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    static const int quarterHeight = 14;
147d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com    SkBitmap origBitmap;
148d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com};
149d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
150d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com//////////////////////////////////////////////////////////////////////////////
151d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
152d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.comstatic GM* MyFactory(void*) { return new BitmapScrollGM; }
153d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.comstatic GMRegistry reg(MyFactory);
154d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com
155d4af56c5f24a7bf0200e20a591d55f8c82fb9627epoger@google.com}
156