/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/*  Description:
 *      This test defines a series of elementatry test steps that perform
 *      a single or a small group of canvas API calls. Each test step is
 *      used in several test cases that verify that different types of SkCanvas
 *      flavors and derivatives pass it and yield consistent behavior. The
 *      test cases analyse results that are queryable through the API. They do
 *      not look at rendering results.
 *
 *  Adding test stepss:
 *      The general pattern for creating a new test step is to write a test
 *      function of the form:
 *
 *          static void MyTestStepFunction(SkCanvas* canvas,
 *                                         skiatest::Reporter* reporter,
 *                                         CanvasTestStep* testStep)
 *          {
 *              canvas->someCanvasAPImethod();
 *              (...)
 *              REPORTER_ASSERT_MESSAGE(reporter, (...), \
 *                  testStep->assertMessage());
 *          }
 *
 *      The definition of the test step function should be followed by an
 *      invocation of the TEST_STEP macro, which generates a class and
 *      instance for the test step:
 *
 *          TEST_STEP(MyTestStep, MyTestStepFunction)
 *
 *      There are also short hand macros for defining simple test steps
 *      in a single line of code.  A simple test step is a one that is made
 *      of a single canvas API call.
 *
 *          SIMPLE_TEST_STEP(MytestStep, someCanvasAPIMethod());
 *
 *      There is another macro called SIMPLE_TEST_STEP_WITH_ASSERT that
 *      works the same way as SIMPLE_TEST_STEP, and additionally verifies
 *      that the invoked method returns a non-zero value.
 */
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkDeferredCanvas.h"
#include "SkDevice.h"
#include "SkMatrix.h"
#include "SkNWayCanvas.h"
#include "SkPDFDevice.h"
#include "SkPDFDocument.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkPicture.h"
#include "SkPictureRecord.h"
#include "SkPictureRecorder.h"
#include "SkProxyCanvas.h"
#include "SkRect.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkStream.h"
#include "SkSurface.h"
#include "SkTDArray.h"
#include "Test.h"

static bool equal_clips(const SkCanvas& a, const SkCanvas& b) {
    if (a.isClipEmpty()) {
        return b.isClipEmpty();
    }
    if (!a.isClipRect()) {
        // this is liberally true, since we don't expose a way to know this exactly (for non-rects)
        return !b.isClipRect();
    }
    SkIRect ar, br;
    a.getClipDeviceBounds(&ar);
    b.getClipDeviceBounds(&br);
    return ar == br;
}

class Canvas2CanvasClipVisitor : public SkCanvas::ClipVisitor {
public:
    Canvas2CanvasClipVisitor(SkCanvas* target) : fTarget(target) {}

    virtual void clipRect(const SkRect& r, SkRegion::Op op, bool aa) SK_OVERRIDE {
        fTarget->clipRect(r, op, aa);
    }
    virtual void clipRRect(const SkRRect& r, SkRegion::Op op, bool aa) SK_OVERRIDE {
        fTarget->clipRRect(r, op, aa);
    }
    virtual void clipPath(const SkPath& p, SkRegion::Op op, bool aa) SK_OVERRIDE {
        fTarget->clipPath(p, op, aa);
    }

private:
    SkCanvas* fTarget;
};

static void test_clipVisitor(skiatest::Reporter* reporter, SkCanvas* canvas) {
    SkISize size = canvas->getDeviceSize();

    SkBitmap bm;
    bm.setInfo(SkImageInfo::MakeN32Premul(size.width(), size.height()));
    SkCanvas c(bm);

    Canvas2CanvasClipVisitor visitor(&c);
    canvas->replayClips(&visitor);

    REPORTER_ASSERT(reporter, equal_clips(c, *canvas));
}

static const int kWidth = 2;
static const int kHeight = 2;

// Format strings that describe the test context.  The %s token is where
// the name of the test step is inserted.  The context is required for
// disambiguating the error in the case of failures that are reported in
// functions that are called multiple times in different contexts (test
// cases and test steps).
static const char* const kDefaultAssertMessageFormat = "%s";
static const char* const kCanvasDrawAssertMessageFormat =
    "Drawing test step %s with SkCanvas";
static const char* const kPictureDrawAssertMessageFormat =
    "Drawing test step %s with SkPicture";
static const char* const kPictureSecondDrawAssertMessageFormat =
    "Duplicate draw of test step %s with SkPicture";
static const char* const kDeferredDrawAssertMessageFormat =
    "Drawing test step %s with SkDeferredCanvas";
static const char* const kProxyDrawAssertMessageFormat =
    "Drawing test step %s with SkProxyCanvas";
static const char* const kNWayDrawAssertMessageFormat =
    "Drawing test step %s with SkNWayCanvas";
static const char* const kDeferredPreFlushAssertMessageFormat =
    "test step %s, SkDeferredCanvas state consistency before flush";
static const char* const kDeferredPostFlushPlaybackAssertMessageFormat =
    "test step %s, SkDeferredCanvas playback canvas state consistency after flush";
static const char* const kDeferredPostSilentFlushPlaybackAssertMessageFormat =
    "test step %s, SkDeferredCanvas playback canvas state consistency after silent flush";
