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 "testing/gtest/include/gtest/gtest.h"
8 #include "third_party/skia/include/core/SkShader.h"
9
10 namespace {
11
SolidColorFill(skia::AnalysisCanvas & canvas)12 void SolidColorFill(skia::AnalysisCanvas& canvas) {
13 canvas.clear(SkColorSetARGB(255, 255, 255, 255));
14 }
15
TransparentFill(skia::AnalysisCanvas & canvas)16 void TransparentFill(skia::AnalysisCanvas& canvas) {
17 canvas.clear(SkColorSetARGB(0, 0, 0, 0));
18 }
19
20 } // namespace
21 namespace skia {
22
TEST(AnalysisCanvasTest,EmptyCanvas)23 TEST(AnalysisCanvasTest, EmptyCanvas) {
24 SkBitmap emptyBitmap;
25 emptyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255);
26 skia::AnalysisDevice device(emptyBitmap);
27 skia::AnalysisCanvas canvas(&device);
28
29 SkColor color;
30 EXPECT_TRUE(canvas.GetColorIfSolid(&color));
31 EXPECT_EQ(color, SkColorSetARGB(0, 0, 0, 0));
32 }
33
TEST(AnalysisCanvasTest,ClearCanvas)34 TEST(AnalysisCanvasTest, ClearCanvas) {
35 SkBitmap emptyBitmap;
36 emptyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255);
37 skia::AnalysisDevice device(emptyBitmap);
38 skia::AnalysisCanvas canvas(&device);
39
40 // Transparent color
41 SkColor color = SkColorSetARGB(0, 12, 34, 56);
42 canvas.clear(color);
43
44 SkColor outputColor;
45 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
46 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
47
48 // Solid color
49 color = SkColorSetARGB(255, 65, 43, 21);
50 canvas.clear(color);
51
52 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
53 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
54 EXPECT_EQ(outputColor, color);
55
56 // Translucent color
57 color = SkColorSetARGB(128, 11, 22, 33);
58 canvas.clear(color);
59
60 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
61
62 // Test helper methods
63 SolidColorFill(canvas);
64 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
65 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
66
67 TransparentFill(canvas);
68 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
69 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
70 }
71
TEST(AnalysisCanvasTest,ComplexActions)72 TEST(AnalysisCanvasTest, ComplexActions) {
73 SkBitmap emptyBitmap;
74 emptyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255);
75 skia::AnalysisDevice device(emptyBitmap);
76 skia::AnalysisCanvas canvas(&device);
77
78 // Draw paint test.
79 SkColor color = SkColorSetARGB(255, 11, 22, 33);
80 SkPaint paint;
81 paint.setColor(color);
82
83 canvas.drawPaint(paint);
84
85 SkColor outputColor;
86 //TODO(vmpstr): This should return true. (crbug.com/180597)
87 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
88
89 // Draw points test.
90 SkPoint points[4] = {
91 SkPoint::Make(0, 0),
92 SkPoint::Make(255, 0),
93 SkPoint::Make(255, 255),
94 SkPoint::Make(0, 255)
95 };
96
97 SolidColorFill(canvas);
98 canvas.drawPoints(SkCanvas::kLines_PointMode, 4, points, paint);
99
100 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
101
102 // Draw oval test.
103 SolidColorFill(canvas);
104 canvas.drawOval(SkRect::MakeWH(255, 255), paint);
105
106 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
107
108 // Draw bitmap test.
109 SolidColorFill(canvas);
110 SkBitmap secondBitmap;
111 secondBitmap.setConfig(SkBitmap::kNo_Config, 255, 255);
112 canvas.drawBitmap(secondBitmap, 0, 0);
113
114 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
115 }
116
TEST(AnalysisCanvasTest,SimpleDrawRect)117 TEST(AnalysisCanvasTest, SimpleDrawRect) {
118 SkBitmap emptyBitmap;
119 emptyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255);
120 skia::AnalysisDevice device(emptyBitmap);
121 skia::AnalysisCanvas canvas(&device);
122
123 SkColor color = SkColorSetARGB(255, 11, 22, 33);
124 SkPaint paint;
125 paint.setColor(color);
126 canvas.clipRect(SkRect::MakeWH(255, 255));
127 canvas.drawRect(SkRect::MakeWH(255, 255), paint);
128
129 SkColor outputColor;
130 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
131 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
132 EXPECT_EQ(color, outputColor);
133
134 color = SkColorSetARGB(255, 22, 33, 44);
135 paint.setColor(color);
136 canvas.translate(-128, -128);
137 canvas.drawRect(SkRect::MakeWH(382, 382), paint);
138
139 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
140
141 color = SkColorSetARGB(255, 33, 44, 55);
142 paint.setColor(color);
143 canvas.drawRect(SkRect::MakeWH(383, 383), paint);
144
145 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
146 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
147 EXPECT_EQ(color, outputColor);
148
149 color = SkColorSetARGB(0, 0, 0, 0);
150 paint.setColor(color);
151 canvas.drawRect(SkRect::MakeWH(383, 383), paint);
152
153 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
154 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
155 EXPECT_EQ(outputColor, SkColorSetARGB(255, 33, 44, 55));
156
157 color = SkColorSetARGB(128, 128, 128, 128);
158 paint.setColor(color);
159 canvas.drawRect(SkRect::MakeWH(383, 383), paint);
160
161 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
162
163 paint.setXfermodeMode(SkXfermode::kClear_Mode);
164 canvas.drawRect(SkRect::MakeWH(382, 382), paint);
165
166 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
167
168 canvas.drawRect(SkRect::MakeWH(383, 383), paint);
169
170 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
171 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
172
173 canvas.translate(128, 128);
174 color = SkColorSetARGB(255, 11, 22, 33);
175 paint.setColor(color);
176 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
177 canvas.drawRect(SkRect::MakeWH(255, 255), paint);
178
179 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
180 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
181 EXPECT_EQ(color, outputColor);
182
183 canvas.rotate(50);
184 canvas.drawRect(SkRect::MakeWH(255, 255), paint);
185
186 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
187 }
188
TEST(AnalysisCanvasTest,ClipPath)189 TEST(AnalysisCanvasTest, ClipPath) {
190 SkBitmap emptyBitmap;
191 emptyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255);
192 skia::AnalysisDevice device(emptyBitmap);
193 skia::AnalysisCanvas canvas(&device);
194
195 SkPath path;
196 path.moveTo(0, 0);
197 path.lineTo(255, 0);
198 path.lineTo(255, 255);
199 path.lineTo(0, 255);
200
201 SkColor outputColor;
202 SolidColorFill(canvas);
203 canvas.clipPath(path);
204 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
205
206 canvas.save();
207 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
208
209 canvas.clipPath(path);
210 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
211
212 canvas.restore();
213 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
214
215 SolidColorFill(canvas);
216 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
217 }
218
TEST(AnalysisCanvasTest,SaveLayerRestore)219 TEST(AnalysisCanvasTest, SaveLayerRestore) {
220 SkBitmap emptyBitmap;
221 emptyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255);
222 skia::AnalysisDevice device(emptyBitmap);
223 skia::AnalysisCanvas canvas(&device);
224
225 SkColor outputColor;
226 SolidColorFill(canvas);
227 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
228
229 SkRect bounds = SkRect::MakeWH(255, 255);
230 SkPaint paint;
231 paint.setColor(SkColorSetARGB(255, 255, 255, 255));
232 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
233
234 // This should force non-transparency
235 canvas.saveLayer(&bounds, &paint, SkCanvas::kMatrix_SaveFlag);
236 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
237 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
238
239 TransparentFill(canvas);
240 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
241
242 SolidColorFill(canvas);
243 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
244 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
245
246 paint.setXfermodeMode(SkXfermode::kDst_Mode);
247
248 // This should force non-solid color
249 canvas.saveLayer(&bounds, &paint, SkCanvas::kMatrix_SaveFlag);
250 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
251
252 TransparentFill(canvas);
253 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
254
255 SolidColorFill(canvas);
256 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
257
258 canvas.restore();
259 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
260
261 TransparentFill(canvas);
262 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
263
264 SolidColorFill(canvas);
265 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
266 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
267
268 canvas.restore();
269 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
270 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
271
272 TransparentFill(canvas);
273 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
274 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
275
276 SolidColorFill(canvas);
277 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
278 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
279 }
280
TEST(AnalysisCanvasTest,HasText)281 TEST(AnalysisCanvasTest, HasText) {
282 int width = 200;
283 int height = 100;
284
285 SkBitmap bitmap;
286 bitmap.setConfig(SkBitmap::kNo_Config, width, height);
287
288 const char* text = "A";
289 size_t byteLength = 1;
290
291 SkPoint point = SkPoint::Make(SkIntToScalar(25), SkIntToScalar(25));
292 SkPath path;
293 path.moveTo(point);
294 path.lineTo(SkIntToScalar(75), SkIntToScalar(75));
295
296 SkPaint paint;
297 paint.setColor(SK_ColorGRAY);
298 paint.setTextSize(SkIntToScalar(10));
299
300 {
301 skia::AnalysisDevice device(bitmap);
302 skia::AnalysisCanvas canvas(&device);
303 // Test after initialization.
304 EXPECT_FALSE(canvas.HasText());
305 // Test drawing anything other than text.
306 canvas.drawRect(SkRect::MakeWH(width/2, height), paint);
307 EXPECT_FALSE(canvas.HasText());
308 }
309 {
310 // Test SkCanvas::drawText.
311 skia::AnalysisDevice device(bitmap);
312 skia::AnalysisCanvas canvas(&device);
313 canvas.drawText(text, byteLength, point.fX, point.fY, paint);
314 EXPECT_TRUE(canvas.HasText());
315 }
316 {
317 // Test SkCanvas::drawPosText.
318 skia::AnalysisDevice device(bitmap);
319 skia::AnalysisCanvas canvas(&device);
320 canvas.drawPosText(text, byteLength, &point, paint);
321 EXPECT_TRUE(canvas.HasText());
322 }
323 {
324 // Test SkCanvas::drawPosTextH.
325 skia::AnalysisDevice device(bitmap);
326 skia::AnalysisCanvas canvas(&device);
327 canvas.drawPosTextH(text, byteLength, &point.fX, point.fY, paint);
328 EXPECT_TRUE(canvas.HasText());
329 }
330 {
331 // Test SkCanvas::drawTextOnPathHV.
332 skia::AnalysisDevice device(bitmap);
333 skia::AnalysisCanvas canvas(&device);
334 canvas.drawTextOnPathHV(text, byteLength, path, point.fX, point.fY, paint);
335 EXPECT_TRUE(canvas.HasText());
336 }
337 {
338 // Test SkCanvas::drawTextOnPath.
339 skia::AnalysisDevice device(bitmap);
340 skia::AnalysisCanvas canvas(&device);
341 canvas.drawTextOnPath(text, byteLength, path, NULL, paint);
342 EXPECT_TRUE(canvas.HasText());
343 }
344 {
345 // Text under opaque rect.
346 skia::AnalysisDevice device(bitmap);
347 skia::AnalysisCanvas canvas(&device);
348 canvas.drawText(text, byteLength, point.fX, point.fY, paint);
349 EXPECT_TRUE(canvas.HasText());
350 canvas.drawRect(SkRect::MakeWH(width, height), paint);
351 EXPECT_FALSE(canvas.HasText());
352 }
353 {
354 // Text under translucent rect.
355 skia::AnalysisDevice device(bitmap);
356 skia::AnalysisCanvas canvas(&device);
357 canvas.drawText(text, byteLength, point.fX, point.fY, paint);
358 EXPECT_TRUE(canvas.HasText());
359 SkPaint translucentPaint;
360 translucentPaint.setColor(0x88FFFFFF);
361 canvas.drawRect(SkRect::MakeWH(width, height), translucentPaint);
362 EXPECT_TRUE(canvas.HasText());
363 }
364 {
365 // Text under rect in clear mode.
366 skia::AnalysisDevice device(bitmap);
367 skia::AnalysisCanvas canvas(&device);
368 canvas.drawText(text, byteLength, point.fX, point.fY, paint);
369 EXPECT_TRUE(canvas.HasText());
370 SkPaint clearModePaint;
371 clearModePaint.setXfermodeMode(SkXfermode::kClear_Mode);
372 canvas.drawRect(SkRect::MakeWH(width, height), clearModePaint);
373 EXPECT_FALSE(canvas.HasText());
374 }
375 {
376 // Clear.
377 skia::AnalysisDevice device(bitmap);
378 skia::AnalysisCanvas canvas(&device);
379 canvas.drawText(text, byteLength, point.fX, point.fY, paint);
380 EXPECT_TRUE(canvas.HasText());
381 canvas.clear(SK_ColorGRAY);
382 EXPECT_FALSE(canvas.HasText());
383 }
384 {
385 // Text inside clip region.
386 skia::AnalysisDevice device(bitmap);
387 skia::AnalysisCanvas canvas(&device);
388 canvas.clipRect(SkRect::MakeWH(100, 100));
389 canvas.drawText(text, byteLength, point.fX, point.fY, paint);
390 EXPECT_TRUE(canvas.HasText());
391 }
392 {
393 // Text outside clip region.
394 skia::AnalysisDevice device(bitmap);
395 skia::AnalysisCanvas canvas(&device);
396 canvas.clipRect(SkRect::MakeXYWH(100, 0, 100, 100));
397 canvas.drawText(text, byteLength, point.fX, point.fY, paint);
398 // Analysis device does not do any clipping.
399 // So even when text is outside the clip region,
400 // it is marked as having the text.
401 // TODO(alokp): We may be able to do some trivial rejection.
402 EXPECT_TRUE(canvas.HasText());
403 }
404 }
405
406 } // namespace skia
407