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