static const char* const kPictureResourceReuseMessageFormat =
    "test step %s, SkPicture duplicate flattened object test";
static const char* const kProxyStateAssertMessageFormat =
    "test step %s, SkProxyCanvas state consistency";
static const char* const kProxyIndirectStateAssertMessageFormat =
    "test step %s, SkProxyCanvas indirect canvas state consistency";
static const char* const kNWayStateAssertMessageFormat =
    "test step %s, SkNWayCanvas state consistency";
static const char* const kNWayIndirect1StateAssertMessageFormat =
    "test step %s, SkNWayCanvas indirect canvas 1 state consistency";
static const char* const kNWayIndirect2StateAssertMessageFormat =
    "test step %s, SkNWayCanvas indirect canvas 2 state consistency";
static const char* const kPdfAssertMessageFormat =
    "PDF sanity check failed %s";

static void createBitmap(SkBitmap* bm, SkColor color) {
    bm->allocN32Pixels(kWidth, kHeight);
    bm->eraseColor(color);
}

static SkSurface* createSurface(SkColor color) {
    SkSurface* surface = SkSurface::NewRasterPMColor(kWidth, kHeight);
    surface->getCanvas()->clear(color);
    return surface;
}

class CanvasTestStep;
static SkTDArray<CanvasTestStep*>& testStepArray() {
    static SkTDArray<CanvasTestStep*> theTests;
    return theTests;
}

class CanvasTestStep {
public:
    CanvasTestStep(bool fEnablePdfTesting = true) {
        *testStepArray().append() = this;
        fAssertMessageFormat = kDefaultAssertMessageFormat;
        this->fEnablePdfTesting = fEnablePdfTesting;
    }
    virtual ~CanvasTestStep() { }

    virtual void draw(SkCanvas*, skiatest::Reporter*) = 0;
    virtual const char* name() const = 0;

    const char* assertMessage() {
        fAssertMessage.printf(fAssertMessageFormat, name());
        return fAssertMessage.c_str();
    }

    void setAssertMessageFormat(const char* format) {
        fAssertMessageFormat = format;
    }

    bool enablePdfTesting() { return fEnablePdfTesting; }

private:
    SkString fAssertMessage;
    const char* fAssertMessageFormat;
    bool fEnablePdfTesting;
};

///////////////////////////////////////////////////////////////////////////////
// Constants used by test steps

const SkRect kTestRect =
    SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
                     SkIntToScalar(2), SkIntToScalar(1));
static SkMatrix testMatrix() {
    SkMatrix matrix;
    matrix.reset();
    matrix.setScale(SkIntToScalar(2), SkIntToScalar(3));
    return matrix;
}
const SkMatrix kTestMatrix = testMatrix();
static SkPath test_path() {
    SkPath path;
    path.addRect(SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
                                  SkIntToScalar(2), SkIntToScalar(1)));
    return path;
}
const SkPath kTestPath = test_path();
static SkPath test_nearly_zero_length_path() {
    SkPath path;
    SkPoint pt1 = { 0, 0 };
    SkPoint pt2 = { 0, SK_ScalarNearlyZero };
    SkPoint pt3 = { SkIntToScalar(1), 0 };
    SkPoint pt4 = { SkIntToScalar(1), SK_ScalarNearlyZero/2 };
    path.moveTo(pt1);
    path.lineTo(pt2);
    path.lineTo(pt3);
    path.lineTo(pt4);
    return path;
}
const SkPath kNearlyZeroLengthPath = test_nearly_zero_length_path();
static SkRegion testRegion() {
    SkRegion region;
    SkIRect rect = SkIRect::MakeXYWH(0, 0, 2, 1);
    region.setRect(rect);
    return region;
}
const SkIRect kTestIRect = SkIRect::MakeXYWH(0, 0, 2, 1);
const SkRegion kTestRegion = testRegion();
const SkColor kTestColor = 0x01020304;
const SkPaint kTestPaint;
const SkPoint kTestPoints[3] = {
    {SkIntToScalar(0), SkIntToScalar(0)},
    {SkIntToScalar(2), SkIntToScalar(1)},
    {SkIntToScalar(0), SkIntToScalar(2)}
};
const size_t kTestPointCount = 3;
static SkBitmap testBitmap() {
    SkBitmap bitmap;
    createBitmap(&bitmap, 0x05060708);
    return bitmap;
}
SkBitmap kTestBitmap; // cannot be created during static init
SkString kTestText("Hello World");
SkPoint kTestPoints2[] = {
  { SkIntToScalar(0), SkIntToScalar(1) },
  { SkIntToScalar(1), SkIntToScalar(1) },
  { SkIntToScalar(2), SkIntToScalar(1) },
  { SkIntToScalar(3), SkIntToScalar(1) },
  { SkIntToScalar(4), SkIntToScalar(1) },
  { SkIntToScalar(5), SkIntToScalar(1) },
  { SkIntToScalar(6), SkIntToScalar(1) },
  { SkIntToScalar(7), SkIntToScalar(1) },
  { SkIntToScalar(8), SkIntToScalar(1) },
  { SkIntToScalar(9), SkIntToScalar(1) },
  { SkIntToScalar(10), SkIntToScalar(1) },
};


