OLD | NEW |
| (Empty) |
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. | |
4 | |
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" | |
13 | |
14 namespace { | |
15 | |
16 void SolidColorFill(skia::AnalysisCanvas& canvas) { | |
17 canvas.clear(SkColorSetARGB(255, 255, 255, 255)); | |
18 } | |
19 | |
20 void TransparentFill(skia::AnalysisCanvas& canvas) { | |
21 canvas.clear(SkColorSetARGB(0, 0, 0, 0)); | |
22 } | |
23 | |
24 } // namespace | |
25 namespace skia { | |
26 | |
27 TEST(AnalysisCanvasTest, EmptyCanvas) { | |
28 skia::AnalysisCanvas canvas(255, 255); | |
29 | |
30 SkColor color; | |
31 EXPECT_TRUE(canvas.GetColorIfSolid(&color)); | |
32 EXPECT_EQ(color, SkColorSetARGB(0, 0, 0, 0)); | |
33 } | |
34 | |
35 TEST(AnalysisCanvasTest, ClearCanvas) { | |
36 skia::AnalysisCanvas canvas(255, 255); | |
37 | |
38 // Transparent color | |
39 SkColor color = SkColorSetARGB(0, 12, 34, 56); | |
40 canvas.clear(color); | |
41 | |
42 SkColor outputColor; | |
43 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
44 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
45 | |
46 // Solid color | |
47 color = SkColorSetARGB(255, 65, 43, 21); | |
48 canvas.clear(color); | |
49 | |
50 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
51 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
52 EXPECT_EQ(outputColor, color); | |
53 | |
54 // Translucent color | |
55 color = SkColorSetARGB(128, 11, 22, 33); | |
56 canvas.clear(color); | |
57 | |
58 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
59 | |
60 // Test helper methods | |
61 SolidColorFill(canvas); | |
62 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
63 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
64 | |
65 TransparentFill(canvas); | |
66 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
67 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
68 } | |
69 | |
70 TEST(AnalysisCanvasTest, ComplexActions) { | |
71 skia::AnalysisCanvas canvas(255, 255); | |
72 | |
73 // Draw paint test. | |
74 SkColor color = SkColorSetARGB(255, 11, 22, 33); | |
75 SkPaint paint; | |
76 paint.setColor(color); | |
77 | |
78 canvas.drawPaint(paint); | |
79 | |
80 SkColor outputColor; | |
81 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
82 | |
83 // Draw points test. | |
84 SkPoint points[4] = { | |
85 SkPoint::Make(0, 0), | |
86 SkPoint::Make(255, 0), | |
87 SkPoint::Make(255, 255), | |
88 SkPoint::Make(0, 255) | |
89 }; | |
90 | |
91 SolidColorFill(canvas); | |
92 canvas.drawPoints(SkCanvas::kLines_PointMode, 4, points, paint); | |
93 | |
94 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
95 | |
96 // Draw oval test. | |
97 SolidColorFill(canvas); | |
98 canvas.drawOval(SkRect::MakeWH(255, 255), paint); | |
99 | |
100 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
101 | |
102 // Draw bitmap test. | |
103 SolidColorFill(canvas); | |
104 SkBitmap secondBitmap; | |
105 secondBitmap.allocN32Pixels(255, 255); | |
106 canvas.drawBitmap(secondBitmap, 0, 0); | |
107 | |
108 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
109 } | |
110 | |
111 TEST(AnalysisCanvasTest, SimpleDrawRect) { | |
112 skia::AnalysisCanvas canvas(255, 255); | |
113 | |
114 SkColor color = SkColorSetARGB(255, 11, 22, 33); | |
115 SkPaint paint; | |
116 paint.setColor(color); | |
117 canvas.clipRect(SkRect::MakeWH(255, 255)); | |
118 canvas.drawRect(SkRect::MakeWH(255, 255), paint); | |
119 | |
120 SkColor outputColor; | |
121 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
122 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
123 EXPECT_EQ(color, outputColor); | |
124 | |
125 color = SkColorSetARGB(255, 22, 33, 44); | |
126 paint.setColor(color); | |
127 canvas.translate(-128, -128); | |
128 canvas.drawRect(SkRect::MakeWH(382, 382), paint); | |
129 | |
130 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
131 | |
132 color = SkColorSetARGB(255, 33, 44, 55); | |
133 paint.setColor(color); | |
134 canvas.drawRect(SkRect::MakeWH(383, 383), paint); | |
135 | |
136 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
137 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
138 EXPECT_EQ(color, outputColor); | |
139 | |
140 color = SkColorSetARGB(0, 0, 0, 0); | |
141 paint.setColor(color); | |
142 canvas.drawRect(SkRect::MakeWH(383, 383), paint); | |
143 | |
144 // This test relies on canvas treating a paint with 0-color as a no-op | |
145 // thus not changing its "is_solid" status. | |
146 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
147 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
148 EXPECT_EQ(outputColor, SkColorSetARGB(255, 33, 44, 55)); | |
149 | |
150 color = SkColorSetARGB(128, 128, 128, 128); | |
151 paint.setColor(color); | |
152 canvas.drawRect(SkRect::MakeWH(383, 383), paint); | |
153 | |
154 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
155 | |
156 paint.setXfermodeMode(SkXfermode::kClear_Mode); | |
157 canvas.drawRect(SkRect::MakeWH(382, 382), paint); | |
158 | |
159 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
160 | |
161 canvas.drawRect(SkRect::MakeWH(383, 383), paint); | |
162 | |
163 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
164 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
165 | |
166 canvas.translate(128, 128); | |
167 color = SkColorSetARGB(255, 11, 22, 33); | |
168 paint.setColor(color); | |
169 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); | |
170 canvas.drawRect(SkRect::MakeWH(255, 255), paint); | |
171 | |
172 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
173 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
174 EXPECT_EQ(color, outputColor); | |
175 | |
176 canvas.rotate(50); | |
177 canvas.drawRect(SkRect::MakeWH(255, 255), paint); | |
178 | |
179 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
180 } | |
181 | |
182 TEST(AnalysisCanvasTest, FilterPaint) { | |
183 skia::AnalysisCanvas canvas(255, 255); | |
184 SkPaint paint; | |
185 | |
186 skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(SkOffsetImageFilter::Creat
e(10, 10)); | |
187 paint.setImageFilter(filter.get()); | |
188 canvas.drawRect(SkRect::MakeWH(255, 255), paint); | |
189 | |
190 SkColor outputColor; | |
191 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
192 } | |
193 | |
194 TEST(AnalysisCanvasTest, ClipPath) { | |
195 skia::AnalysisCanvas canvas(255, 255); | |
196 | |
197 // Skia will look for paths that are actually rects and treat | |
198 // them as such. We add a divot to the following path to prevent | |
199 // this optimization and truly test clipPath's behavior. | |
200 SkPath path; | |
201 path.moveTo(0, 0); | |
202 path.lineTo(128, 50); | |
203 path.lineTo(255, 0); | |
204 path.lineTo(255, 255); | |
205 path.lineTo(0, 255); | |
206 | |
207 SkColor outputColor; | |
208 SolidColorFill(canvas); | |
209 canvas.clipPath(path); | |
210 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
211 | |
212 canvas.save(); | |
213 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
214 | |
215 canvas.clipPath(path); | |
216 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
217 | |
218 canvas.restore(); | |
219 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
220 | |
221 SolidColorFill(canvas); | |
222 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
223 } | |
224 | |
225 TEST(AnalysisCanvasTest, SaveLayerWithXfermode) { | |
226 skia::AnalysisCanvas canvas(255, 255); | |
227 SkRect bounds = SkRect::MakeWH(255, 255); | |
228 SkColor outputColor; | |
229 | |
230 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
231 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
232 SkPaint paint; | |
233 | |
234 // Note: nothing is draw to the the save layer, but solid color | |
235 // and transparency are handled conservatively in case the layer's | |
236 // SkPaint draws something. For example, there could be an | |
237 // SkPictureImageFilter. If someday analysis_canvas starts doing | |
238 // a deeper analysis of the SkPaint, this test may need to be | |
239 // redesigned. | |
240 TransparentFill(canvas); | |
241 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
242 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
243 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | |
244 canvas.saveLayer(&bounds, &paint); | |
245 canvas.restore(); | |
246 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
247 | |
248 TransparentFill(canvas); | |
249 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
250 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
251 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); | |
252 canvas.saveLayer(&bounds, &paint); | |
253 canvas.restore(); | |
254 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
255 | |
256 // Layer with dst xfermode is a no-op, so this is the only case | |
257 // where solid color is unaffected by the layer. | |
258 TransparentFill(canvas); | |
259 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
260 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
261 paint.setXfermodeMode(SkXfermode::kDst_Mode); | |
262 canvas.saveLayer(&bounds, &paint); | |
263 canvas.restore(); | |
264 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
265 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
266 } | |
267 | |
268 TEST(AnalysisCanvasTest, SaveLayerRestore) { | |
269 skia::AnalysisCanvas canvas(255, 255); | |
270 | |
271 SkColor outputColor; | |
272 SolidColorFill(canvas); | |
273 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
274 | |
275 SkRect bounds = SkRect::MakeWH(255, 255); | |
276 SkPaint paint; | |
277 paint.setColor(SkColorSetARGB(255, 255, 255, 255)); | |
278 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); | |
279 | |
280 // This should force non-transparency | |
281 canvas.saveLayer(&bounds, &paint); | |
282 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
283 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
284 | |
285 TransparentFill(canvas); | |
286 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
287 | |
288 SolidColorFill(canvas); | |
289 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
290 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
291 | |
292 paint.setXfermodeMode(SkXfermode::kDst_Mode); | |
293 | |
294 // This should force non-solid color | |
295 canvas.saveLayer(&bounds, &paint); | |
296 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
297 | |
298 TransparentFill(canvas); | |
299 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
300 | |
301 SolidColorFill(canvas); | |
302 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
303 | |
304 canvas.restore(); | |
305 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
306 | |
307 TransparentFill(canvas); | |
308 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
309 | |
310 SolidColorFill(canvas); | |
311 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
312 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
313 | |
314 canvas.restore(); | |
315 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
316 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
317 | |
318 TransparentFill(canvas); | |
319 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
320 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
321 | |
322 SolidColorFill(canvas); | |
323 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor)); | |
324 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor); | |
325 } | |
326 | |
327 TEST(AnalysisCanvasTest, EarlyOutNotSolid) { | |
328 SkRTreeFactory factory; | |
329 SkPictureRecorder recorder; | |
330 | |
331 // Create a picture with 3 commands, last of which is non-solid. | |
332 skia::RefPtr<SkCanvas> record_canvas = | |
333 skia::SharePtr(recorder.beginRecording(256, 256, &factory)); | |
334 | |
335 std::string text = "text"; | |
336 SkPoint point = SkPoint::Make(SkIntToScalar(25), SkIntToScalar(25)); | |
337 | |
338 SkPaint paint; | |
339 paint.setColor(SkColorSetARGB(255, 255, 255, 255)); | |
340 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); | |
341 | |
342 record_canvas->drawRect(SkRect::MakeWH(256, 256), paint); | |
343 record_canvas->drawRect(SkRect::MakeWH(256, 256), paint); | |
344 record_canvas->drawText( | |
345 text.c_str(), text.length(), point.fX, point.fY, paint); | |
346 | |
347 skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording()); | |
348 | |
349 // Draw the picture into the analysis canvas, using the canvas as a callback | |
350 // as well. | |
351 skia::AnalysisCanvas canvas(256, 256); | |
352 picture->playback(&canvas, &canvas); | |
353 | |
354 // Ensure that canvas is not solid. | |
355 SkColor output_color; | |
356 EXPECT_FALSE(canvas.GetColorIfSolid(&output_color)); | |
357 | |
358 // Verify that we aborted drawing. | |
359 EXPECT_TRUE(canvas.abortDrawing()); | |
360 | |
361 } | |
362 | |
363 TEST(AnalysisCanvasTest, ClipComplexRegion) { | |
364 skia::AnalysisCanvas canvas(255, 255); | |
365 | |
366 SkPath path; | |
367 path.moveTo(0, 0); | |
368 path.lineTo(128, 50); | |
369 path.lineTo(255, 0); | |
370 path.lineTo(255, 255); | |
371 path.lineTo(0, 255); | |
372 SkIRect pathBounds = path.getBounds().round(); | |
373 SkRegion region; | |
374 region.setPath(path, SkRegion(pathBounds)); | |
375 | |
376 SkColor outputColor; | |
377 SolidColorFill(canvas); | |
378 canvas.clipRegion(region); | |
379 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
380 | |
381 canvas.save(); | |
382 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
383 | |
384 canvas.clipRegion(region); | |
385 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
386 | |
387 canvas.restore(); | |
388 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
389 | |
390 SolidColorFill(canvas); | |
391 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor)); | |
392 } | |
393 | |
394 } // namespace skia | |
OLD | NEW |