1 /*
2  * Copyright 2014 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 "SkBBoxHierarchy.h"
10 #include "SkPaint.h"
11 #include "SkPicture.h"
12 #include "SkPictureRecorder.h"
13 
14 #include "Test.h"
15 
16 class PictureBBHTestBase {
17 public:
PictureBBHTestBase(int playbackWidth,int playbackHeight,int recordWidth,int recordHeight)18     PictureBBHTestBase(int playbackWidth, int playbackHeight,
19         int recordWidth, int recordHeight) {
20 
21         fResultBitmap.allocN32Pixels(playbackWidth, playbackHeight);
22         fPictureWidth = recordWidth;
23         fPictureHeight = recordHeight;
24     }
25 
~PictureBBHTestBase()26     virtual ~PictureBBHTestBase() { }
27 
28     virtual void doTest(SkCanvas& playbackCanvas, SkCanvas& recordingCanvas) = 0;
29 
run(skiatest::Reporter * reporter)30     void run(skiatest::Reporter* reporter) {
31         // No BBH
32         this->run(nullptr, reporter);
33 
34         // With an R-Tree
35         SkRTreeFactory RTreeFactory;
36         this->run(&RTreeFactory, reporter);
37     }
38 
39 private:
run(SkBBHFactory * factory,skiatest::Reporter * reporter)40     void run(SkBBHFactory* factory, skiatest::Reporter* reporter) {
41         SkCanvas playbackCanvas(fResultBitmap);
42         playbackCanvas.clear(SK_ColorGREEN);
43         SkPictureRecorder recorder;
44         SkCanvas* recordCanvas = recorder.beginRecording(SkIntToScalar(fPictureWidth),
45                                                          SkIntToScalar(fPictureHeight),
46                                                          factory);
47         this->doTest(playbackCanvas, *recordCanvas);
48         SkAutoTUnref<SkPicture> picture(recorder.endRecording());
49         playbackCanvas.drawPicture(picture);
50         REPORTER_ASSERT(reporter, SK_ColorGREEN == fResultBitmap.getColor(0, 0));
51     }
52 
53     SkBitmap fResultBitmap;
54     int fPictureWidth, fPictureHeight;
55 };
56 
57 // Test to verify the playback of an empty picture
58 //
59 class DrawEmptyPictureBBHTest : public PictureBBHTestBase {
60 public:
DrawEmptyPictureBBHTest()61     DrawEmptyPictureBBHTest()
62         : PictureBBHTestBase(2, 2, 1, 1) { }
~DrawEmptyPictureBBHTest()63     virtual ~DrawEmptyPictureBBHTest() { }
64 
doTest(SkCanvas &,SkCanvas &)65     void doTest(SkCanvas&, SkCanvas&) override { }
66 };
67 
68 // Test to verify the playback of a picture into a canvas that has
69 // an empty clip.
70 //
71 class EmptyClipPictureBBHTest : public PictureBBHTestBase {
72 public:
EmptyClipPictureBBHTest()73     EmptyClipPictureBBHTest()
74         : PictureBBHTestBase(2, 2, 3, 3) { }
75 
doTest(SkCanvas & playbackCanvas,SkCanvas & recordingCanvas)76     void doTest(SkCanvas& playbackCanvas, SkCanvas& recordingCanvas) override {
77         // intersect with out of bounds rect -> empty clip.
78         playbackCanvas.clipRect(SkRect::MakeXYWH(SkIntToScalar(10), SkIntToScalar(10),
79             SkIntToScalar(1), SkIntToScalar(1)), SkRegion::kIntersect_Op);
80         SkPaint paint;
81         recordingCanvas.drawRect(SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
82             SkIntToScalar(3), SkIntToScalar(3)), paint);
83     }
84 
~EmptyClipPictureBBHTest()85     virtual ~EmptyClipPictureBBHTest() { }
86 };
87 
DEF_TEST(PictureBBH,reporter)88 DEF_TEST(PictureBBH, reporter) {
89 
90     DrawEmptyPictureBBHTest emptyPictureTest;
91     emptyPictureTest.run(reporter);
92 
93     EmptyClipPictureBBHTest emptyClipPictureTest;
94     emptyClipPictureTest.run(reporter);
95 }
96