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