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 12 void SolidColorFill(skia::AnalysisCanvas& canvas) { 13 canvas.clear(SkColorSetARGB(255, 255, 255, 255)); 14 } 15 16 void TransparentFill(skia::AnalysisCanvas& canvas) { 17 canvas.clear(SkColorSetARGB(0, 0, 0, 0)); 18 } 19 20 } // namespace 21 namespace skia { 22 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 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 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 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 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 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 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