///////////////////////////////////////////////////////////////////////////////
// Macros for defining test steps

#define TEST_STEP(NAME, FUNCTION)                                       \
class NAME##_TestStep : public CanvasTestStep{                          \
public:                                                                 \
    virtual void draw(SkCanvas* canvas, skiatest::Reporter* reporter) { \
        FUNCTION (canvas, reporter, this);                              \
    }                                                                   \
    virtual const char* name() const {return #NAME ;}                   \
};                                                                      \
static NAME##_TestStep NAME##_TestStepInstance;

#define TEST_STEP_NO_PDF(NAME, FUNCTION)                                       \
class NAME##_TestStep : public CanvasTestStep{                          \
public:                                                                 \
    NAME##_TestStep() : CanvasTestStep(false) {}                        \
    virtual void draw(SkCanvas* canvas, skiatest::Reporter* reporter) { \
        FUNCTION (canvas, reporter, this);                              \
    }                                                                   \
    virtual const char* name() const {return #NAME ;}                   \
};                                                                      \
static NAME##_TestStep NAME##_TestStepInstance;

#define SIMPLE_TEST_STEP(NAME, CALL)                              \
static void NAME##TestStep(SkCanvas* canvas, skiatest::Reporter*, \
    CanvasTestStep*) {                                            \
    canvas-> CALL ;                                               \
}                                                                 \
TEST_STEP(NAME, NAME##TestStep )

#define SIMPLE_TEST_STEP_WITH_ASSERT(NAME, CALL)                           \
static void NAME##TestStep(SkCanvas* canvas, skiatest::Reporter* reporter, \
    CanvasTestStep* testStep) {                                            \
    REPORTER_ASSERT_MESSAGE(reporter, canvas-> CALL ,                      \
        testStep->assertMessage());                                        \
}                                                                          \
TEST_STEP(NAME, NAME##TestStep )


///////////////////////////////////////////////////////////////////////////////
// Basic test steps for most virtual methods in SkCanvas that draw or affect
// the state of the canvas.

SIMPLE_TEST_STEP(Translate, translate(SkIntToScalar(1), SkIntToScalar(2)));
SIMPLE_TEST_STEP(Scale, scale(SkIntToScalar(1), SkIntToScalar(2)));
SIMPLE_TEST_STEP(Rotate, rotate(SkIntToScalar(1)));
SIMPLE_TEST_STEP(Skew, skew(SkIntToScalar(1), SkIntToScalar(2)));
SIMPLE_TEST_STEP(Concat, concat(kTestMatrix));
SIMPLE_TEST_STEP(SetMatrix, setMatrix(kTestMatrix));
SIMPLE_TEST_STEP(ClipRect, clipRect(kTestRect));
SIMPLE_TEST_STEP(ClipPath, clipPath(kTestPath));
SIMPLE_TEST_STEP(ClipRegion,
    clipRegion(kTestRegion, SkRegion::kReplace_Op));
SIMPLE_TEST_STEP(Clear, clear(kTestColor));
SIMPLE_TEST_STEP(DrawPaint, drawPaint(kTestPaint));
SIMPLE_TEST_STEP(DrawPointsPoints, drawPoints(SkCanvas::kPoints_PointMode,
    kTestPointCount, kTestPoints, kTestPaint));
SIMPLE_TEST_STEP(DrawPointsLiness, drawPoints(SkCanvas::kLines_PointMode,
    kTestPointCount, kTestPoints, kTestPaint));
SIMPLE_TEST_STEP(DrawPointsPolygon, drawPoints(SkCanvas::kPolygon_PointMode,
    kTestPointCount, kTestPoints, kTestPaint));
SIMPLE_TEST_STEP(DrawRect, drawRect(kTestRect, kTestPaint));
SIMPLE_TEST_STEP(DrawPath, drawPath(kTestPath, kTestPaint));
SIMPLE_TEST_STEP(DrawBitmap, drawBitmap(kTestBitmap, 0, 0));
SIMPLE_TEST_STEP(DrawBitmapPaint, drawBitmap(kTestBitmap, 0, 0, &kTestPaint));
SIMPLE_TEST_STEP(DrawBitmapRect, drawBitmapRect(kTestBitmap, NULL, kTestRect,
    NULL));
SIMPLE_TEST_STEP(DrawBitmapRectSrcRect, drawBitmapRect(kTestBitmap,
    &kTestIRect, kTestRect, NULL));
SIMPLE_TEST_STEP(DrawBitmapRectPaint, drawBitmapRect(kTestBitmap, NULL,
    kTestRect, &kTestPaint));
SIMPLE_TEST_STEP(DrawBitmapMatrix, drawBitmapMatrix(kTestBitmap, kTestMatrix,
    NULL));
SIMPLE_TEST_STEP(DrawBitmapMatrixPaint, drawBitmapMatrix(kTestBitmap,
    kTestMatrix, &kTestPaint));
SIMPLE_TEST_STEP(DrawBitmapNine, drawBitmapNine(kTestBitmap, kTestIRect,
    kTestRect, NULL));
SIMPLE_TEST_STEP(DrawBitmapNinePaint, drawBitmapNine(kTestBitmap, kTestIRect,
    kTestRect, &kTestPaint));
SIMPLE_TEST_STEP(DrawSprite, drawSprite(kTestBitmap, 0, 0, NULL));
SIMPLE_TEST_STEP(DrawSpritePaint, drawSprite(kTestBitmap, 0, 0, &kTestPaint));
SIMPLE_TEST_STEP(DrawText, drawText(kTestText.c_str(), kTestText.size(),
    0, 1, kTestPaint));
SIMPLE_TEST_STEP(DrawPosText, drawPosText(kTestText.c_str(),
    kTestText.size(), kTestPoints2, kTestPaint));
SIMPLE_TEST_STEP(DrawTextOnPath, drawTextOnPath(kTestText.c_str(),
    kTestText.size(), kTestPath, NULL, kTestPaint));
SIMPLE_TEST_STEP(DrawTextOnPathMatrix, drawTextOnPath(kTestText.c_str(),
    kTestText.size(), kTestPath, &kTestMatrix, kTestPaint));
SIMPLE_TEST_STEP(DrawData, drawData(kTestText.c_str(), kTestText.size()));
SIMPLE_TEST_STEP(BeginGroup, beginCommentGroup(kTestText.c_str()));
SIMPLE_TEST_STEP(AddComment, addComment(kTestText.c_str(), kTestText.c_str()));
SIMPLE_TEST_STEP(EndGroup, endCommentGroup());

///////////////////////////////////////////////////////////////////////////////
// Complex test steps

static void SaveMatrixClipStep(SkCanvas* canvas,
                               skiatest::Reporter* reporter,
                               CanvasTestStep* testStep) {
    int saveCount = canvas->getSaveCount();
    canvas->save();
    canvas->translate(SkIntToScalar(1), SkIntToScalar(2));
    canvas->clipRegion(kTestRegion);
    canvas->restore();
    REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
        testStep->assertMessage());
    REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalMatrix().isIdentity(),
        testStep->assertMessage());
