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::kARGB_8888_Config
, 255, 255);
112 secondBitmap
.allocPixels();
113 canvas
.drawBitmap(secondBitmap
, 0, 0);
115 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
118 TEST(AnalysisCanvasTest
, SimpleDrawRect
) {
119 SkBitmap emptyBitmap
;
120 emptyBitmap
.setConfig(SkBitmap::kNo_Config
, 255, 255);
121 skia::AnalysisDevice
device(emptyBitmap
);
122 skia::AnalysisCanvas
canvas(&device
);
124 SkColor color
= SkColorSetARGB(255, 11, 22, 33);
126 paint
.setColor(color
);
127 canvas
.clipRect(SkRect::MakeWH(255, 255));
128 canvas
.drawRect(SkRect::MakeWH(255, 255), paint
);
131 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
132 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
133 EXPECT_EQ(color
, outputColor
);
135 color
= SkColorSetARGB(255, 22, 33, 44);
136 paint
.setColor(color
);
137 canvas
.translate(-128, -128);
138 canvas
.drawRect(SkRect::MakeWH(382, 382), paint
);
140 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
142 color
= SkColorSetARGB(255, 33, 44, 55);
143 paint
.setColor(color
);
144 canvas
.drawRect(SkRect::MakeWH(383, 383), paint
);
146 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
147 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
148 EXPECT_EQ(color
, outputColor
);
150 color
= SkColorSetARGB(0, 0, 0, 0);
151 paint
.setColor(color
);
152 canvas
.drawRect(SkRect::MakeWH(383, 383), paint
);
154 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
155 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
156 EXPECT_EQ(outputColor
, SkColorSetARGB(255, 33, 44, 55));
158 color
= SkColorSetARGB(128, 128, 128, 128);
159 paint
.setColor(color
);
160 canvas
.drawRect(SkRect::MakeWH(383, 383), paint
);
162 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
164 paint
.setXfermodeMode(SkXfermode::kClear_Mode
);
165 canvas
.drawRect(SkRect::MakeWH(382, 382), paint
);
167 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
169 canvas
.drawRect(SkRect::MakeWH(383, 383), paint
);
171 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
172 EXPECT_EQ(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
174 canvas
.translate(128, 128);
175 color
= SkColorSetARGB(255, 11, 22, 33);
176 paint
.setColor(color
);
177 paint
.setXfermodeMode(SkXfermode::kSrcOver_Mode
);
178 canvas
.drawRect(SkRect::MakeWH(255, 255), paint
);
180 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
181 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
182 EXPECT_EQ(color
, outputColor
);
185 canvas
.drawRect(SkRect::MakeWH(255, 255), paint
);
187 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
190 TEST(AnalysisCanvasTest
, ClipPath
) {
191 SkBitmap emptyBitmap
;
192 emptyBitmap
.setConfig(SkBitmap::kNo_Config
, 255, 255);
193 skia::AnalysisDevice
device(emptyBitmap
);
194 skia::AnalysisCanvas
canvas(&device
);
199 path
.lineTo(255, 255);
203 SolidColorFill(canvas
);
204 canvas
.clipPath(path
);
205 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
208 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
210 canvas
.clipPath(path
);
211 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
214 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
216 SolidColorFill(canvas
);
217 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
220 TEST(AnalysisCanvasTest
, SaveLayerRestore
) {
221 SkBitmap emptyBitmap
;
222 emptyBitmap
.setConfig(SkBitmap::kNo_Config
, 255, 255);
223 skia::AnalysisDevice
device(emptyBitmap
);
224 skia::AnalysisCanvas
canvas(&device
);
227 SolidColorFill(canvas
);
228 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
230 SkRect bounds
= SkRect::MakeWH(255, 255);
232 paint
.setColor(SkColorSetARGB(255, 255, 255, 255));
233 paint
.setXfermodeMode(SkXfermode::kSrcOver_Mode
);
235 // This should force non-transparency
236 canvas
.saveLayer(&bounds
, &paint
, SkCanvas::kMatrix_SaveFlag
);
237 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
238 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
240 TransparentFill(canvas
);
241 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
243 SolidColorFill(canvas
);
244 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
245 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
247 paint
.setXfermodeMode(SkXfermode::kDst_Mode
);
249 // This should force non-solid color
250 canvas
.saveLayer(&bounds
, &paint
, SkCanvas::kMatrix_SaveFlag
);
251 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
253 TransparentFill(canvas
);
254 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
256 SolidColorFill(canvas
);
257 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
260 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
262 TransparentFill(canvas
);
263 EXPECT_FALSE(canvas
.GetColorIfSolid(&outputColor
));
265 SolidColorFill(canvas
);
266 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
267 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
270 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
271 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
273 TransparentFill(canvas
);
274 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
275 EXPECT_EQ(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
277 SolidColorFill(canvas
);
278 EXPECT_TRUE(canvas
.GetColorIfSolid(&outputColor
));
279 EXPECT_NE(static_cast<SkColor
>(SK_ColorTRANSPARENT
), outputColor
);
282 TEST(AnalysisCanvasTest
, HasText
) {
287 bitmap
.setConfig(SkBitmap::kNo_Config
, width
, height
);
289 const char* text
= "A";
290 size_t byteLength
= 1;
292 SkPoint point
= SkPoint::Make(SkIntToScalar(25), SkIntToScalar(25));
295 path
.lineTo(SkIntToScalar(75), SkIntToScalar(75));
298 paint
.setColor(SK_ColorGRAY
);
299 paint
.setTextSize(SkIntToScalar(10));
302 skia::AnalysisDevice
device(bitmap
);
303 skia::AnalysisCanvas
canvas(&device
);
304 // Test after initialization.
305 EXPECT_FALSE(canvas
.HasText());
306 // Test drawing anything other than text.
307 canvas
.drawRect(SkRect::MakeWH(width
/2, height
), paint
);
308 EXPECT_FALSE(canvas
.HasText());
311 // Test SkCanvas::drawText.
312 skia::AnalysisDevice
device(bitmap
);
313 skia::AnalysisCanvas
canvas(&device
);
314 canvas
.drawText(text
, byteLength
, point
.fX
, point
.fY
, paint
);
315 EXPECT_TRUE(canvas
.HasText());
318 // Test SkCanvas::drawPosText.
319 skia::AnalysisDevice
device(bitmap
);
320 skia::AnalysisCanvas
canvas(&device
);
321 canvas
.drawPosText(text
, byteLength
, &point
, paint
);
322 EXPECT_TRUE(canvas
.HasText());
325 // Test SkCanvas::drawPosTextH.
326 skia::AnalysisDevice
device(bitmap
);
327 skia::AnalysisCanvas
canvas(&device
);
328 canvas
.drawPosTextH(text
, byteLength
, &point
.fX
, point
.fY
, paint
);
329 EXPECT_TRUE(canvas
.HasText());
332 // Test SkCanvas::drawTextOnPathHV.
333 skia::AnalysisDevice
device(bitmap
);
334 skia::AnalysisCanvas
canvas(&device
);
335 canvas
.drawTextOnPathHV(text
, byteLength
, path
, point
.fX
, point
.fY
, paint
);
336 EXPECT_TRUE(canvas
.HasText());
339 // Test SkCanvas::drawTextOnPath.
340 skia::AnalysisDevice
device(bitmap
);
341 skia::AnalysisCanvas
canvas(&device
);
342 canvas
.drawTextOnPath(text
, byteLength
, path
, NULL
, paint
);
343 EXPECT_TRUE(canvas
.HasText());
346 // Text under opaque rect.
347 skia::AnalysisDevice
device(bitmap
);
348 skia::AnalysisCanvas
canvas(&device
);
349 canvas
.drawText(text
, byteLength
, point
.fX
, point
.fY
, paint
);
350 EXPECT_TRUE(canvas
.HasText());
351 canvas
.drawRect(SkRect::MakeWH(width
, height
), paint
);
352 EXPECT_FALSE(canvas
.HasText());
355 // Text under translucent rect.
356 skia::AnalysisDevice
device(bitmap
);
357 skia::AnalysisCanvas
canvas(&device
);
358 canvas
.drawText(text
, byteLength
, point
.fX
, point
.fY
, paint
);
359 EXPECT_TRUE(canvas
.HasText());
360 SkPaint translucentPaint
;
361 translucentPaint
.setColor(0x88FFFFFF);
362 canvas
.drawRect(SkRect::MakeWH(width
, height
), translucentPaint
);
363 EXPECT_TRUE(canvas
.HasText());
366 // Text under rect in clear mode.
367 skia::AnalysisDevice
device(bitmap
);
368 skia::AnalysisCanvas
canvas(&device
);
369 canvas
.drawText(text
, byteLength
, point
.fX
, point
.fY
, paint
);
370 EXPECT_TRUE(canvas
.HasText());
371 SkPaint clearModePaint
;
372 clearModePaint
.setXfermodeMode(SkXfermode::kClear_Mode
);
373 canvas
.drawRect(SkRect::MakeWH(width
, height
), clearModePaint
);
374 EXPECT_FALSE(canvas
.HasText());
378 skia::AnalysisDevice
device(bitmap
);
379 skia::AnalysisCanvas
canvas(&device
);
380 canvas
.drawText(text
, byteLength
, point
.fX
, point
.fY
, paint
);
381 EXPECT_TRUE(canvas
.HasText());
382 canvas
.clear(SK_ColorGRAY
);
383 EXPECT_FALSE(canvas
.HasText());
386 // Text inside clip region.
387 skia::AnalysisDevice
device(bitmap
);
388 skia::AnalysisCanvas
canvas(&device
);
389 canvas
.clipRect(SkRect::MakeWH(100, 100));
390 canvas
.drawText(text
, byteLength
, point
.fX
, point
.fY
, paint
);
391 EXPECT_TRUE(canvas
.HasText());
394 // Text outside clip region.
395 skia::AnalysisDevice
device(bitmap
);
396 skia::AnalysisCanvas
canvas(&device
);
397 canvas
.clipRect(SkRect::MakeXYWH(100, 0, 100, 100));
398 canvas
.drawText(text
, byteLength
, point
.fX
, point
.fY
, paint
);
399 // Analysis device does not do any clipping.
400 // So even when text is outside the clip region,
401 // it is marked as having the text.
402 // TODO(alokp): We may be able to do some trivial rejection.
403 EXPECT_TRUE(canvas
.HasText());