1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkCanvas.h" 9 #include "SkDrawLooper.h" 10 #include "SkTypes.h" 11 #include "Test.h" 12 13 /* 14 * Subclass of looper that just draws once, with an offset in X. 15 */ 16 class TestLooper : public SkDrawLooper { 17 public: 18 19 SkDrawLooper::Context* createContext(SkCanvas*, void* storage) const override { 20 return new (storage) TestDrawLooperContext; 21 } 22 23 size_t contextSize() const override { return sizeof(TestDrawLooperContext); } 24 25 #ifndef SK_IGNORE_TO_STRING 26 void toString(SkString* str) const override { 27 str->append("TestLooper:"); 28 } 29 #endif 30 31 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(TestLooper); 32 33 private: 34 class TestDrawLooperContext : public SkDrawLooper::Context { 35 public: 36 TestDrawLooperContext() : fOnce(true) {} 37 virtual ~TestDrawLooperContext() {} 38 39 bool next(SkCanvas* canvas, SkPaint*) override { 40 if (fOnce) { 41 fOnce = false; 42 canvas->translate(SkIntToScalar(10), 0); 43 return true; 44 } 45 return false; 46 } 47 private: 48 bool fOnce; 49 }; 50 }; 51 52 SkFlattenable* TestLooper::CreateProc(SkReadBuffer&) { return new TestLooper; } 53 54 static void test_drawBitmap(skiatest::Reporter* reporter) { 55 SkBitmap src; 56 src.allocN32Pixels(10, 10); 57 src.eraseColor(SK_ColorWHITE); 58 59 SkBitmap dst; 60 dst.allocN32Pixels(10, 10); 61 dst.eraseColor(SK_ColorTRANSPARENT); 62 63 SkCanvas canvas(dst); 64 SkPaint paint; 65 66 // we are initially transparent 67 REPORTER_ASSERT(reporter, 0 == *dst.getAddr32(5, 5)); 68 69 // we see the bitmap drawn 70 canvas.drawBitmap(src, 0, 0, &paint); 71 REPORTER_ASSERT(reporter, 0xFFFFFFFF == *dst.getAddr32(5, 5)); 72 73 // reverify we are clear again 74 dst.eraseColor(SK_ColorTRANSPARENT); 75 REPORTER_ASSERT(reporter, 0 == *dst.getAddr32(5, 5)); 76 77 // if the bitmap is clipped out, we don't draw it 78 canvas.drawBitmap(src, SkIntToScalar(-10), 0, &paint); 79 REPORTER_ASSERT(reporter, 0 == *dst.getAddr32(5, 5)); 80 81 // now install our looper, which will draw, since it internally translates 82 // to the left. The test is to ensure that canvas' quickReject machinary 83 // allows us through, even though sans-looper we would look like we should 84 // be clipped out. 85 paint.setLooper(new TestLooper)->unref(); 86 canvas.drawBitmap(src, SkIntToScalar(-10), 0, &paint); 87 REPORTER_ASSERT(reporter, 0xFFFFFFFF == *dst.getAddr32(5, 5)); 88 } 89 90 static void test_layers(skiatest::Reporter* reporter) { 91 SkCanvas canvas(100, 100); 92 93 SkRect r = SkRect::MakeWH(10, 10); 94 REPORTER_ASSERT(reporter, false == canvas.quickReject(r)); 95 96 r.offset(300, 300); 97 REPORTER_ASSERT(reporter, true == canvas.quickReject(r)); 98 99 // Test that saveLayer updates quickReject 100 SkRect bounds = SkRect::MakeLTRB(50, 50, 70, 70); 101 canvas.saveLayer(&bounds, nullptr); 102 REPORTER_ASSERT(reporter, true == canvas.quickReject(SkRect::MakeWH(10, 10))); 103 REPORTER_ASSERT(reporter, false == canvas.quickReject(SkRect::MakeWH(60, 60))); 104 } 105 106 DEF_TEST(QuickReject, reporter) { 107 test_drawBitmap(reporter); 108 test_layers(reporter); 109 } 110