//    REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalClip() != kTestRegion, testStep->assertMessage());
}
TEST_STEP(SaveMatrixClip, SaveMatrixClipStep);

static void SaveLayerStep(SkCanvas* canvas,
                          skiatest::Reporter* reporter,
                          CanvasTestStep* testStep) {
    int saveCount = canvas->getSaveCount();
    canvas->saveLayer(NULL, NULL);
    canvas->restore();
    REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
        testStep->assertMessage());
}
TEST_STEP(SaveLayer, SaveLayerStep);

static void BoundedSaveLayerStep(SkCanvas* canvas,
                          skiatest::Reporter* reporter,
                          CanvasTestStep* testStep) {
    int saveCount = canvas->getSaveCount();
    canvas->saveLayer(&kTestRect, NULL);
    canvas->restore();
    REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
        testStep->assertMessage());
}
TEST_STEP(BoundedSaveLayer, BoundedSaveLayerStep);

static void PaintSaveLayerStep(SkCanvas* canvas,
                          skiatest::Reporter* reporter,
                          CanvasTestStep* testStep) {
    int saveCount = canvas->getSaveCount();
    canvas->saveLayer(NULL, &kTestPaint);
    canvas->restore();
    REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
        testStep->assertMessage());
}
TEST_STEP(PaintSaveLayer, PaintSaveLayerStep);

static void TwoClipOpsStep(SkCanvas* canvas,
                           skiatest::Reporter*,
                           CanvasTestStep*) {
    // This test exercises a functionality in SkPicture that leads to the
    // recording of restore offset placeholders.  This test will trigger an
    // assertion at playback time if the placeholders are not properly
    // filled when the recording ends.
    canvas->clipRect(kTestRect);
    canvas->clipRegion(kTestRegion);
}
TEST_STEP(TwoClipOps, TwoClipOpsStep);

// exercise fix for http://code.google.com/p/skia/issues/detail?id=560
// ('SkPathStroker::lineTo() fails for line with length SK_ScalarNearlyZero')
static void DrawNearlyZeroLengthPathTestStep(SkCanvas* canvas,
                                             skiatest::Reporter*,
                                             CanvasTestStep*) {
    SkPaint paint;
    paint.setStrokeWidth(SkIntToScalar(1));
    paint.setStyle(SkPaint::kStroke_Style);

    canvas->drawPath(kNearlyZeroLengthPath, paint);
}
TEST_STEP(DrawNearlyZeroLengthPath, DrawNearlyZeroLengthPathTestStep);

