1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/compiler_specific.h"
6 #include "skia/ext/analysis_canvas.h"
7 #include "skia/ext/refptr.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "third_party/skia/include/core/SkPicture.h"
10 #include "third_party/skia/include/core/SkPictureRecorder.h"
11 #include "third_party/skia/include/core/SkShader.h"
12 #include "third_party/skia/include/effects/SkOffsetImageFilter.h"
16 void SolidColorFill(skia::AnalysisCanvas
& canvas
) {
17 canvas
.clear(SkColorSetARGB(255, 255, 255, 255));
20 void TransparentFill(skia::AnalysisCanvas
& canvas
) {
21 canvas
.clear(SkColorSetARGB(0, 0, 0, 0));
27 TEST(AnalysisCanvasTest
, EmptyCanvas
) {
28 skia::AnalysisCanvas
canvas(255, 255);
31 EXPECT_TRUE(canvas
.GetColorIfSolid(&color
));
32 EXPECT_EQ(color
, SkColorSetARGB(0, 0, 0, 0));
35 TEST(AnalysisCanvasTest
, ClearCanvas
) {
36 skia::AnalysisCanvas
canvas(255, 255);
39 SkColor color
= SkColorSetARGB(0, 12, 34, 56);
43 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
44 EXPECT_EQ(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
47 color
= SkColorSetARGB(255, 65, 43, 21);
50 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
51 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
52 EXPECT_EQ(outputColor
, color
);
55 color
= SkColorSetARGB(128, 11, 22, 33);
58 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
60 // Test helper methods
61 SolidColorFill(canvas
);
62 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
63 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
65 TransparentFill(canvas
);
66 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
67 EXPECT_EQ(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
70 TEST(AnalysisCanvasTest
, ComplexActions
) {
71 skia::AnalysisCanvas
canvas(255, 255);
74 SkColor color
= SkColorSetARGB(255, 11, 22, 33);
76 paint
.setColor(color
);
78 canvas
.drawPaint(paint
);
81 //TODO(vmpstr): This should return true. (crbug.com/180597)
82 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
87 SkPoint::Make(255, 0),
88 SkPoint::Make(255, 255),
92 SolidColorFill(canvas
);
93 canvas
.drawPoints(SkCanvas::kLines_PointMode
, 4, points
, paint
);
95 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
98 SolidColorFill(canvas
);
99 canvas
.drawOval(SkRect::MakeWH(255, 255), paint
);
101 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
104 SolidColorFill(canvas
);
105 SkBitmap secondBitmap
;
106 secondBitmap
.allocN32Pixels(255, 255);
107 canvas
.drawBitmap(secondBitmap
, 0, 0);
109 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
112 TEST(AnalysisCanvasTest
, SimpleDrawRect
) {
113 skia::AnalysisCanvas
canvas(255, 255);
115 SkColor color
= SkColorSetARGB(255, 11, 22, 33);
117 paint
.setColor(color
);
118 canvas
.clipRect(SkRect::MakeWH(255, 255));
119 canvas
.drawRect(SkRect::MakeWH(255, 255), paint
);
122 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
123 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
124 EXPECT_EQ(color
, outputColor
);
126 color
= SkColorSetARGB(255, 22, 33, 44);
127 paint
.setColor(color
);
128 canvas
.translate(-128, -128);
129 canvas
.drawRect(SkRect::MakeWH(382, 382), paint
);
131 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
133 color
= SkColorSetARGB(255, 33, 44, 55);
134 paint
.setColor(color
);
135 canvas
.drawRect(SkRect::MakeWH(383, 383), paint
);
137 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
138 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
139 EXPECT_EQ(color
, outputColor
);
141 color
= SkColorSetARGB(0, 0, 0, 0);
142 paint
.setColor(color
);
143 canvas
.drawRect(SkRect::MakeWH(383, 383), paint
);
145 // This test relies on canvas treating a paint with 0-color as a no-op
146 // thus not changing its "is_solid" status.
147 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
148 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
149 EXPECT_EQ(outputColor
, SkColorSetARGB(255, 33, 44, 55));
151 color
= SkColorSetARGB(128, 128, 128, 128);
152 paint
.setColor(color
);
153 canvas
.drawRect(SkRect::MakeWH(383, 383), paint
);
155 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
157 paint
.setXfermodeMode(SkXfermode::kClear_Mode
);
158 canvas
.drawRect(SkRect::MakeWH(382, 382), paint
);
160 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
162 canvas
.drawRect(SkRect::MakeWH(383, 383), paint
);
164 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
165 EXPECT_EQ(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
167 canvas
.translate(128, 128);
168 color
= SkColorSetARGB(255, 11, 22, 33);
169 paint
.setColor(color
);
170 paint
.setXfermodeMode(SkXfermode::kSrcOver_Mode
);
171 canvas
.drawRect(SkRect::MakeWH(255, 255), paint
);
173 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
174 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
175 EXPECT_EQ(color
, outputColor
);
178 canvas
.drawRect(SkRect::MakeWH(255, 255), paint
);
180 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
183 TEST(AnalysisCanvasTest
, FilterPaint
) {
184 skia::AnalysisCanvas
canvas(255, 255);
187 skia::RefPtr
<SkImageFilter
> filter
= skia::AdoptRef(SkOffsetImageFilter::Create(10, 10));
188 paint
.setImageFilter(filter
.get());
189 canvas
.drawRect(SkRect::MakeWH(255, 255), paint
);
192 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
195 TEST(AnalysisCanvasTest
, ClipPath
) {
196 skia::AnalysisCanvas
canvas(255, 255);
198 // Skia will look for paths that are actually rects and treat
199 // them as such. We add a divot to the following path to prevent
200 // this optimization and truly test clipPath's behavior.
203 path
.lineTo(128, 50);
205 path
.lineTo(255, 255);
209 SolidColorFill(canvas
);
210 canvas
.clipPath(path
);
211 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
214 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
216 canvas
.clipPath(path
);
217 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
220 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
222 SolidColorFill(canvas
);
223 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
226 TEST(AnalysisCanvasTest
, SaveLayerRestore
) {
227 skia::AnalysisCanvas
canvas(255, 255);
230 SolidColorFill(canvas
);
231 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
233 SkRect bounds
= SkRect::MakeWH(255, 255);
235 paint
.setColor(SkColorSetARGB(255, 255, 255, 255));
236 paint
.setXfermodeMode(SkXfermode::kSrcOver_Mode
);
238 // This should force non-transparency
239 canvas
.saveLayer(&bounds
, &paint
);
240 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
241 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
243 TransparentFill(canvas
);
244 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
246 SolidColorFill(canvas
);
247 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
248 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
250 paint
.setXfermodeMode(SkXfermode::kDst_Mode
);
252 // This should force non-solid color
253 canvas
.saveLayer(&bounds
, &paint
);
254 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
256 TransparentFill(canvas
);
257 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
259 SolidColorFill(canvas
);
260 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
263 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
265 TransparentFill(canvas
);
266 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
268 SolidColorFill(canvas
);
269 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
270 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
273 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
274 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
276 TransparentFill(canvas
);
277 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
278 EXPECT_EQ(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
280 SolidColorFill(canvas
);
281 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
282 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
285 TEST(AnalysisCanvasTest
, EarlyOutNotSolid
) {
286 SkTileGridFactory::TileGridInfo tile_grid_info
;
287 tile_grid_info
.fTileInterval
.set(256, 256);
288 tile_grid_info
.fOffset
.setZero();
289 tile_grid_info
.fMargin
.setEmpty();
290 SkTileGridFactory
factory(tile_grid_info
);
291 SkPictureRecorder recorder
;
293 // Create a picture with 3 commands, last of which is non-solid.
294 skia::RefPtr
<SkCanvas
> record_canvas
=
295 skia::SharePtr(recorder
.beginRecording(256, 256, &factory
));
297 std::string text
= "text";
298 SkPoint point
= SkPoint::Make(SkIntToScalar(25), SkIntToScalar(25));
301 paint
.setColor(SkColorSetARGB(255, 255, 255, 255));
302 paint
.setXfermodeMode(SkXfermode::kSrcOver_Mode
);
304 record_canvas
->drawRect(SkRect::MakeWH(256, 256), paint
);
305 record_canvas
->drawRect(SkRect::MakeWH(256, 256), paint
);
306 record_canvas
->drawText(
307 text
.c_str(), text
.length(), point
.fX
, point
.fY
, paint
);
309 skia::RefPtr
<SkPicture
> picture
= skia::AdoptRef(recorder
.endRecording());
311 // Draw the picture into the analysis canvas, using the canvas as a callback
313 skia::AnalysisCanvas
canvas(256, 256);
314 picture
->draw(&canvas
, &canvas
);
316 // Ensure that canvas is not solid.
317 SkColor output_color
;
318 EXPECT_FALSE(canvas
.GetColorIfSolid(&output_color
));
320 // Verify that we aborted drawing.
321 EXPECT_TRUE(canvas
.abortDrawing());
325 TEST(AnalysisCanvasTest
, ClipComplexRegion
) {
326 skia::AnalysisCanvas
canvas(255, 255);
330 path
.lineTo(128, 50);
332 path
.lineTo(255, 255);
334 SkIRect pathBounds
= path
.getBounds().round();
336 region
.setPath(path
, SkRegion(pathBounds
));
339 SolidColorFill(canvas
);
340 canvas
.clipRegion(region
);
341 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
344 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
346 canvas
.clipRegion(region
);
347 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
350 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
352 SolidColorFill(canvas
);
353 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));