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 "testing/gtest/include/gtest/gtest.h"
8 #include "third_party/skia/include/core/SkShader.h"
12 void SolidColorFill(skia::AnalysisCanvas& canvas) {
13 canvas.clear(SkColorSetARGB(255, 255, 255, 255));
16 void TransparentFill(skia::AnalysisCanvas& canvas) {
17 canvas.clear(SkColorSetARGB(0, 0, 0, 0));
23 TEST(AnalysisCanvasTest, EmptyCanvas) {
25 emptyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255);
26 skia::AnalysisDevice device(emptyBitmap);
27 skia::AnalysisCanvas canvas(&device);
30 EXPECT_TRUE(canvas.GetColorIfSolid(&color));
31 EXPECT_EQ(color, SkColorSetARGB(0, 0, 0, 0));
34 TEST(AnalysisCanvasTest, ClearCanvas) {
36 emptyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255);
37 skia::AnalysisDevice device(emptyBitmap);
38 skia::AnalysisCanvas canvas(&device);
41 SkColor color = SkColorSetARGB(0, 12, 34, 56);
45 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
46 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
49 color = SkColorSetARGB(255, 65, 43, 21);
52 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
53 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
54 EXPECT_EQ(outputColor, color);
57 color = SkColorSetARGB(128, 11, 22, 33);
60 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
62 // Test helper methods
63 SolidColorFill(canvas);
64 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
65 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
67 TransparentFill(canvas);
68 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
69 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
72 TEST(AnalysisCanvasTest, ComplexActions) {
74 emptyBitmap.setConfig(SkBitmap::kNo_Config, 255, 255);
75 skia::AnalysisDevice device(emptyBitmap);
76 skia::AnalysisCanvas canvas(&device);
79 SkColor color = SkColorSetARGB(255, 11, 22, 33);
81 paint.setColor(color);
83 canvas.drawPaint(paint);
86 //TODO(vmpstr): This should return true. (crbug.com/180597)
87 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
92 SkPoint::Make(255, 0),
93 SkPoint::Make(255, 255),
97 SolidColorFill(canvas);
98 canvas.drawPoints(SkCanvas::kLines_PointMode, 4, points, paint);
100 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
103 SolidColorFill(canvas);
104 canvas.drawOval(SkRect::MakeWH(255, 255), paint);
106 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
109 SolidColorFill(canvas);
110 SkBitmap secondBitmap;
111 secondBitmap.setConfig(SkBitmap::kNo_Config, 255, 255);
112 canvas.drawBitmap(secondBitmap, 0, 0);
114 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
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);
123 SkColor color = SkColorSetARGB(255, 11, 22, 33);
125 paint.setColor(color);
126 canvas.clipRect(SkRect::MakeWH(255, 255));
127 canvas.drawRect(SkRect::MakeWH(255, 255), paint);
130 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
131 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
132 EXPECT_EQ(color, outputColor);
134 color = SkColorSetARGB(255, 22, 33, 44);
135 paint.setColor(color);
136 canvas.translate(-128, -128);
137 canvas.drawRect(SkRect::MakeWH(382, 382), paint);
139 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
141 color = SkColorSetARGB(255, 33, 44, 55);
142 paint.setColor(color);
143 canvas.drawRect(SkRect::MakeWH(383, 383), paint);
145 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
146 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
147 EXPECT_EQ(color, outputColor);
149 color = SkColorSetARGB(0, 0, 0, 0);
150 paint.setColor(color);
151 canvas.drawRect(SkRect::MakeWH(383, 383), paint);
153 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
154 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
155 EXPECT_EQ(outputColor, SkColorSetARGB(255, 33, 44, 55));
157 color = SkColorSetARGB(128, 128, 128, 128);
158 paint.setColor(color);
159 canvas.drawRect(SkRect::MakeWH(383, 383), paint);
161 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
163 paint.setXfermodeMode(SkXfermode::kClear_Mode);
164 canvas.drawRect(SkRect::MakeWH(382, 382), paint);
166 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
168 canvas.drawRect(SkRect::MakeWH(383, 383), paint);
170 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
171 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
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);
179 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
180 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
181 EXPECT_EQ(color, outputColor);
184 canvas.drawRect(SkRect::MakeWH(255, 255), paint);
186 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
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);
198 path.lineTo(255, 255);
202 SolidColorFill(canvas);
203 canvas.clipPath(path);
204 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
207 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
209 canvas.clipPath(path);
210 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
213 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
215 SolidColorFill(canvas);
216 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
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);
226 SolidColorFill(canvas);
227 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
229 SkRect bounds = SkRect::MakeWH(255, 255);
231 paint.setColor(SkColorSetARGB(255, 255, 255, 255));
232 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
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);
239 TransparentFill(canvas);
240 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
242 SolidColorFill(canvas);
243 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
244 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
246 paint.setXfermodeMode(SkXfermode::kDst_Mode);
248 // This should force non-solid color
249 canvas.saveLayer(&bounds, &paint, SkCanvas::kMatrix_SaveFlag);
250 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
252 TransparentFill(canvas);
253 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
255 SolidColorFill(canvas);
256 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
259 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
261 TransparentFill(canvas);
262 EXPECT_FALSE(canvas.GetColorIfSolid(&outputColor));
264 SolidColorFill(canvas);
265 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
266 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
269 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
270 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
272 TransparentFill(canvas);
273 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
274 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
276 SolidColorFill(canvas);
277 EXPECT_TRUE(canvas.GetColorIfSolid(&outputColor));
278 EXPECT_NE(static_cast<SkColor>(SK_ColorTRANSPARENT), outputColor);
281 TEST(AnalysisCanvasTest, HasText) {
286 bitmap.setConfig(SkBitmap::kNo_Config, width, height);
288 const char* text = "A";
289 size_t byteLength = 1;
291 SkPoint point = SkPoint::Make(SkIntToScalar(25), SkIntToScalar(25));
294 path.lineTo(SkIntToScalar(75), SkIntToScalar(75));
297 paint.setColor(SK_ColorGRAY);
298 paint.setTextSize(SkIntToScalar(10));
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());
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());