Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkAutoMalloc.h"
      9 #include "SkColor.h"
     10 #include "SkColorFilter.h"
     11 #include "SkColorPriv.h"
     12 #include "SkLumaColorFilter.h"
     13 #include "SkRandom.h"
     14 #include "SkReadBuffer.h"
     15 #include "SkWriteBuffer.h"
     16 #include "SkRandom.h"
     17 #include "Test.h"
     18 
     19 static sk_sp<SkColorFilter> reincarnate_colorfilter(SkFlattenable* obj) {
     20     SkBinaryWriteBuffer wb;
     21     wb.writeFlattenable(obj);
     22 
     23     size_t size = wb.bytesWritten();
     24     SkAutoSMalloc<1024> storage(size);
     25     // make a copy into storage
     26     wb.writeToMemory(storage.get());
     27 
     28     SkReadBuffer rb(storage.get(), size);
     29     return rb.readColorFilter();
     30 }
     31 
     32 ///////////////////////////////////////////////////////////////////////////////
     33 
     34 static sk_sp<SkColorFilter> make_filter() {
     35     // pick a filter that cannot compose with itself via newComposed()
     36     return SkColorFilter::MakeModeFilter(SK_ColorRED, SkBlendMode::kColorBurn);
     37 }
     38 
     39 static void test_composecolorfilter_limit(skiatest::Reporter* reporter) {
     40     // Test that CreateComposeFilter() has some finite limit (i.e. that the factory can return null)
     41     const int way_too_many = 100;
     42     auto parent(make_filter());
     43     for (int i = 2; i < way_too_many; ++i) {
     44         auto filter(make_filter());
     45         parent = SkColorFilter::MakeComposeFilter(parent, filter);
     46         if (nullptr == parent) {
     47             REPORTER_ASSERT(reporter, i > 2); // we need to have succeeded at least once!
     48             return;
     49         }
     50     }
     51     REPORTER_ASSERT(reporter, false); // we never saw a nullptr :(
     52 }
     53 
     54 #define ILLEGAL_MODE    ((SkBlendMode)-1)
     55 
     56 DEF_TEST(ColorFilter, reporter) {
     57     SkRandom rand;
     58 
     59     for (int mode = 0; mode <= (int)SkBlendMode::kLastMode; mode++) {
     60         SkColor color = rand.nextU();
     61 
     62         // ensure we always get a filter, by avoiding the possibility of a
     63         // special case that would return nullptr (if color's alpha is 0 or 0xFF)
     64         color = SkColorSetA(color, 0x7F);
     65 
     66         auto cf = SkColorFilter::MakeModeFilter(color, (SkBlendMode)mode);
     67 
     68         // allow for no filter if we're in Dst mode (its a no op)
     69         if (SkBlendMode::kDst == (SkBlendMode)mode && nullptr == cf) {
     70             continue;
     71         }
     72 
     73         REPORTER_ASSERT(reporter, cf);
     74 
     75         SkColor c = ~color;
     76         SkBlendMode m = ILLEGAL_MODE;
     77 
     78         SkColor expectedColor = color;
     79         SkBlendMode expectedMode = (SkBlendMode)mode;
     80 
     81 //        SkDebugf("--- mc [%d %x] ", mode, color);
     82 
     83         REPORTER_ASSERT(reporter, cf->asColorMode(&c, (SkBlendMode*)&m));
     84         // handle special-case folding by the factory
     85         if (SkBlendMode::kClear == (SkBlendMode)mode) {
     86             if (c != expectedColor) {
     87                 expectedColor = 0;
     88             }
     89             if (m != expectedMode) {
     90                 expectedMode = SkBlendMode::kSrc;
     91             }
     92         }
     93 
     94 //        SkDebugf("--- got [%d %x] expected [%d %x]\n", m, c, expectedMode, expectedColor);
     95 
     96         REPORTER_ASSERT(reporter, c == expectedColor);
     97         REPORTER_ASSERT(reporter, m == expectedMode);
     98 
     99         {
    100             auto cf2 = reincarnate_colorfilter(cf.get());
    101             REPORTER_ASSERT(reporter, cf2);
    102 
    103             SkColor c2 = ~color;
    104             SkBlendMode m2 = ILLEGAL_MODE;
    105             REPORTER_ASSERT(reporter, cf2->asColorMode(&c2, (SkBlendMode*)&m2));
    106             REPORTER_ASSERT(reporter, c2 == expectedColor);
    107             REPORTER_ASSERT(reporter, m2 == expectedMode);
    108         }
    109     }
    110 
    111     test_composecolorfilter_limit(reporter);
    112 }
    113