static void DrawVerticesShaderTestStep(SkCanvas* canvas,
                                       skiatest::Reporter*,
                                       CanvasTestStep*) {
    SkPoint pts[4];
    pts[0].set(0, 0);
    pts[1].set(SkIntToScalar(kWidth), 0);
    pts[2].set(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
    pts[3].set(0, SkIntToScalar(kHeight));
    SkPaint paint;
    SkShader* shader = SkShader::CreateBitmapShader(kTestBitmap,
        SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
    paint.setShader(shader)->unref();
    canvas->drawVertices(SkCanvas::kTriangleFan_VertexMode, 4, pts, pts,
                         NULL, NULL, NULL, 0, paint);
}
// NYI: issue 240.
TEST_STEP_NO_PDF(DrawVerticesShader, DrawVerticesShaderTestStep);

static void DrawPictureTestStep(SkCanvas* canvas,
                                skiatest::Reporter*,
                                CanvasTestStep*) {
    SkPictureRecorder recorder;
    SkCanvas* testCanvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight), 
                                                   NULL, 0);
    testCanvas->scale(SkIntToScalar(2), SkIntToScalar(1));
    testCanvas->clipRect(kTestRect);
    testCanvas->drawRect(kTestRect, kTestPaint);
    SkAutoTUnref<SkPicture> testPicture(recorder.endRecording());

    canvas->drawPicture(testPicture);
}
TEST_STEP(DrawPicture, DrawPictureTestStep);

static void SaveRestoreTestStep(SkCanvas* canvas,
                                skiatest::Reporter* reporter,
                                CanvasTestStep* testStep) {
    int baseSaveCount = canvas->getSaveCount();
    int n = canvas->save();
    REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount == n, testStep->assertMessage());
    REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount + 1 == canvas->getSaveCount(),
        testStep->assertMessage());
    canvas->save();
    canvas->save();
    REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount + 3 == canvas->getSaveCount(),
        testStep->assertMessage());
    canvas->restoreToCount(baseSaveCount + 1);
    REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount + 1 == canvas->getSaveCount(),
        testStep->assertMessage());

    // should this pin to 1, or be a no-op, or crash?
    canvas->restoreToCount(0);
    REPORTER_ASSERT_MESSAGE(reporter, 1 == canvas->getSaveCount(),
        testStep->assertMessage());
}
TEST_STEP(SaveRestore, SaveRestoreTestStep);

static void DrawLayerTestStep(SkCanvas* canvas,
                              skiatest::Reporter* reporter,
                              CanvasTestStep* testStep) {
    REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
        testStep->assertMessage());
    canvas->save();
    REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
        testStep->assertMessage());
    canvas->restore();

    const SkRect* bounds = NULL;    // null means include entire bounds
    const SkPaint* paint = NULL;

    canvas->saveLayer(bounds, paint);
    REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(),
        testStep->assertMessage());
    canvas->restore();
    REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
        testStep->assertMessage());

    canvas->saveLayer(bounds, paint);
    canvas->saveLayer(bounds, paint);
    REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(),
        testStep->assertMessage());
    canvas->restore();
    REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(),
        testStep->assertMessage());
    canvas->restore();
    // now layer count should be 0
    REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
        testStep->assertMessage());
}
TEST_STEP(DrawLayer, DrawLayerTestStep);

static void NestedSaveRestoreWithSolidPaintTestStep(SkCanvas* canvas,
                                      skiatest::Reporter*,
                                      CanvasTestStep*) {
    // This test step challenges the TestDeferredCanvasStateConsistency
    // test cases because the opaque paint can trigger an optimization
    // that discards previously recorded commands. The challenge is to maintain
    // correct clip and matrix stack state.
    canvas->resetMatrix();
    canvas->rotate(SkIntToScalar(30));
    canvas->save();
    canvas->translate(SkIntToScalar(2), SkIntToScalar(1));
    canvas->save();
    canvas->scale(SkIntToScalar(3), SkIntToScalar(3));
    SkPaint paint;
    paint.setColor(0xFFFFFFFF);
    canvas->drawPaint(paint);
    canvas->restore();
    canvas->restore();
}
TEST_STEP(NestedSaveRestoreWithSolidPaint, \
    NestedSaveRestoreWithSolidPaintTestStep);

static void NestedSaveRestoreWithFlushTestStep(SkCanvas* canvas,
                                      skiatest::Reporter*,
                                      CanvasTestStep*) {
    // This test step challenges the TestDeferredCanvasStateConsistency
    // test case because the canvas flush on a deferred canvas will
    // reset the recording session. The challenge is to maintain correct
    // clip and matrix stack state on the playback canvas.
    canvas->resetMatrix();
    canvas->rotate(SkIntToScalar(30));
    canvas->save();
    canvas->translate(SkIntToScalar(2), SkIntToScalar(1));
    canvas->save();
    canvas->scale(SkIntToScalar(3), SkIntToScalar(3));
    canvas->drawRect(kTestRect,kTestPaint);
    canvas->flush();
    canvas->restore();
    canvas->restore();
}
TEST_STEP(NestedSaveRestoreWithFlush, \
    NestedSaveRestoreWithFlushTestStep);

