|  |  | 
|  | /* | 
|  | * 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->allocN32Pixels(quarterWidth*4, quarterHeight*4); | 
|  | 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 { | 
|  | bool fInited; | 
|  | void init() { | 
|  | if (fInited) { | 
|  | return; | 
|  | } | 
|  | fInited = true; | 
|  | // Create the original bitmap. | 
|  | make_bitmap(quarterWidth, quarterHeight, &origBitmap); | 
|  | } | 
|  |  | 
|  | public: | 
|  | BitmapScrollGM() { | 
|  | fInited = false; | 
|  | this->setBGColor(0xFFDDDDDD); | 
|  | } | 
|  |  | 
|  | protected: | 
|  | virtual SkString onShortName() { | 
|  | return SkString("bitmapscroll"); | 
|  | } | 
|  |  | 
|  | virtual SkISize onISize() { | 
|  | return make_isize(800, 600); | 
|  | } | 
|  |  | 
|  | virtual void onDraw(SkCanvas* canvas) { | 
|  | this->init(); | 
|  | 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; | 
|  | SkDEBUGCODE(bool copyToReturnValue = )origBitmap.copyTo( | 
|  | &scrolledBitmap, origBitmap.colorType()); | 
|  | SkASSERT(copyToReturnValue); | 
|  | SkDEBUGCODE(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); | 
|  |  | 
|  | } |