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