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