static void AssertCanvasStatesEqual(skiatest::Reporter* reporter,
                                    const SkCanvas* canvas1,
                                    const SkCanvas* canvas2,
                                    CanvasTestStep* testStep) {
    REPORTER_ASSERT_MESSAGE(reporter, canvas1->getDeviceSize() ==
        canvas2->getDeviceSize(), testStep->assertMessage());
    REPORTER_ASSERT_MESSAGE(reporter, canvas1->getSaveCount() ==
        canvas2->getSaveCount(), testStep->assertMessage());
    REPORTER_ASSERT_MESSAGE(reporter, canvas1->isDrawingToLayer() ==
        canvas2->isDrawingToLayer(), testStep->assertMessage());

    SkRect bounds1, bounds2;
    REPORTER_ASSERT_MESSAGE(reporter,
        canvas1->getClipBounds(&bounds1) == canvas2->getClipBounds(&bounds2),
        testStep->assertMessage());
    REPORTER_ASSERT_MESSAGE(reporter, bounds1 == bounds2,
                            testStep->assertMessage());

    REPORTER_ASSERT_MESSAGE(reporter, canvas1->getDrawFilter() ==
        canvas2->getDrawFilter(), testStep->assertMessage());
    SkIRect deviceBounds1, deviceBounds2;
    REPORTER_ASSERT_MESSAGE(reporter,
        canvas1->getClipDeviceBounds(&deviceBounds1) ==
        canvas2->getClipDeviceBounds(&deviceBounds2),
        testStep->assertMessage());
    REPORTER_ASSERT_MESSAGE(reporter, deviceBounds1 == deviceBounds2, testStep->assertMessage());
    REPORTER_ASSERT_MESSAGE(reporter, canvas1->getTotalMatrix() ==
        canvas2->getTotalMatrix(), testStep->assertMessage());
    REPORTER_ASSERT_MESSAGE(reporter, equal_clips(*canvas1, *canvas2), testStep->assertMessage());

    // The following test code is commented out because the test fails when
    // the canvas is an SkPictureRecord or SkDeferredCanvas
    // Issue: http://code.google.com/p/skia/issues/detail?id=498
    // Also, creating a LayerIter on an SkProxyCanvas crashes
    // Issue: http://code.google.com/p/skia/issues/detail?id=499
    /*
    SkCanvas::LayerIter layerIter1(const_cast<SkCanvas*>(canvas1), false);
    SkCanvas::LayerIter layerIter2(const_cast<SkCanvas*>(canvas2), false);
    while (!layerIter1.done() && !layerIter2.done()) {
        REPORTER_ASSERT_MESSAGE(reporter, layerIter1.matrix() ==
            layerIter2.matrix(), testStep->assertMessage());
        REPORTER_ASSERT_MESSAGE(reporter, layerIter1.clip() ==
            layerIter2.clip(), testStep->assertMessage());
        REPORTER_ASSERT_MESSAGE(reporter, layerIter1.paint() ==
            layerIter2.paint(), testStep->assertMessage());
        REPORTER_ASSERT_MESSAGE(reporter, layerIter1.x() ==
            layerIter2.x(), testStep->assertMessage());
        REPORTER_ASSERT_MESSAGE(reporter, layerIter1.y() ==
            layerIter2.y(), testStep->assertMessage());
        layerIter1.next();
        layerIter2.next();
    }
    REPORTER_ASSERT_MESSAGE(reporter, layerIter1.done(),
        testStep->assertMessage());
    REPORTER_ASSERT_MESSAGE(reporter, layerIter2.done(),
        testStep->assertMessage());
    */
}

// The following class groups static functions that need to access
// the privates members of SkPictureRecord
class SkPictureTester {
private:
    static int EQ(const SkFlatData* a, const SkFlatData* b) {
        return *a == *b;
    }

    static void AssertFlattenedObjectsEqual(
        SkPictureRecord* referenceRecord,
        SkPictureRecord* testRecord,
        skiatest::Reporter* reporter,
        CanvasTestStep* testStep) {

        REPORTER_ASSERT_MESSAGE(reporter,
            referenceRecord->fBitmapHeap->count() ==
            testRecord->fBitmapHeap->count(), testStep->assertMessage());
        REPORTER_ASSERT_MESSAGE(reporter,
            referenceRecord->fPaints.count() ==
            testRecord->fPaints.count(), testStep->assertMessage());
        for (int i = 0; i < referenceRecord->fPaints.count(); ++i) {
            REPORTER_ASSERT_MESSAGE(reporter,
                EQ(referenceRecord->fPaints[i], testRecord->fPaints[i]),
                                    testStep->assertMessage());
        }
        REPORTER_ASSERT_MESSAGE(reporter,
            !referenceRecord->fPathHeap == !testRecord->fPathHeap,
            testStep->assertMessage());
        // The following tests are commented out because they currently
        // fail. Issue: http://code.google.com/p/skia/issues/detail?id=507
        /*
        if (referenceRecord->fPathHeap) {
            REPORTER_ASSERT_MESSAGE(reporter,
                referenceRecord->fPathHeap->count() ==
                testRecord->fPathHeap->count(),
                testStep->assertMessage());
            for (int i = 0; i < referenceRecord->fPathHeap->count(); ++i) {
                REPORTER_ASSERT_MESSAGE(reporter,
                    (*referenceRecord->fPathHeap)[i] ==
                    (*testRecord->fPathHeap)[i], testStep->assertMessage());
            }
        }
        */

    }

public:

