Exit SkBitmap::scrollRect() early if width <= 0

As suggested in email from saintlou@google.com
Review URL: http://codereview.appspot.com/4806047

git-svn-id: http://skia.googlecode.com/svn/trunk@1948 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/bitmapscroll.cpp b/gm/bitmapscroll.cpp
new file mode 100644
index 0000000..de7130d
--- /dev/null
+++ b/gm/bitmapscroll.cpp
@@ -0,0 +1,136 @@
+#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;
+    pRed.setColor(0xFFFF9999);
+    pWhite.setColor(0xFFFFFFFF);
+    pGreen.setColor(0xFF99FF99);
+    pBlue.setColor(0xFF9999FF);
+    pLine.setColor(0xFF000000);
+    pLine.setStyle(SkPaint::kStroke_Style);
+
+    // 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.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);
+    }
+
+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, quarterHeight*2);
+        int x = quarterWidth;
+        int y = quarterHeight;
+        int xSpacing = quarterWidth * 20;
+        int ySpacing = quarterHeight * 16;
+
+        // Draw background and left-hand text labels.
+        canvas->drawColor(0xFFDDDDDD);
+        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;
+                SkASSERT(origBitmap.copyTo(
+                    &scrolledBitmap, origBitmap.config()));
+                SkASSERT(scrolledBitmap.scrollRect(
+                    subset, scrollX * xMult, scrollY * yMult));
+                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);
+
+}
diff --git a/gm/gm.h b/gm/gm.h
index ab92ff6..ce10ec7 100644
--- a/gm/gm.h
+++ b/gm/gm.h
@@ -1,7 +1,9 @@
 #ifndef skiagm_DEFINED
 #define skiagm_DEFINED
 
+#include "SkBitmap.h"
 #include "SkCanvas.h"
+#include "SkDevice.h"
 #include "SkPaint.h"
 #include "SkRefCnt.h"
 #include "SkSize.h"