Home | History | Annotate | Download | only in tests
      1 
      2 /*
      3  * Copyright 2012 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 /*  Description:
     10  *      This test defines a series of elementatry test steps that perform
     11  *      a single or a small group of canvas API calls. Each test step is
     12  *      used in several test cases that verify that different types of SkCanvas
     13  *      flavors and derivatives pass it and yield consistent behavior. The
     14  *      test cases analyse results that are queryable through the API. They do
     15  *      not look at rendering results.
     16  *
     17  *  Adding test stepss:
     18  *      The general pattern for creating a new test step is to write a test
     19  *      function of the form:
     20  *
     21  *          static void MyTestStepFunction(SkCanvas* canvas,
     22  *                                         skiatest::Reporter* reporter,
     23  *                                         CanvasTestStep* testStep)
     24  *          {
     25  *              canvas->someCanvasAPImethod();
     26  *              (...)
     27  *              REPORTER_ASSERT_MESSAGE(reporter, (...), \
     28  *                  testStep->assertMessage());
     29  *          }
     30  *
     31  *      The definition of the test step function should be followed by an
     32  *      invocation of the TEST_STEP macro, which generates a class and
     33  *      instance for the test step:
     34  *
     35  *          TEST_STEP(MyTestStep, MyTestStepFunction)
     36  *
     37  *      There are also short hand macros for defining simple test steps
     38  *      in a single line of code.  A simple test step is a one that is made
     39  *      of a single canvas API call.
     40  *
     41  *          SIMPLE_TEST_STEP(MytestStep, someCanvasAPIMethod());
     42  *
     43  *      There is another macro called SIMPLE_TEST_STEP_WITH_ASSERT that
     44  *      works the same way as SIMPLE_TEST_STEP, and additionally verifies
     45  *      that the invoked method returns a non-zero value.
     46  */
     47 #include "SkBitmap.h"
     48 #include "SkCanvas.h"
     49 #include "SkDeferredCanvas.h"
     50 #include "SkDevice.h"
     51 #include "SkMatrix.h"
     52 #include "SkNWayCanvas.h"
     53 #include "SkPDFDevice.h"
     54 #include "SkPDFDocument.h"
     55 #include "SkPaint.h"
     56 #include "SkPath.h"
     57 #include "SkPicture.h"
     58 #include "SkPictureRecord.h"
     59 #include "SkProxyCanvas.h"
     60 #include "SkRect.h"
     61 #include "SkRegion.h"
     62 #include "SkShader.h"
     63 #include "SkStream.h"
     64 #include "SkTDArray.h"
     65 #include "Test.h"
     66 
     67 class Canvas2CanvasClipVisitor : public SkCanvas::ClipVisitor {
     68 public:
     69     Canvas2CanvasClipVisitor(SkCanvas* target) : fTarget(target) {}
     70 
     71     virtual void clipRect(const SkRect& r, SkRegion::Op op, bool aa) {
     72         fTarget->clipRect(r, op, aa);
     73     }
     74     virtual void clipPath(const SkPath& p, SkRegion::Op op, bool aa) {
     75         fTarget->clipPath(p, op, aa);
     76     }
     77 
     78 private:
     79     SkCanvas* fTarget;
     80 };
     81 
     82 static void test_clipVisitor(skiatest::Reporter* reporter, SkCanvas* canvas) {
     83     SkISize size = canvas->getDeviceSize();
     84 
     85     SkBitmap bm;
     86     bm.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height());
     87     SkCanvas c(bm);
     88 
     89     Canvas2CanvasClipVisitor visitor(&c);
     90     canvas->replayClips(&visitor);
     91 
     92     REPORTER_ASSERT(reporter, c.getTotalClip() == canvas->getTotalClip());
     93 }
     94 
     95 static const int kWidth = 2;
     96 static const int kHeight = 2;
     97 // Maximum stream length for picture serialization
     98 static const size_t kMaxPictureBufferSize = 1024;
     99 
    100 // Format strings that describe the test context.  The %s token is where
    101 // the name of the test step is inserted.  The context is required for
    102 // disambiguating the error in the case of failures that are reported in
    103 // functions that are called multiple times in different contexts (test
    104 // cases and test steps).
    105 static const char* const kDefaultAssertMessageFormat = "%s";
    106 static const char* const kCanvasDrawAssertMessageFormat =
    107     "Drawing test step %s with SkCanvas";
    108 static const char* const kPictureDrawAssertMessageFormat =
    109     "Drawing test step %s with SkPicture";
    110 static const char* const kPictureSecondDrawAssertMessageFormat =
    111     "Duplicate draw of test step %s with SkPicture";
    112 static const char* const kPictureReDrawAssertMessageFormat =
    113     "Playing back test step %s from an SkPicture to another SkPicture";
    114 static const char* const kDeferredDrawAssertMessageFormat =
    115     "Drawing test step %s with SkDeferredCanvas";
    116 static const char* const kProxyDrawAssertMessageFormat =
    117     "Drawing test step %s with SkProxyCanvas";
    118 static const char* const kNWayDrawAssertMessageFormat =
    119     "Drawing test step %s with SkNWayCanvas";
    120 static const char* const kRoundTripAssertMessageFormat =
    121     "test step %s, SkPicture consistency after round trip";
    122 static const char* const kPictureRecoringAssertMessageFormat =
    123     "test step %s, SkPicture state consistency after recording";
    124 static const char* const kPicturePlaybackAssertMessageFormat =
    125     "test step %s, SkPicture state consistency in playback canvas";
    126 static const char* const kDeferredPreFlushAssertMessageFormat =
    127     "test step %s, SkDeferredCanvas state consistency before flush";
    128 static const char* const kDeferredPostFlushPlaybackAssertMessageFormat =
    129     "test step %s, SkDeferredCanvas playback canvas state consistency after flush";
    130 static const char* const kDeferredPostSilentFlushPlaybackAssertMessageFormat =
    131     "test step %s, SkDeferredCanvas playback canvas state consistency after silent flush";
    132 static const char* const kDeferredPostFlushAssertMessageFormat =
    133     "test step %s, SkDeferredCanvas state consistency after flush";
    134 static const char* const kPictureResourceReuseMessageFormat =
    135     "test step %s, SkPicture duplicate flattened object test";
    136 static const char* const kProxyStateAssertMessageFormat =
    137     "test step %s, SkProxyCanvas state consistency";
    138 static const char* const kProxyIndirectStateAssertMessageFormat =
    139     "test step %s, SkProxyCanvas indirect canvas state consistency";
    140 static const char* const kNWayStateAssertMessageFormat =
    141     "test step %s, SkNWayCanvas state consistency";
    142 static const char* const kNWayIndirect1StateAssertMessageFormat =
    143     "test step %s, SkNWayCanvas indirect canvas 1 state consistency";
    144 static const char* const kNWayIndirect2StateAssertMessageFormat =
    145     "test step %s, SkNWayCanvas indirect canvas 2 state consistency";
    146 static const char* const kPdfAssertMessageFormat =
    147     "PDF sanity check failed %s";
    148 
    149 static void createBitmap(SkBitmap* bm, SkBitmap::Config config, SkColor color) {
    150     bm->setConfig(config, kWidth, kHeight);
    151     bm->allocPixels();
    152     bm->eraseColor(color);
    153 }
    154 
    155 class CanvasTestStep;
    156 static SkTDArray<CanvasTestStep*>& testStepArray() {
    157     static SkTDArray<CanvasTestStep*> theTests;
    158     return theTests;
    159 }
    160 
    161 class CanvasTestStep {
    162 public:
    163     CanvasTestStep(bool fEnablePdfTesting = true) {
    164         *testStepArray().append() = this;
    165         fAssertMessageFormat = kDefaultAssertMessageFormat;
    166         this->fEnablePdfTesting = fEnablePdfTesting;
    167     }
    168     virtual ~CanvasTestStep() { }
    169 
    170     virtual void draw(SkCanvas*, skiatest::Reporter*) = 0;
    171     virtual const char* name() const = 0;
    172 
    173     const char* assertMessage() {
    174         fAssertMessage.printf(fAssertMessageFormat, name());
    175         return fAssertMessage.c_str();
    176     }
    177 
    178     void setAssertMessageFormat(const char* format) {
    179         fAssertMessageFormat = format;
    180     }
    181 
    182     bool enablePdfTesting() { return fEnablePdfTesting; }
    183 
    184 private:
    185     SkString fAssertMessage;
    186     const char* fAssertMessageFormat;
    187     bool fEnablePdfTesting;
    188 };
    189 
    190 ///////////////////////////////////////////////////////////////////////////////
    191 // Constants used by test steps
    192 
    193 const SkRect kTestRect =
    194     SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
    195                      SkIntToScalar(2), SkIntToScalar(1));
    196 static SkMatrix testMatrix() {
    197     SkMatrix matrix;
    198     matrix.reset();
    199     matrix.setScale(SkIntToScalar(2), SkIntToScalar(3));
    200     return matrix;
    201 }
    202 const SkMatrix kTestMatrix = testMatrix();
    203 static SkPath testPath() {
    204     SkPath path;
    205     path.addRect(SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
    206                                   SkIntToScalar(2), SkIntToScalar(1)));
    207     return path;
    208 }
    209 const SkPath kTestPath = testPath();
    210 static SkRegion testRegion() {
    211     SkRegion region;
    212     SkIRect rect = SkIRect::MakeXYWH(0, 0, 2, 1);
    213     region.setRect(rect);
    214     return region;
    215 }
    216 const SkIRect kTestIRect = SkIRect::MakeXYWH(0, 0, 2, 1);
    217 const SkRegion kTestRegion = testRegion();
    218 const SkColor kTestColor = 0x01020304;
    219 const SkPaint kTestPaint;
    220 const SkPoint kTestPoints[3] = {
    221     {SkIntToScalar(0), SkIntToScalar(0)},
    222     {SkIntToScalar(2), SkIntToScalar(1)},
    223     {SkIntToScalar(0), SkIntToScalar(2)}
    224 };
    225 const size_t kTestPointCount = 3;
    226 static SkBitmap testBitmap() {
    227     SkBitmap bitmap;
    228     createBitmap(&bitmap, SkBitmap::kARGB_8888_Config, 0x05060708);
    229     return bitmap;
    230 }
    231 SkBitmap kTestBitmap; // cannot be created during static init
    232 SkString kTestText("Hello World");
    233 SkPoint kTestPoints2[] = {
    234   { SkIntToScalar(0), SkIntToScalar(1) },
    235   { SkIntToScalar(1), SkIntToScalar(1) },
    236   { SkIntToScalar(2), SkIntToScalar(1) },
    237   { SkIntToScalar(3), SkIntToScalar(1) },
    238   { SkIntToScalar(4), SkIntToScalar(1) },
    239   { SkIntToScalar(5), SkIntToScalar(1) },
    240   { SkIntToScalar(6), SkIntToScalar(1) },
    241   { SkIntToScalar(7), SkIntToScalar(1) },
    242   { SkIntToScalar(8), SkIntToScalar(1) },
    243   { SkIntToScalar(9), SkIntToScalar(1) },
    244   { SkIntToScalar(10), SkIntToScalar(1) },
    245 };
    246 
    247 
    248 ///////////////////////////////////////////////////////////////////////////////
    249 // Macros for defining test steps
    250 
    251 #define TEST_STEP(NAME, FUNCTION)                                       \
    252 class NAME##_TestStep : public CanvasTestStep{                          \
    253 public:                                                                 \
    254     virtual void draw(SkCanvas* canvas, skiatest::Reporter* reporter) { \
    255         FUNCTION (canvas, reporter, this);                              \
    256     }                                                                   \
    257     virtual const char* name() const {return #NAME ;}                   \
    258 };                                                                      \
    259 static NAME##_TestStep NAME##_TestStepInstance;
    260 
    261 #define TEST_STEP_NO_PDF(NAME, FUNCTION)                                       \
    262 class NAME##_TestStep : public CanvasTestStep{                          \
    263 public:                                                                 \
    264     NAME##_TestStep() : CanvasTestStep(false) {}                        \
    265     virtual void draw(SkCanvas* canvas, skiatest::Reporter* reporter) { \
    266         FUNCTION (canvas, reporter, this);                              \
    267     }                                                                   \
    268     virtual const char* name() const {return #NAME ;}                   \
    269 };                                                                      \
    270 static NAME##_TestStep NAME##_TestStepInstance;
    271 
    272 #define SIMPLE_TEST_STEP(NAME, CALL)                              \
    273 static void NAME##TestStep(SkCanvas* canvas, skiatest::Reporter*, \
    274     CanvasTestStep*) {                                            \
    275     canvas-> CALL ;                                               \
    276 }                                                                 \
    277 TEST_STEP(NAME, NAME##TestStep )
    278 
    279 #define SIMPLE_TEST_STEP_WITH_ASSERT(NAME, CALL)                           \
    280 static void NAME##TestStep(SkCanvas* canvas, skiatest::Reporter* reporter, \
    281     CanvasTestStep* testStep) {                                            \
    282     REPORTER_ASSERT_MESSAGE(reporter, canvas-> CALL ,                      \
    283         testStep->assertMessage());                                        \
    284 }                                                                          \
    285 TEST_STEP(NAME, NAME##TestStep )
    286 
    287 
    288 ///////////////////////////////////////////////////////////////////////////////
    289 // Basic test steps for most virtual methods in SkCanvas that draw or affect
    290 // the state of the canvas.
    291 
    292 SIMPLE_TEST_STEP_WITH_ASSERT(Translate,
    293     translate(SkIntToScalar(1), SkIntToScalar(2)));
    294 SIMPLE_TEST_STEP_WITH_ASSERT(Scale,
    295     scale(SkIntToScalar(1), SkIntToScalar(2)));
    296 SIMPLE_TEST_STEP_WITH_ASSERT(Rotate, rotate(SkIntToScalar(1)));
    297 SIMPLE_TEST_STEP_WITH_ASSERT(Skew,
    298     skew(SkIntToScalar(1), SkIntToScalar(2)));
    299 SIMPLE_TEST_STEP_WITH_ASSERT(Concat, concat(kTestMatrix));
    300 SIMPLE_TEST_STEP(SetMatrix, setMatrix(kTestMatrix));
    301 SIMPLE_TEST_STEP(ClipRect, clipRect(kTestRect));
    302 SIMPLE_TEST_STEP(ClipPath, clipPath(kTestPath));
    303 SIMPLE_TEST_STEP(ClipRegion,
    304     clipRegion(kTestRegion, SkRegion::kReplace_Op));
    305 SIMPLE_TEST_STEP(Clear, clear(kTestColor));
    306 SIMPLE_TEST_STEP(DrawPaint, drawPaint(kTestPaint));
    307 SIMPLE_TEST_STEP(DrawPointsPoints, drawPoints(SkCanvas::kPoints_PointMode,
    308     kTestPointCount, kTestPoints, kTestPaint));
    309 SIMPLE_TEST_STEP(DrawPointsLiness, drawPoints(SkCanvas::kLines_PointMode,
    310     kTestPointCount, kTestPoints, kTestPaint));
    311 SIMPLE_TEST_STEP(DrawPointsPolygon, drawPoints(SkCanvas::kPolygon_PointMode,
    312     kTestPointCount, kTestPoints, kTestPaint));
    313 SIMPLE_TEST_STEP(DrawRect, drawRect(kTestRect, kTestPaint));
    314 SIMPLE_TEST_STEP(DrawPath, drawPath(kTestPath, kTestPaint));
    315 SIMPLE_TEST_STEP(DrawBitmap, drawBitmap(kTestBitmap, 0, 0));
    316 SIMPLE_TEST_STEP(DrawBitmapPaint, drawBitmap(kTestBitmap, 0, 0, &kTestPaint));
    317 SIMPLE_TEST_STEP(DrawBitmapRect, drawBitmapRect(kTestBitmap, NULL, kTestRect,
    318     NULL));
    319 SIMPLE_TEST_STEP(DrawBitmapRectSrcRect, drawBitmapRect(kTestBitmap,
    320     &kTestIRect, kTestRect, NULL));
    321 SIMPLE_TEST_STEP(DrawBitmapRectPaint, drawBitmapRect(kTestBitmap, NULL,
    322     kTestRect, &kTestPaint));
    323 SIMPLE_TEST_STEP(DrawBitmapMatrix, drawBitmapMatrix(kTestBitmap, kTestMatrix,
    324     NULL));
    325 SIMPLE_TEST_STEP(DrawBitmapMatrixPaint, drawBitmapMatrix(kTestBitmap,
    326     kTestMatrix, &kTestPaint));
    327 SIMPLE_TEST_STEP(DrawBitmapNine, drawBitmapNine(kTestBitmap, kTestIRect,
    328     kTestRect, NULL));
    329 SIMPLE_TEST_STEP(DrawBitmapNinePaint, drawBitmapNine(kTestBitmap, kTestIRect,
    330     kTestRect, &kTestPaint));
    331 SIMPLE_TEST_STEP(DrawSprite, drawSprite(kTestBitmap, 0, 0, NULL));
    332 SIMPLE_TEST_STEP(DrawSpritePaint, drawSprite(kTestBitmap, 0, 0, &kTestPaint));
    333 SIMPLE_TEST_STEP(DrawText, drawText(kTestText.c_str(), kTestText.size(),
    334     0, 1, kTestPaint));
    335 SIMPLE_TEST_STEP(DrawPosText, drawPosText(kTestText.c_str(),
    336     kTestText.size(), kTestPoints2, kTestPaint));
    337 SIMPLE_TEST_STEP(DrawTextOnPath, drawTextOnPath(kTestText.c_str(),
    338     kTestText.size(), kTestPath, NULL, kTestPaint));
    339 SIMPLE_TEST_STEP(DrawTextOnPathMatrix, drawTextOnPath(kTestText.c_str(),
    340     kTestText.size(), kTestPath, &kTestMatrix, kTestPaint));
    341 SIMPLE_TEST_STEP(DrawData, drawData(kTestText.c_str(), kTestText.size()));
    342 SIMPLE_TEST_STEP(BeginGroup, beginCommentGroup(kTestText.c_str()));
    343 SIMPLE_TEST_STEP(AddComment, addComment(kTestText.c_str(), kTestText.c_str()));
    344 SIMPLE_TEST_STEP(EndGroup, endCommentGroup());
    345 
    346 ///////////////////////////////////////////////////////////////////////////////
    347 // Complex test steps
    348 
    349 // Save/restore calls cannot be in isolated simple test steps because the test
    350 // cases that use SkPicture require that save and restore calls be balanced.
    351 static void SaveMatrixStep(SkCanvas* canvas,
    352                            skiatest::Reporter* reporter,
    353                            CanvasTestStep* testStep) {
    354     int saveCount = canvas->getSaveCount();
    355     canvas->save(SkCanvas::kMatrix_SaveFlag);
    356     canvas->clipRegion(kTestRegion);
    357     canvas->translate(SkIntToScalar(1), SkIntToScalar(2));
    358     canvas->restore();
    359     REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
    360         testStep->assertMessage());
    361     REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalMatrix().isIdentity(),
    362         testStep->assertMessage());
    363     REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalClip() == kTestRegion,
    364         testStep->assertMessage());
    365 }
    366 TEST_STEP(SaveMatrix, SaveMatrixStep);
    367 
    368 static void SaveClipStep(SkCanvas* canvas,
    369                          skiatest::Reporter* reporter,
    370                          CanvasTestStep* testStep) {
    371     int saveCount = canvas->getSaveCount();
    372     canvas->save(SkCanvas::kClip_SaveFlag);
    373     canvas->translate(SkIntToScalar(1), SkIntToScalar(2));
    374     canvas->clipRegion(kTestRegion);
    375     canvas->restore();
    376     REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
    377         testStep->assertMessage());
    378     REPORTER_ASSERT_MESSAGE(reporter, !canvas->getTotalMatrix().isIdentity(),
    379         testStep->assertMessage());
    380     REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalClip() != kTestRegion,
    381         testStep->assertMessage());
    382 }
    383 TEST_STEP(SaveClip, SaveClipStep);
    384 
    385 static void SaveMatrixClipStep(SkCanvas* canvas,
    386                                skiatest::Reporter* reporter,
    387                                CanvasTestStep* testStep) {
    388     int saveCount = canvas->getSaveCount();
    389     canvas->save(SkCanvas::kMatrixClip_SaveFlag);
    390     canvas->translate(SkIntToScalar(1), SkIntToScalar(2));
    391     canvas->clipRegion(kTestRegion);
    392     canvas->restore();
    393     REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
    394         testStep->assertMessage());
    395     REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalMatrix().isIdentity(),
    396         testStep->assertMessage());
    397     REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalClip() != kTestRegion,
    398         testStep->assertMessage());
    399 }
    400 TEST_STEP(SaveMatrixClip, SaveMatrixClipStep);
    401 
    402 static void SaveLayerStep(SkCanvas* canvas,
    403                           skiatest::Reporter* reporter,
    404                           CanvasTestStep* testStep) {
    405     int saveCount = canvas->getSaveCount();
    406     canvas->saveLayer(NULL, NULL);
    407     canvas->restore();
    408     REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
    409         testStep->assertMessage());
    410 }
    411 TEST_STEP(SaveLayer, SaveLayerStep);
    412 
    413 static void BoundedSaveLayerStep(SkCanvas* canvas,
    414                           skiatest::Reporter* reporter,
    415                           CanvasTestStep* testStep) {
    416     int saveCount = canvas->getSaveCount();
    417     canvas->saveLayer(&kTestRect, NULL);
    418     canvas->restore();
    419     REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
    420         testStep->assertMessage());
    421 }
    422 TEST_STEP(BoundedSaveLayer, BoundedSaveLayerStep);
    423 
    424 static void PaintSaveLayerStep(SkCanvas* canvas,
    425                           skiatest::Reporter* reporter,
    426                           CanvasTestStep* testStep) {
    427     int saveCount = canvas->getSaveCount();
    428     canvas->saveLayer(NULL, &kTestPaint);
    429     canvas->restore();
    430     REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
    431         testStep->assertMessage());
    432 }
    433 TEST_STEP(PaintSaveLayer, PaintSaveLayerStep);
    434 
    435 static void TwoClipOpsStep(SkCanvas* canvas,
    436                            skiatest::Reporter*,
    437                            CanvasTestStep*) {
    438     // This test exercises a functionality in SkPicture that leads to the
    439     // recording of restore offset placeholders.  This test will trigger an
    440     // assertion at playback time if the placeholders are not properly
    441     // filled when the recording ends.
    442     canvas->clipRect(kTestRect);
    443     canvas->clipRegion(kTestRegion);
    444 }
    445 TEST_STEP(TwoClipOps, TwoClipOpsStep);
    446 
    447 // exercise fix for http://code.google.com/p/skia/issues/detail?id=560
    448 // ('SkPathStroker::lineTo() fails for line with length SK_ScalarNearlyZero')
    449 static void DrawNearlyZeroLengthPathTestStep(SkCanvas* canvas,
    450                                              skiatest::Reporter*,
    451                                              CanvasTestStep*) {
    452     SkPaint paint;
    453     paint.setStrokeWidth(SkIntToScalar(1));
    454     paint.setStyle(SkPaint::kStroke_Style);
    455 
    456     SkPath path;
    457     SkPoint pt1 = { 0, 0 };
    458     SkPoint pt2 = { 0, SK_ScalarNearlyZero };
    459     SkPoint pt3 = { SkIntToScalar(1), 0 };
    460     SkPoint pt4 = { SkIntToScalar(1), SK_ScalarNearlyZero/2 };
    461     path.moveTo(pt1);
    462     path.lineTo(pt2);
    463     path.lineTo(pt3);
    464     path.lineTo(pt4);
    465 
    466     canvas->drawPath(path, paint);
    467 }
    468 TEST_STEP(DrawNearlyZeroLengthPath, DrawNearlyZeroLengthPathTestStep);
    469 
    470 static void DrawVerticesShaderTestStep(SkCanvas* canvas,
    471                                        skiatest::Reporter*,
    472                                        CanvasTestStep*) {
    473     SkPoint pts[4];
    474     pts[0].set(0, 0);
    475     pts[1].set(SkIntToScalar(kWidth), 0);
    476     pts[2].set(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
    477     pts[3].set(0, SkIntToScalar(kHeight));
    478     SkPaint paint;
    479     SkShader* shader = SkShader::CreateBitmapShader(kTestBitmap,
    480         SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
    481     paint.setShader(shader)->unref();
    482     canvas->drawVertices(SkCanvas::kTriangleFan_VertexMode, 4, pts, pts,
    483                          NULL, NULL, NULL, 0, paint);
    484 }
    485 // NYI: issue 240.
    486 TEST_STEP_NO_PDF(DrawVerticesShader, DrawVerticesShaderTestStep);
    487 
    488 static void DrawPictureTestStep(SkCanvas* canvas,
    489                                 skiatest::Reporter*,
    490                                 CanvasTestStep*) {
    491     SkPicture* testPicture = SkNEW_ARGS(SkPicture, ());
    492     SkAutoUnref aup(testPicture);
    493     SkCanvas* testCanvas = testPicture->beginRecording(kWidth, kHeight);
    494     testCanvas->scale(SkIntToScalar(2), SkIntToScalar(1));
    495     testCanvas->clipRect(kTestRect);
    496     testCanvas->drawRect(kTestRect, kTestPaint);
    497     canvas->drawPicture(*testPicture);
    498 }
    499 TEST_STEP(DrawPicture, DrawPictureTestStep);
    500 
    501 static void SaveRestoreTestStep(SkCanvas* canvas,
    502                                 skiatest::Reporter* reporter,
    503                                 CanvasTestStep* testStep) {
    504     int baseSaveCount = canvas->getSaveCount();
    505     int n = canvas->save();
    506     REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount == n, testStep->assertMessage());
    507     REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount + 1 == canvas->getSaveCount(),
    508         testStep->assertMessage());
    509     canvas->save();
    510     canvas->save();
    511     REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount + 3 == canvas->getSaveCount(),
    512         testStep->assertMessage());
    513     canvas->restoreToCount(baseSaveCount + 1);
    514     REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount + 1 == canvas->getSaveCount(),
    515         testStep->assertMessage());
    516 
    517     // should this pin to 1, or be a no-op, or crash?
    518     canvas->restoreToCount(0);
    519     REPORTER_ASSERT_MESSAGE(reporter, 1 == canvas->getSaveCount(),
    520         testStep->assertMessage());
    521 }
    522 TEST_STEP(SaveRestore, SaveRestoreTestStep);
    523 
    524 static void DrawLayerTestStep(SkCanvas* canvas,
    525                               skiatest::Reporter* reporter,
    526                               CanvasTestStep* testStep) {
    527     REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
    528         testStep->assertMessage());
    529     canvas->save();
    530     REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
    531         testStep->assertMessage());
    532     canvas->restore();
    533 
    534     const SkRect* bounds = NULL;    // null means include entire bounds
    535     const SkPaint* paint = NULL;
    536 
    537     canvas->saveLayer(bounds, paint);
    538     REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(),
    539         testStep->assertMessage());
    540     canvas->restore();
    541     REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
    542         testStep->assertMessage());
    543 
    544     canvas->saveLayer(bounds, paint);
    545     canvas->saveLayer(bounds, paint);
    546     REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(),
    547         testStep->assertMessage());
    548     canvas->restore();
    549     REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(),
    550         testStep->assertMessage());
    551     canvas->restore();
    552     // now layer count should be 0
    553     REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
    554         testStep->assertMessage());
    555 }
    556 TEST_STEP(DrawLayer, DrawLayerTestStep);
    557 
    558 static void NestedSaveRestoreWithSolidPaintTestStep(SkCanvas* canvas,
    559                                       skiatest::Reporter*,
    560                                       CanvasTestStep*) {
    561     // This test step challenges the TestDeferredCanvasStateConsistency
    562     // test cases because the opaque paint can trigger an optimization
    563     // that discards previously recorded commands. The challenge is to maintain
    564     // correct clip and matrix stack state.
    565     canvas->resetMatrix();
    566     canvas->rotate(SkIntToScalar(30));
    567     canvas->save();
    568     canvas->translate(SkIntToScalar(2), SkIntToScalar(1));
    569     canvas->save();
    570     canvas->scale(SkIntToScalar(3), SkIntToScalar(3));
    571     SkPaint paint;
    572     paint.setColor(0xFFFFFFFF);
    573     canvas->drawPaint(paint);
    574     canvas->restore();
    575     canvas->restore();
    576 }
    577 TEST_STEP(NestedSaveRestoreWithSolidPaint, \
    578     NestedSaveRestoreWithSolidPaintTestStep);
    579 
    580 static void NestedSaveRestoreWithFlushTestStep(SkCanvas* canvas,
    581                                       skiatest::Reporter*,
    582                                       CanvasTestStep*) {
    583     // This test step challenges the TestDeferredCanvasStateConsistency
    584     // test case because the canvas flush on a deferred canvas will
    585     // reset the recording session. The challenge is to maintain correct
    586     // clip and matrix stack state on the playback canvas.
    587     canvas->resetMatrix();
    588     canvas->rotate(SkIntToScalar(30));
    589     canvas->save();
    590     canvas->translate(SkIntToScalar(2), SkIntToScalar(1));
    591     canvas->save();
    592     canvas->scale(SkIntToScalar(3), SkIntToScalar(3));
    593     canvas->drawRect(kTestRect,kTestPaint);
    594     canvas->flush();
    595     canvas->restore();
    596     canvas->restore();
    597 }
    598 TEST_STEP(NestedSaveRestoreWithFlush, \
    599     NestedSaveRestoreWithFlushTestStep);
    600 
    601 static void AssertCanvasStatesEqual(skiatest::Reporter* reporter,
    602                                     const SkCanvas* canvas1,
    603                                     const SkCanvas* canvas2,
    604                                     CanvasTestStep* testStep) {
    605     REPORTER_ASSERT_MESSAGE(reporter, canvas1->getDeviceSize() ==
    606         canvas2->getDeviceSize(), testStep->assertMessage());
    607     REPORTER_ASSERT_MESSAGE(reporter, canvas1->getSaveCount() ==
    608         canvas2->getSaveCount(), testStep->assertMessage());
    609     REPORTER_ASSERT_MESSAGE(reporter, canvas1->isDrawingToLayer() ==
    610         canvas2->isDrawingToLayer(), testStep->assertMessage());
    611 
    612     SkRect bounds1, bounds2;
    613     REPORTER_ASSERT_MESSAGE(reporter,
    614         canvas1->getClipBounds(&bounds1) == canvas2->getClipBounds(&bounds2),
    615         testStep->assertMessage());
    616     REPORTER_ASSERT_MESSAGE(reporter, bounds1 == bounds2,
    617                             testStep->assertMessage());
    618 
    619     REPORTER_ASSERT_MESSAGE(reporter, canvas1->getDrawFilter() ==
    620         canvas2->getDrawFilter(), testStep->assertMessage());
    621     SkIRect deviceBounds1, deviceBounds2;
    622     REPORTER_ASSERT_MESSAGE(reporter,
    623         canvas1->getClipDeviceBounds(&deviceBounds1) ==
    624         canvas2->getClipDeviceBounds(&deviceBounds2),
    625         testStep->assertMessage());
    626     REPORTER_ASSERT_MESSAGE(reporter, deviceBounds1 == deviceBounds2,
    627         testStep->assertMessage());
    628     REPORTER_ASSERT_MESSAGE(reporter, canvas1->getBounder() ==
    629         canvas2->getBounder(), testStep->assertMessage());
    630     REPORTER_ASSERT_MESSAGE(reporter, canvas1->getTotalMatrix() ==
    631         canvas2->getTotalMatrix(), testStep->assertMessage());
    632     REPORTER_ASSERT_MESSAGE(reporter, canvas1->getClipType() ==
    633         canvas2->getClipType(), testStep->assertMessage());
    634     REPORTER_ASSERT_MESSAGE(reporter, canvas1->getTotalClip() ==
    635         canvas2->getTotalClip(), testStep->assertMessage());
    636 
    637     // The following test code is commented out because the test fails when
    638     // the canvas is an SkPictureRecord or SkDeferredCanvas
    639     // Issue: http://code.google.com/p/skia/issues/detail?id=498
    640     // Also, creating a LayerIter on an SkProxyCanvas crashes
    641     // Issue: http://code.google.com/p/skia/issues/detail?id=499
    642     /*
    643     SkCanvas::LayerIter layerIter1(const_cast<SkCanvas*>(canvas1), false);
    644     SkCanvas::LayerIter layerIter2(const_cast<SkCanvas*>(canvas2), false);
    645     while (!layerIter1.done() && !layerIter2.done()) {
    646         REPORTER_ASSERT_MESSAGE(reporter, layerIter1.matrix() ==
    647             layerIter2.matrix(), testStep->assertMessage());
    648         REPORTER_ASSERT_MESSAGE(reporter, layerIter1.clip() ==
    649             layerIter2.clip(), testStep->assertMessage());
    650         REPORTER_ASSERT_MESSAGE(reporter, layerIter1.paint() ==
    651             layerIter2.paint(), testStep->assertMessage());
    652         REPORTER_ASSERT_MESSAGE(reporter, layerIter1.x() ==
    653             layerIter2.x(), testStep->assertMessage());
    654         REPORTER_ASSERT_MESSAGE(reporter, layerIter1.y() ==
    655             layerIter2.y(), testStep->assertMessage());
    656         layerIter1.next();
    657         layerIter2.next();
    658     }
    659     REPORTER_ASSERT_MESSAGE(reporter, layerIter1.done(),
    660         testStep->assertMessage());
    661     REPORTER_ASSERT_MESSAGE(reporter, layerIter2.done(),
    662         testStep->assertMessage());
    663     */
    664 }
    665 
    666 // The following class groups static functions that need to access
    667 // the privates members of SkPictureRecord
    668 class SkPictureTester {
    669 private:
    670     static int EQ(const SkFlatData* a, const SkFlatData* b) {
    671         return *a == *b;
    672     }
    673 
    674     static void AssertFlattenedObjectsEqual(
    675         SkPictureRecord* referenceRecord,
    676         SkPictureRecord* testRecord,
    677         skiatest::Reporter* reporter,
    678         CanvasTestStep* testStep) {
    679 
    680         REPORTER_ASSERT_MESSAGE(reporter,
    681             referenceRecord->fBitmapHeap->count() ==
    682             testRecord->fBitmapHeap->count(), testStep->assertMessage());
    683         REPORTER_ASSERT_MESSAGE(reporter,
    684             referenceRecord->fMatrices.count() ==
    685             testRecord->fMatrices.count(), testStep->assertMessage());
    686         for (int i = 0; i < referenceRecord->fMatrices.count(); ++i) {
    687             REPORTER_ASSERT_MESSAGE(reporter,
    688                 EQ(referenceRecord->fMatrices[i], testRecord->fMatrices[i]),
    689                 testStep->assertMessage());
    690         }
    691         REPORTER_ASSERT_MESSAGE(reporter,
    692             referenceRecord->fPaints.count() ==
    693             testRecord->fPaints.count(), testStep->assertMessage());
    694         for (int i = 0; i < referenceRecord->fPaints.count(); ++i) {
    695             REPORTER_ASSERT_MESSAGE(reporter,
    696                 EQ(referenceRecord->fPaints[i], testRecord->fPaints[i]),
    697                                     testStep->assertMessage());
    698         }
    699         REPORTER_ASSERT_MESSAGE(reporter,
    700             referenceRecord->fRegions.count() ==
    701             testRecord->fRegions.count(), testStep->assertMessage());
    702         for (int i = 0; i < referenceRecord->fRegions.count(); ++i) {
    703             REPORTER_ASSERT_MESSAGE(reporter,
    704                 EQ(referenceRecord->fRegions[i], testRecord->fRegions[i]),
    705                                     testStep->assertMessage());
    706         }
    707         REPORTER_ASSERT_MESSAGE(reporter,
    708             !referenceRecord->fPathHeap ==
    709             !testRecord->fPathHeap,
    710             testStep->assertMessage());
    711         // The following tests are commented out because they currently
    712         // fail. Issue: http://code.google.com/p/skia/issues/detail?id=507
    713         /*
    714         if (referenceRecord->fPathHeap) {
    715             REPORTER_ASSERT_MESSAGE(reporter,
    716                 referenceRecord->fPathHeap->count() ==
    717                 testRecord->fPathHeap->count(),
    718                 testStep->assertMessage());
    719             for (int i = 0; i < referenceRecord->fPathHeap->count(); ++i) {
    720                 REPORTER_ASSERT_MESSAGE(reporter,
    721                     (*referenceRecord->fPathHeap)[i] ==
    722                     (*testRecord->fPathHeap)[i], testStep->assertMessage());
    723             }
    724         }
    725         */
    726 
    727     }
    728 
    729 public:
    730 
    731     static void TestPictureFlattenedObjectReuse(skiatest::Reporter* reporter,
    732                                                 CanvasTestStep* testStep,
    733                                                 uint32_t recordFlags) {
    734         // Verify that when a test step is executed twice, no extra resources
    735         // are flattened during the second execution
    736         testStep->setAssertMessageFormat(kPictureDrawAssertMessageFormat);
    737         SkPicture referencePicture;
    738         SkCanvas* referenceCanvas = referencePicture.beginRecording(kWidth,
    739             kHeight, recordFlags);
    740         testStep->draw(referenceCanvas, reporter);
    741         SkPicture testPicture;
    742         SkCanvas* testCanvas = testPicture.beginRecording(kWidth,
    743             kHeight, recordFlags);
    744         testStep->draw(testCanvas, reporter);
    745         testStep->setAssertMessageFormat(kPictureSecondDrawAssertMessageFormat);
    746         testStep->draw(testCanvas, reporter);
    747 
    748         SkPictureRecord* referenceRecord = static_cast<SkPictureRecord*>(
    749             referenceCanvas);
    750         SkPictureRecord* testRecord = static_cast<SkPictureRecord*>(
    751             testCanvas);
    752         testStep->setAssertMessageFormat(kPictureResourceReuseMessageFormat);
    753         AssertFlattenedObjectsEqual(referenceRecord, testRecord,
    754             reporter, testStep);
    755     }
    756 };
    757 
    758 static void TestPdfDevice(skiatest::Reporter* reporter,
    759                           CanvasTestStep* testStep) {
    760     SkISize pageSize = SkISize::Make(kWidth, kHeight);
    761     SkPDFDevice device(pageSize, pageSize, SkMatrix::I());
    762     SkCanvas canvas(&device);
    763     testStep->setAssertMessageFormat(kPdfAssertMessageFormat);
    764     testStep->draw(&canvas, reporter);
    765     SkPDFDocument doc;
    766     doc.appendPage(&device);
    767     SkDynamicMemoryWStream stream;
    768     doc.emitPDF(&stream);
    769 }
    770 
    771 // The following class groups static functions that need to access
    772 // the privates members of SkDeferredCanvas
    773 class SkDeferredCanvasTester {
    774 public:
    775     static void TestDeferredCanvasStateConsistency(
    776         skiatest::Reporter* reporter,
    777         CanvasTestStep* testStep,
    778         const SkCanvas& referenceCanvas, bool silent) {
    779 
    780         SkBitmap deferredStore;
    781         createBitmap(&deferredStore, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
    782         SkDevice deferredDevice(deferredStore);
    783         SkAutoTUnref<SkDeferredCanvas> deferredCanvas(SkDeferredCanvas::Create(&deferredDevice));
    784         testStep->setAssertMessageFormat(kDeferredDrawAssertMessageFormat);
    785         testStep->draw(deferredCanvas, reporter);
    786         testStep->setAssertMessageFormat(kDeferredPreFlushAssertMessageFormat);
    787         AssertCanvasStatesEqual(reporter, deferredCanvas, &referenceCanvas,
    788             testStep);
    789 
    790         if (silent) {
    791             deferredCanvas->silentFlush();
    792         } else {
    793             deferredCanvas->flush();
    794         }
    795 
    796         testStep->setAssertMessageFormat(
    797             silent ? kDeferredPostSilentFlushPlaybackAssertMessageFormat :
    798             kDeferredPostFlushPlaybackAssertMessageFormat);
    799         AssertCanvasStatesEqual(reporter,
    800             deferredCanvas->immediateCanvas(),
    801             &referenceCanvas, testStep);
    802 
    803         // Verified that deferred canvas state is not affected by flushing
    804         // pending draw operations
    805 
    806         // The following test code is commented out because it currently fails.
    807         // Issue: http://code.google.com/p/skia/issues/detail?id=496
    808         /*
    809         testStep->setAssertMessageFormat(kDeferredPostFlushAssertMessageFormat);
    810         AssertCanvasStatesEqual(reporter, &deferredCanvas, &referenceCanvas,
    811             testStep);
    812         */
    813     }
    814 };
    815 
    816 // unused
    817 static void TestProxyCanvasStateConsistency(
    818     skiatest::Reporter* reporter,
    819     CanvasTestStep* testStep,
    820     const SkCanvas& referenceCanvas) {
    821 
    822     SkBitmap indirectStore;
    823     createBitmap(&indirectStore, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
    824     SkDevice indirectDevice(indirectStore);
    825     SkCanvas indirectCanvas(&indirectDevice);
    826     SkProxyCanvas proxyCanvas(&indirectCanvas);
    827     testStep->setAssertMessageFormat(kProxyDrawAssertMessageFormat);
    828     testStep->draw(&proxyCanvas, reporter);
    829     // Verify that the SkProxyCanvas reports consitent state
    830     testStep->setAssertMessageFormat(kProxyStateAssertMessageFormat);
    831     AssertCanvasStatesEqual(reporter, &proxyCanvas, &referenceCanvas,
    832         testStep);
    833     // Verify that the indirect canvas reports consitent state
    834     testStep->setAssertMessageFormat(kProxyIndirectStateAssertMessageFormat);
    835     AssertCanvasStatesEqual(reporter, &indirectCanvas, &referenceCanvas,
    836         testStep);
    837 }
    838 
    839 // unused
    840 static void TestNWayCanvasStateConsistency(
    841     skiatest::Reporter* reporter,
    842     CanvasTestStep* testStep,
    843     const SkCanvas& referenceCanvas) {
    844 
    845     SkBitmap indirectStore1;
    846     createBitmap(&indirectStore1, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
    847     SkDevice indirectDevice1(indirectStore1);
    848     SkCanvas indirectCanvas1(&indirectDevice1);
    849 
    850     SkBitmap indirectStore2;
    851     createBitmap(&indirectStore2, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
    852     SkDevice indirectDevice2(indirectStore2);
    853     SkCanvas indirectCanvas2(&indirectDevice2);
    854 
    855     SkISize canvasSize = referenceCanvas.getDeviceSize();
    856     SkNWayCanvas nWayCanvas(canvasSize.width(), canvasSize.height());
    857     nWayCanvas.addCanvas(&indirectCanvas1);
    858     nWayCanvas.addCanvas(&indirectCanvas2);
    859 
    860     testStep->setAssertMessageFormat(kNWayDrawAssertMessageFormat);
    861     testStep->draw(&nWayCanvas, reporter);
    862     // Verify that the SkProxyCanvas reports consitent state
    863     testStep->setAssertMessageFormat(kNWayStateAssertMessageFormat);
    864     AssertCanvasStatesEqual(reporter, &nWayCanvas, &referenceCanvas,
    865         testStep);
    866     // Verify that the indirect canvases report consitent state
    867     testStep->setAssertMessageFormat(kNWayIndirect1StateAssertMessageFormat);
    868     AssertCanvasStatesEqual(reporter, &indirectCanvas1, &referenceCanvas,
    869         testStep);
    870     testStep->setAssertMessageFormat(kNWayIndirect2StateAssertMessageFormat);
    871     AssertCanvasStatesEqual(reporter, &indirectCanvas2, &referenceCanvas,
    872         testStep);
    873 }
    874 
    875 /*
    876  * This sub-test verifies that the test step passes when executed
    877  * with SkCanvas and with classes derrived from SkCanvas. It also verifies
    878  * that the all canvas derivatives report the same state as an SkCanvas
    879  * after having executed the test step.
    880  */
    881 static void TestOverrideStateConsistency(skiatest::Reporter* reporter,
    882                                          CanvasTestStep* testStep) {
    883     SkBitmap referenceStore;
    884     createBitmap(&referenceStore, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
    885     SkDevice referenceDevice(referenceStore);
    886     SkCanvas referenceCanvas(&referenceDevice);
    887     testStep->setAssertMessageFormat(kCanvasDrawAssertMessageFormat);
    888     testStep->draw(&referenceCanvas, reporter);
    889 
    890     SkDeferredCanvasTester::TestDeferredCanvasStateConsistency(reporter, testStep, referenceCanvas, false);
    891 
    892     SkDeferredCanvasTester::TestDeferredCanvasStateConsistency(reporter, testStep, referenceCanvas, true);
    893 
    894     // The following test code is disabled because SkProxyCanvas is
    895     // missing a lot of virtual overrides on get* methods, which are used
    896     // to verify canvas state.
    897     // Issue: http://code.google.com/p/skia/issues/detail?id=500
    898 
    899     if (false) { // avoid bit rot, suppress warning
    900         TestProxyCanvasStateConsistency(reporter, testStep, referenceCanvas);
    901     }
    902 
    903     // The following test code is disabled because SkNWayCanvas does not
    904     // report correct clipping and device bounds information
    905     // Issue: http://code.google.com/p/skia/issues/detail?id=501
    906 
    907     if (false) { // avoid bit rot, suppress warning
    908         TestNWayCanvasStateConsistency(reporter, testStep, referenceCanvas);
    909     }
    910 
    911     if (false) { // avoid bit rot, suppress warning
    912         test_clipVisitor(reporter, &referenceCanvas);
    913     }
    914 }
    915 
    916 static void TestCanvas(skiatest::Reporter* reporter) {
    917     // Init global here because bitmap pixels cannot be alocated during
    918     // static initialization
    919     kTestBitmap = testBitmap();
    920 
    921     for (int testStep = 0; testStep < testStepArray().count(); testStep++) {
    922         TestOverrideStateConsistency(reporter, testStepArray()[testStep]);
    923         SkPictureTester::TestPictureFlattenedObjectReuse(reporter,
    924             testStepArray()[testStep], 0);
    925         if (testStepArray()[testStep]->enablePdfTesting()) {
    926             TestPdfDevice(reporter, testStepArray()[testStep]);
    927         }
    928     }
    929 
    930     // Explicitly call reset(), so we don't leak the pixels (since kTestBitmap is a global)
    931     kTestBitmap.reset();
    932 }
    933 
    934 #include "TestClassDef.h"
    935 DEFINE_TESTCLASS("Canvas", TestCanvasClass, TestCanvas)
    936