    static void TestPictureFlattenedObjectReuse(skiatest::Reporter* reporter,
                                                CanvasTestStep* testStep,
                                                uint32_t recordFlags) {
        // Verify that when a test step is executed twice, no extra resources
        // are flattened during the second execution
        testStep->setAssertMessageFormat(kPictureDrawAssertMessageFormat);
        SkPictureRecorder referenceRecorder;
        SkCanvas* referenceCanvas =
            referenceRecorder.DEPRECATED_beginRecording(SkIntToScalar(kWidth), 
                                                        SkIntToScalar(kHeight), 
                                                        NULL, recordFlags);
        testStep->draw(referenceCanvas, reporter);

        SkPictureRecorder testRecorder;
        SkCanvas* testCanvas =
            testRecorder.DEPRECATED_beginRecording(SkIntToScalar(kWidth), 
                                                   SkIntToScalar(kHeight), 
                                                   NULL, recordFlags);
        testStep->draw(testCanvas, reporter);
        testStep->setAssertMessageFormat(kPictureSecondDrawAssertMessageFormat);
        testStep->draw(testCanvas, reporter);

        SkPictureRecord* referenceRecord = static_cast<SkPictureRecord*>(referenceCanvas);
        SkPictureRecord* testRecord = static_cast<SkPictureRecord*>(testCanvas);
        testStep->setAssertMessageFormat(kPictureResourceReuseMessageFormat);
        AssertFlattenedObjectsEqual(referenceRecord, testRecord,
                                    reporter, testStep);
    }
};

static void TestPdfDevice(skiatest::Reporter* reporter,
                          CanvasTestStep* testStep) {
    SkISize pageSize = SkISize::Make(kWidth, kHeight);
    SkPDFDevice device(pageSize, pageSize, SkMatrix::I());
    SkCanvas canvas(&device);
    testStep->setAssertMessageFormat(kPdfAssertMessageFormat);
    testStep->draw(&canvas, reporter);
    SkPDFDocument doc;
    doc.appendPage(&device);
    SkDynamicMemoryWStream stream;
    doc.emitPDF(&stream);
}

// The following class groups static functions that need to access
// the privates members of SkDeferredCanvas
class SkDeferredCanvasTester {
public:
    static void TestDeferredCanvasStateConsistency(
        skiatest::Reporter* reporter,
        CanvasTestStep* testStep,
        const SkCanvas& referenceCanvas, bool silent) {

        SkAutoTUnref<SkSurface> surface(createSurface(0xFFFFFFFF));
        SkAutoTUnref<SkDeferredCanvas> deferredCanvas(SkDeferredCanvas::Create(surface.get()));

        testStep->setAssertMessageFormat(kDeferredDrawAssertMessageFormat);
        testStep->draw(deferredCanvas, reporter);
        testStep->setAssertMessageFormat(kDeferredPreFlushAssertMessageFormat);
        AssertCanvasStatesEqual(reporter, deferredCanvas, &referenceCanvas,
            testStep);

        if (silent) {
            deferredCanvas->silentFlush();
        } else {
            deferredCanvas->flush();
        }

        testStep->setAssertMessageFormat(
            silent ? kDeferredPostSilentFlushPlaybackAssertMessageFormat :
            kDeferredPostFlushPlaybackAssertMessageFormat);
        AssertCanvasStatesEqual(reporter,
            deferredCanvas->immediateCanvas(),
            &referenceCanvas, testStep);

        // Verified that deferred canvas state is not affected by flushing
        // pending draw operations

        // The following test code is commented out because it currently fails.
        // Issue: http://code.google.com/p/skia/issues/detail?id=496
        /*
        testStep->setAssertMessageFormat(kDeferredPostFlushAssertMessageFormat);
        AssertCanvasStatesEqual(reporter, &deferredCanvas, &referenceCanvas,
            testStep);
        */
    }
};

// unused
static void TestProxyCanvasStateConsistency(
    skiatest::Reporter* reporter,
    CanvasTestStep* testStep,
    const SkCanvas& referenceCanvas) {

    SkBitmap indirectStore;
    createBitmap(&indirectStore, 0xFFFFFFFF);
    SkCanvas indirectCanvas(indirectStore);
    SkProxyCanvas proxyCanvas(&indirectCanvas);
    testStep->setAssertMessageFormat(kProxyDrawAssertMessageFormat);
    testStep->draw(&proxyCanvas, reporter);
    // Verify that the SkProxyCanvas reports consitent state
    testStep->setAssertMessageFormat(kProxyStateAssertMessageFormat);
    AssertCanvasStatesEqual(reporter, &proxyCanvas, &referenceCanvas,
        testStep);
    // Verify that the indirect canvas reports consitent state
    testStep->setAssertMessageFormat(kProxyIndirectStateAssertMessageFormat);
    AssertCanvasStatesEqual(reporter, &indirectCanvas, &referenceCanvas,
        testStep);
}

