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 "include/core/SkBitmap.h" 9#include "include/core/SkCanvas.h" 10#include "include/core/SkPoint3.h" 11#include "include/core/SkTypes.h" 12#include "include/effects/SkImageFilters.h" 13#include "src/core/SkArenaAlloc.h" 14#include "tests/Test.h" 15 16static void test_drawBitmap(skiatest::Reporter* reporter) { 17 SkBitmap src; 18 src.allocN32Pixels(10, 10); 19 src.eraseColor(SK_ColorWHITE); 20 21 SkBitmap dst; 22 dst.allocN32Pixels(10, 10); 23 dst.eraseColor(SK_ColorTRANSPARENT); 24 25 SkCanvas canvas(dst); 26 27 // we are initially transparent 28 REPORTER_ASSERT(reporter, 0 == *dst.getAddr32(5, 5)); 29 30 // we see the bitmap drawn 31 canvas.drawImage(src.asImage(), 0, 0); 32 REPORTER_ASSERT(reporter, 0xFFFFFFFF == *dst.getAddr32(5, 5)); 33 34 // reverify we are clear again 35 dst.eraseColor(SK_ColorTRANSPARENT); 36 REPORTER_ASSERT(reporter, 0 == *dst.getAddr32(5, 5)); 37 38 // if the bitmap is clipped out, we don't draw it 39 canvas.drawImage(src.asImage(), SkIntToScalar(-10), 0); 40 REPORTER_ASSERT(reporter, 0 == *dst.getAddr32(5, 5)); 41} 42 43static void test_layers(skiatest::Reporter* reporter) { 44 SkCanvas canvas(100, 100); 45 46 SkRect r = SkRect::MakeWH(10, 10); 47 REPORTER_ASSERT(reporter, false == canvas.quickReject(r)); 48 49 r.offset(300, 300); 50 REPORTER_ASSERT(reporter, true == canvas.quickReject(r)); 51 52 // Test that saveLayer updates quickReject 53 SkRect bounds = SkRect::MakeLTRB(50, 50, 70, 70); 54 canvas.saveLayer(&bounds, nullptr); 55 REPORTER_ASSERT(reporter, true == canvas.quickReject(SkRect::MakeWH(10, 10))); 56 REPORTER_ASSERT(reporter, false == canvas.quickReject(SkRect::MakeWH(60, 60))); 57} 58 59static void test_quick_reject(skiatest::Reporter* reporter) { 60 SkCanvas canvas(100, 100); 61 SkRect r0 = SkRect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f); 62 SkRect r1 = SkRect::MakeLTRB(-50.0f, 110.0f, 50.0f, 120.0f); 63 SkRect r2 = SkRect::MakeLTRB(110.0f, -50.0f, 120.0f, 50.0f); 64 SkRect r3 = SkRect::MakeLTRB(-120.0f, -50.0f, 120.0f, 50.0f); 65 SkRect r4 = SkRect::MakeLTRB(-50.0f, -120.0f, 50.0f, 120.0f); 66 SkRect r5 = SkRect::MakeLTRB(-120.0f, -120.0f, 120.0f, 120.0f); 67 SkRect r6 = SkRect::MakeLTRB(-120.0f, -120.0f, -110.0f, -110.0f); 68 SkRect r7 = SkRect::MakeLTRB(SK_ScalarNaN, -50.0f, 50.0f, 50.0f); 69 SkRect r8 = SkRect::MakeLTRB(-50.0f, SK_ScalarNaN, 50.0f, 50.0f); 70 SkRect r9 = SkRect::MakeLTRB(-50.0f, -50.0f, SK_ScalarNaN, 50.0f); 71 SkRect r10 = SkRect::MakeLTRB(-50.0f, -50.0f, 50.0f, SK_ScalarNaN); 72 REPORTER_ASSERT(reporter, false == canvas.quickReject(r0)); 73 REPORTER_ASSERT(reporter, true == canvas.quickReject(r1)); 74 REPORTER_ASSERT(reporter, true == canvas.quickReject(r2)); 75 REPORTER_ASSERT(reporter, false == canvas.quickReject(r3)); 76 REPORTER_ASSERT(reporter, false == canvas.quickReject(r4)); 77 REPORTER_ASSERT(reporter, false == canvas.quickReject(r5)); 78 REPORTER_ASSERT(reporter, true == canvas.quickReject(r6)); 79 REPORTER_ASSERT(reporter, true == canvas.quickReject(r7)); 80 REPORTER_ASSERT(reporter, true == canvas.quickReject(r8)); 81 REPORTER_ASSERT(reporter, true == canvas.quickReject(r9)); 82 REPORTER_ASSERT(reporter, true == canvas.quickReject(r10)); 83 84 SkMatrix m = SkMatrix::Scale(2, 2); 85 m.setTranslateX(10.0f); 86 m.setTranslateY(10.0f); 87 canvas.setMatrix(m); 88 SkRect r11 = SkRect::MakeLTRB(5.0f, 5.0f, 100.0f, 100.0f); 89 SkRect r12 = SkRect::MakeLTRB(5.0f, 50.0f, 100.0f, 100.0f); 90 SkRect r13 = SkRect::MakeLTRB(50.0f, 5.0f, 100.0f, 100.0f); 91 REPORTER_ASSERT(reporter, false == canvas.quickReject(r11)); 92 REPORTER_ASSERT(reporter, true == canvas.quickReject(r12)); 93 REPORTER_ASSERT(reporter, true == canvas.quickReject(r13)); 94} 95 96DEF_TEST(QuickReject, reporter) { 97 test_drawBitmap(reporter); 98 test_layers(reporter); 99 test_quick_reject(reporter); 100} 101 102// Regression test to make sure that we keep fIsScaleTranslate up to date on the canvas. 103// It is possible to set a new matrix on the canvas without calling setMatrix(). This tests 104// that code path. 105DEF_TEST(QuickReject_MatrixState, reporter) { 106 SkCanvas canvas(100, 100); 107 108 SkMatrix matrix; 109 matrix.setRotate(45.0f); 110 canvas.setMatrix(matrix); 111 112 SkPaint paint; 113 sk_sp<SkImageFilter> filter = SkImageFilters::DistantLitDiffuse( 114 SkPoint3::Make(1.0f, 1.0f, 1.0f), 0xFF0000FF, 2.0f, 0.5f, nullptr); 115 REPORTER_ASSERT(reporter, filter); 116 paint.setImageFilter(filter); 117 SkCanvas::SaveLayerRec rec; 118 rec.fPaint = &paint; 119 canvas.saveLayer(rec); 120 121 // quickReject() will assert if the matrix is out of sync. 122 canvas.quickReject(SkRect::MakeWH(100.0f, 100.0f)); 123} 124