blob: f3f6a0a8e890f73d2752b6ef4b869276bf746e64 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
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 */
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +00007
reed@google.com43c50c82011-04-14 15:50:52 +00008#include "SkColor.h"
9#include "SkColorFilter.h"
tfarina@chromium.org8f6884a2014-01-24 20:56:26 +000010#include "SkColorPriv.h"
commit-bot@chromium.org6c1ee2d2013-10-07 18:00:17 +000011#include "SkLumaColorFilter.h"
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000012#include "SkReadBuffer.h"
13#include "SkWriteBuffer.h"
tfarina@chromium.org8f6884a2014-01-24 20:56:26 +000014#include "SkRandom.h"
15#include "SkXfermode.h"
16#include "Test.h"
reed@google.com43c50c82011-04-14 15:50:52 +000017
reed@google.com35348222013-10-16 13:05:06 +000018static SkColorFilter* reincarnate_colorfilter(SkFlattenable* obj) {
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000019 SkWriteBuffer wb;
djsollen@google.comcefc8652012-03-26 15:52:10 +000020 wb.writeFlattenable(obj);
reed@google.com43c50c82011-04-14 15:50:52 +000021
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000022 size_t size = wb.bytesWritten();
reed@google.com43c50c82011-04-14 15:50:52 +000023 SkAutoSMalloc<1024> storage(size);
24 // make a copy into storage
djsollen@google.comc73dd5c2012-08-07 15:54:32 +000025 wb.writeToMemory(storage.get());
reed@google.com43c50c82011-04-14 15:50:52 +000026
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000027 SkReadBuffer rb(storage.get(), size);
reed@google.com35348222013-10-16 13:05:06 +000028 return rb.readColorFilter();
reed@google.com43c50c82011-04-14 15:50:52 +000029}
30
31///////////////////////////////////////////////////////////////////////////////
32
33#define ILLEGAL_MODE ((SkXfermode::Mode)-1)
34
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +000035DEF_TEST(ColorFilter, reporter) {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000036 SkRandom rand;
reed@google.com43c50c82011-04-14 15:50:52 +000037
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 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000073 }
reed@google.com43c50c82011-04-14 15:50:52 +000074
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);
rmistry@google.comd6176b02012-08-23 18:14:13 +000079
reed@google.com43c50c82011-04-14 15:50:52 +000080 {
reed@google.com35348222013-10-16 13:05:06 +000081 SkColorFilter* cf2 = reincarnate_colorfilter(cf);
reed@google.com43c50c82011-04-14 15:50:52 +000082 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
commit-bot@chromium.org6c1ee2d2013-10-07 18:00:17 +000094///////////////////////////////////////////////////////////////////////////////
95
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +000096DEF_TEST(LumaColorFilter, reporter) {
commit-bot@chromium.org6c1ee2d2013-10-07 18:00:17 +000097 SkPMColor in, out;
98 SkAutoTUnref<SkColorFilter> lf(SkLumaColorFilter::Create());
99
commit-bot@chromium.orgd494b092013-10-10 20:13:51 +0000100 // Applying luma to white produces black with the same transparency.
commit-bot@chromium.org6c1ee2d2013-10-07 18:00:17 +0000101 for (unsigned i = 0; i < 256; ++i) {
102 in = SkPackARGB32(i, i, i, i);
103 lf->filterSpan(&in, 1, &out);
commit-bot@chromium.orgd494b092013-10-10 20:13:51 +0000104 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);
commit-bot@chromium.org6c1ee2d2013-10-07 18:00:17 +0000108 }
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
commit-bot@chromium.orgd494b092013-10-10 20:13:51 +0000117 // For general colors, a luma filter generates black with an attenuated alpha channel.
commit-bot@chromium.org6c1ee2d2013-10-07 18:00:17 +0000118 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);
commit-bot@chromium.orgd494b092013-10-10 20:13:51 +0000123 REPORTER_ASSERT(reporter, SkGetPackedR32(out) == 0);
124 REPORTER_ASSERT(reporter, SkGetPackedG32(out) == 0);
125 REPORTER_ASSERT(reporter, SkGetPackedB32(out) == 0);
commit-bot@chromium.org6c1ee2d2013-10-07 18:00:17 +0000126 }
127}