// unused
static void TestNWayCanvasStateConsistency(
    skiatest::Reporter* reporter,
    CanvasTestStep* testStep,
    const SkCanvas& referenceCanvas) {

    SkBitmap indirectStore1;
    createBitmap(&indirectStore1, 0xFFFFFFFF);
    SkCanvas indirectCanvas1(indirectStore1);

    SkBitmap indirectStore2;
    createBitmap(&indirectStore2, 0xFFFFFFFF);
    SkCanvas indirectCanvas2(indirectStore2);

    SkISize canvasSize = referenceCanvas.getDeviceSize();
    SkNWayCanvas nWayCanvas(canvasSize.width(), canvasSize.height());
    nWayCanvas.addCanvas(&indirectCanvas1);
    nWayCanvas.addCanvas(&indirectCanvas2);

    testStep->setAssertMessageFormat(kNWayDrawAssertMessageFormat);
    testStep->draw(&nWayCanvas, reporter);
    // Verify that the SkProxyCanvas reports consitent state
    testStep->setAssertMessageFormat(kNWayStateAssertMessageFormat);
    AssertCanvasStatesEqual(reporter, &nWayCanvas, &referenceCanvas,
        testStep);
    // Verify that the indirect canvases report consitent state
    testStep->setAssertMessageFormat(kNWayIndirect1StateAssertMessageFormat);
    AssertCanvasStatesEqual(reporter, &indirectCanvas1, &referenceCanvas,
        testStep);
    testStep->setAssertMessageFormat(kNWayIndirect2StateAssertMessageFormat);
    AssertCanvasStatesEqual(reporter, &indirectCanvas2, &referenceCanvas,
        testStep);
}

/*
 * This sub-test verifies that the test step passes when executed
 * with SkCanvas and with classes derrived from SkCanvas. It also verifies
 * that the all canvas derivatives report the same state as an SkCanvas
 * after having executed the test step.
 */
static void TestOverrideStateConsistency(skiatest::Reporter* reporter,
                                         CanvasTestStep* testStep) {
    SkBitmap referenceStore;
    createBitmap(&referenceStore, 0xFFFFFFFF);
    SkCanvas referenceCanvas(referenceStore);
    testStep->setAssertMessageFormat(kCanvasDrawAssertMessageFormat);
    testStep->draw(&referenceCanvas, reporter);

    SkDeferredCanvasTester::TestDeferredCanvasStateConsistency(reporter, testStep, referenceCanvas, false);

    SkDeferredCanvasTester::TestDeferredCanvasStateConsistency(reporter, testStep, referenceCanvas, true);

    // The following test code is disabled because SkProxyCanvas is
    // missing a lot of virtual overrides on get* methods, which are used
    // to verify canvas state.
    // Issue: http://code.google.com/p/skia/issues/detail?id=500

    if (false) { // avoid bit rot, suppress warning
        TestProxyCanvasStateConsistency(reporter, testStep, referenceCanvas);
    }

    // The following test code is disabled because SkNWayCanvas does not
    // report correct clipping and device bounds information
    // Issue: http://code.google.com/p/skia/issues/detail?id=501

    if (false) { // avoid bit rot, suppress warning
        TestNWayCanvasStateConsistency(reporter, testStep, referenceCanvas);
    }

    if (false) { // avoid bit rot, suppress warning
        test_clipVisitor(reporter, &referenceCanvas);
    }
}

static void test_newraster(skiatest::Reporter* reporter) {
    SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
    SkCanvas* canvas = SkCanvas::NewRaster(info);
    REPORTER_ASSERT(reporter, canvas);

    SkImageInfo info2;
    size_t rowBytes;
    const SkPMColor* addr = (const SkPMColor*)canvas->peekPixels(&info2, &rowBytes);
    REPORTER_ASSERT(reporter, addr);
    REPORTER_ASSERT(reporter, info == info2);
    for (int y = 0; y < info.height(); ++y) {
        for (int x = 0; x < info.width(); ++x) {
            REPORTER_ASSERT(reporter, 0 == addr[x]);
        }
        addr = (const SkPMColor*)((const char*)addr + rowBytes);
    }
    SkDELETE(canvas);

    // now try a deliberately bad info
    info = info.makeWH(-1, info.height());
    REPORTER_ASSERT(reporter, NULL == SkCanvas::NewRaster(info));

    // too big
    info = info.makeWH(1 << 30, 1 << 30);
    REPORTER_ASSERT(reporter, NULL == SkCanvas::NewRaster(info));

    // not a valid pixel type
    info = SkImageInfo::Make(10, 10, kUnknown_SkColorType, info.alphaType());
    REPORTER_ASSERT(reporter, NULL == SkCanvas::NewRaster(info));

    // We should succeed with a zero-sized valid info
    info = SkImageInfo::MakeN32Premul(0, 0);
    canvas = SkCanvas::NewRaster(info);
    REPORTER_ASSERT(reporter, canvas);
    SkDELETE(canvas);
}

DEF_TEST(Canvas, reporter) {
    // Init global here because bitmap pixels cannot be alocated during
    // static initialization
    kTestBitmap = testBitmap();

    for (int testStep = 0; testStep < testStepArray().count(); testStep++) {
        TestOverrideStateConsistency(reporter, testStepArray()[testStep]);
        SkPictureTester::TestPictureFlattenedObjectReuse(reporter,
            testStepArray()[testStep], 0);
        if (testStepArray()[testStep]->enablePdfTesting()) {
            TestPdfDevice(reporter, testStepArray()[testStep]);
        }
    }

    // Explicitly call reset(), so we don't leak the pixels (since kTestBitmap is a global)
    kTestBitmap.reset();

    test_newraster(reporter);
}
