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 "SkColor.h"
      9 #include "SkColorFilter.h"
     10 #include "SkColorPriv.h"
     11 #include "SkLumaColorFilter.h"
     12 #include "SkReadBuffer.h"
     13 #include "SkWriteBuffer.h"
     14 #include "SkRandom.h"
     15 #include "SkXfermode.h"
     16 #include "Test.h"
     17 
     18 static SkColorFilter* reincarnate_colorfilter(SkFlattenable* obj) {
     19     SkWriteBuffer wb;
     20     wb.writeFlattenable(obj);
     21 
     22     size_t size = wb.bytesWritten();
     23     SkAutoSMalloc<1024> storage(size);
     24     // make a copy into storage
     25     wb.writeToMemory(storage.get());
     26 
     27     SkReadBuffer rb(storage.get(), size);
     28     return rb.readColorFilter();
     29 }
     30 
     31 ///////////////////////////////////////////////////////////////////////////////
     32 
     33 #define ILLEGAL_MODE    ((SkXfermode::Mode)-1)
     34 
     35 DEF_TEST(ColorFilter, reporter) {
     36     SkRandom rand;
     37 
     38     for (int mode = 0; mode <= SkXfermode::kLastMode; mode++) {
     39         SkColor color = rand.nextU();
     40 
     41         // ensure we always get a filter, by avoiding the possibility of a
     42         // special case that would return NULL (if color's alpha is 0 or 0xFF)
     43         color = SkColorSetA(color, 0x7F);
     44 
     45         SkColorFilter* cf = SkColorFilter::CreateModeFilter(color,
     46                                                         (SkXfermode::Mode)mode);
     47 
     48         // allow for no filter if we're in Dst mode (its a no op)
     49         if (SkXfermode::kDst_Mode == mode && NULL == cf) {
     50             continue;
     51         }
     52 
     53         SkAutoUnref aur(cf);
     54         REPORTER_ASSERT(reporter, cf);
     55 
     56         SkColor c = ~color;
     57         SkXfermode::Mode m = ILLEGAL_MODE;
     58 
     59         SkColor expectedColor = color;
     60         SkXfermode::Mode expectedMode = (SkXfermode::Mode)mode;
     61 
     62 //        SkDebugf("--- mc [%d %x] ", mode, color);
     63 
     64         REPORTER_ASSERT(reporter, cf->asColorMode(&c, &m));
     65         // handle special-case folding by the factory
     66         if (SkXfermode::kClear_Mode == mode) {
     67             if (c != expectedColor) {
     68                 expectedColor = 0;
     69             }
     70             if (m != expectedMode) {
     71                 expectedMode = SkXfermode::kSrc_Mode;
     72             }
     73         }
     74 
     75 //        SkDebugf("--- got [%d %x] expected [%d %x]\n", m, c, expectedMode, expectedColor);
     76 
     77         REPORTER_ASSERT(reporter, c == expectedColor);
     78         REPORTER_ASSERT(reporter, m == expectedMode);
     79 
     80         {
     81             SkColorFilter* cf2 = reincarnate_colorfilter(cf);
     82             SkAutoUnref aur2(cf2);
     83             REPORTER_ASSERT(reporter, cf2);
     84 
     85             SkColor c2 = ~color;
     86             SkXfermode::Mode m2 = ILLEGAL_MODE;
     87             REPORTER_ASSERT(reporter, cf2->asColorMode(&c2, &m2));
     88             REPORTER_ASSERT(reporter, c2 == expectedColor);
     89             REPORTER_ASSERT(reporter, m2 == expectedMode);
     90         }
     91     }
     92 }
     93 
     94 ///////////////////////////////////////////////////////////////////////////////
     95 
     96 DEF_TEST(LumaColorFilter, reporter) {
     97     SkPMColor in, out;
     98     SkAutoTUnref<SkColorFilter> lf(SkLumaColorFilter::Create());
     99 
    100     // Applying luma to white produces black with the same transparency.
    101     for (unsigned i = 0; i < 256; ++i) {
    102         in = SkPackARGB32(i, i, i, i);
    103         lf->filterSpan(&in, 1, &out);
    104         REPORTER_ASSERT(reporter, SkGetPackedA32(out) == i);
    105         REPORTER_ASSERT(reporter, SkGetPackedR32(out) == 0);
    106         REPORTER_ASSERT(reporter, SkGetPackedG32(out) == 0);
    107         REPORTER_ASSERT(reporter, SkGetPackedB32(out) == 0);
    108     }
    109 
    110     // Applying luma to black yields transparent black (luminance(black) == 0)
    111     for (unsigned i = 0; i < 256; ++i) {
    112         in = SkPackARGB32(i, 0, 0, 0);
    113         lf->filterSpan(&in, 1, &out);
    114         REPORTER_ASSERT(reporter, out == SK_ColorTRANSPARENT);
    115     }
    116 
    117     // For general colors, a luma filter generates black with an attenuated alpha channel.
    118     for (unsigned i = 1; i < 256; ++i) {
    119         in = SkPackARGB32(i, i, i / 2, i / 3);
    120         lf->filterSpan(&in, 1, &out);
    121         REPORTER_ASSERT(reporter, out != in);
    122         REPORTER_ASSERT(reporter, SkGetPackedA32(out) <= i);
    123         REPORTER_ASSERT(reporter, SkGetPackedR32(out) == 0);
    124         REPORTER_ASSERT(reporter, SkGetPackedG32(out) == 0);
    125         REPORTER_ASSERT(reporter, SkGetPackedB32(out) == 0);
    126     }
    127 }
    128