blob: af1cd935a2d6811719de08074291a2f2882e9182 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
halcanaryb0cce2c2015-01-26 12:49:00 -08008#include "sk_tool_utils.h"
reed@google.com9ac5e222011-05-05 20:05:10 +00009#include "SampleCode.h"
10#include "SkView.h"
11#include "SkCanvas.h"
12#include "SkColorFilter.h"
13#include "SkDevice.h"
14#include "SkPaint.h"
15#include "SkShader.h"
16
reed@google.com79b3b7e2011-05-18 13:07:22 +000017static int inflate5To8(int x) {
18 return (x << 3) | (x >> 2);
19}
20
21static int trunc5(int x) {
22 return x >> 3;
23}
24
25#define SK_R16_BITS 5
26
humper@google.com0e515772013-01-07 19:54:40 +000027#ifdef SK_DEBUG
rmistry@google.comae933ce2012-08-23 18:19:56 +000028static int round5_slow(int x) {
reed@google.com79b3b7e2011-05-18 13:07:22 +000029 int orig = x & 7;
30 int fake = x >> 5;
31 int trunc = x >> 3;
32
33 int diff = fake - orig;
34
35 int bias = 0;
36 if (diff > 4) {
37 bias = -1;
38 } else if (diff < -4) {
39 bias = 1;
40 }
41 return trunc + bias;
42}
humper@google.com0e515772013-01-07 19:54:40 +000043#endif
reed@google.com79b3b7e2011-05-18 13:07:22 +000044
45static int round5_fast(int x) {
46 int result = x + 3 - (x >> 5) + (x >> 7);
47 result >>= 3;
humper@google.com0e515772013-01-07 19:54:40 +000048#ifdef SK_DEBUG
reed@google.com79b3b7e2011-05-18 13:07:22 +000049 {
50 int r2 = round5_slow(x);
51 SkASSERT(r2 == result);
52 }
humper@google.com0e515772013-01-07 19:54:40 +000053#endif
reed@google.com79b3b7e2011-05-18 13:07:22 +000054 return result;
55}
56
57static void test_5bits() {
58 int e0 = 0;
59 int e1 = 0;
60 int e2 = 0;
61 int ae0 = 0;
62 int ae1 = 0;
63 int ae2 = 0;
64 for (int i = 0; i < 256; i++) {
65 int t0 = trunc5(i);
66 int t1 = round5_fast(i);
67 int t2 = trunc5(i);
68 int v0 = inflate5To8(t0);
69 int v1 = inflate5To8(t1);
70 int v2 = inflate5To8(t2);
71 int err0 = i - v0;
72 int err1 = i - v1;
73 int err2 = i - v2;
74 SkDebugf("--- %3d : trunc=%3d (%2d) round:%3d (%2d) \n"/*new:%d (%2d)\n"*/, i,
75 v0, err0, v1, err1, v2, err2);
rmistry@google.comae933ce2012-08-23 18:19:56 +000076
reed@google.com79b3b7e2011-05-18 13:07:22 +000077
78 e0 += err0;
79 e1 += err1;
80 e2 += err2;
81 ae0 += SkAbs32(err0);
82 ae1 += SkAbs32(err1);
83 ae2 += SkAbs32(err2);
84 }
85 SkDebugf("--- trunc: %d %d round: %d %d new: %d %d\n", e0, ae0, e1, ae1, e2, ae2);
86}
87
reed@google.com9ac5e222011-05-05 20:05:10 +000088static SkBitmap createBitmap(int n) {
89 SkBitmap bitmap;
commit-bot@chromium.orga8c18312014-02-17 02:55:57 +000090 bitmap.allocN32Pixels(n, n);
junov@google.comdbfac8a2012-12-06 21:47:40 +000091 bitmap.eraseColor(SK_ColorTRANSPARENT);
rmistry@google.comae933ce2012-08-23 18:19:56 +000092
reed@google.com9ac5e222011-05-05 20:05:10 +000093 SkCanvas canvas(bitmap);
94 SkRect r;
95 r.set(0, 0, SkIntToScalar(n), SkIntToScalar(n));
96 r.inset(SK_Scalar1, SK_Scalar1);
97
98 SkPaint paint;
99 paint.setAntiAlias(true);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000100
reed@google.com9ac5e222011-05-05 20:05:10 +0000101 paint.setColor(SK_ColorRED);
102 canvas.drawOval(r, paint);
103
104 r.inset(SK_Scalar1*n/4, SK_Scalar1*n/4);
105 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
106 paint.setColor(0x800000FF);
107 canvas.drawOval(r, paint);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000108
reed@google.com9ac5e222011-05-05 20:05:10 +0000109 return bitmap;
110}
111
112class ColorFilterView : public SampleView {
113 SkBitmap fBitmap;
114 SkShader* fShader;
115 enum {
116 N = 64
117 };
118public:
119 ColorFilterView() {
120 fBitmap = createBitmap(N);
halcanaryb0cce2c2015-01-26 12:49:00 -0800121 fShader = sk_tool_utils::create_checkerboard_shader(
halcanary878fa022015-01-26 11:24:32 -0800122 0xFFCCCCCC, 0xFFFFFFFF, 12);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000123
caryclark@google.com02939ce2012-06-06 12:09:51 +0000124 if (false) { // avoid bit rot, suppress warning
125 test_5bits();
126 }
reed@google.com9ac5e222011-05-05 20:05:10 +0000127 }
128
129 virtual ~ColorFilterView() {
130 fShader->unref();
131 }
132
133protected:
134 // overrides from SkEventSink
135 virtual bool onQuery(SkEvent* evt) {
136 if (SampleCode::TitleQ(*evt)) {
137 SampleCode::TitleR(evt, "ColorFilter");
138 return true;
139 }
140 return this->INHERITED::onQuery(evt);
141 }
142
143 virtual void onDrawBackground(SkCanvas* canvas) {
144 SkPaint paint;
145 paint.setShader(fShader);
146 canvas->drawPaint(paint);
147 }
148
149 virtual void onDrawContent(SkCanvas* canvas) {
150 if (false) {
151 SkPaint p;
152 p.setAntiAlias(true);
153 SkRect r = { 20.4f, 10, 20.6f, 20 };
154 canvas->drawRect(r, p);
155 r.set(30.9f, 10, 31.1f, 20);
156 canvas->drawRect(r, p);
157 return;
158 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000159
reed@google.com9ac5e222011-05-05 20:05:10 +0000160 static const SkXfermode::Mode gModes[] = {
Scroggo97c88c22011-05-11 14:05:25 +0000161 SkXfermode::kClear_Mode,
reed@google.com9ac5e222011-05-05 20:05:10 +0000162 SkXfermode::kSrc_Mode,
163 SkXfermode::kDst_Mode,
Scroggo97c88c22011-05-11 14:05:25 +0000164 SkXfermode::kSrcOver_Mode,
165 SkXfermode::kDstOver_Mode,
reed@google.com9ac5e222011-05-05 20:05:10 +0000166 SkXfermode::kSrcIn_Mode,
167 SkXfermode::kDstIn_Mode,
168 SkXfermode::kSrcOut_Mode,
169 SkXfermode::kDstOut_Mode,
170 SkXfermode::kSrcATop_Mode,
171 SkXfermode::kDstATop_Mode,
Scroggo97c88c22011-05-11 14:05:25 +0000172 SkXfermode::kXor_Mode,
173 SkXfermode::kPlus_Mode,
reed@google.com8d3cd7a2013-01-30 21:36:11 +0000174 SkXfermode::kModulate_Mode,
reed@google.com9ac5e222011-05-05 20:05:10 +0000175 };
rmistry@google.comae933ce2012-08-23 18:19:56 +0000176
reed@google.com9ac5e222011-05-05 20:05:10 +0000177 static const SkColor gColors[] = {
178 0xFF000000,
179 0x80000000,
180 0xFF00FF00,
181 0x8000FF00,
182 0x00000000,
183 };
184
185 float scale = 1.5f;
186 SkPaint paint;
187 canvas->translate(N / 8, N / 8);
188
189 for (size_t y = 0; y < SK_ARRAY_COUNT(gColors); y++) {
190 for (size_t x = 0; x < SK_ARRAY_COUNT(gModes); x++) {
191 SkColorFilter* cf = SkColorFilter::CreateModeFilter(gColors[y], gModes[x]);
192 SkSafeUnref(paint.setColorFilter(cf));
193 canvas->drawBitmap(fBitmap, x * N * 1.25f, y * N * scale, &paint);
194 }
195 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000196
reed@google.com9ac5e222011-05-05 20:05:10 +0000197 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000198
reed@google.com9ac5e222011-05-05 20:05:10 +0000199private:
200 typedef SampleView INHERITED;
201};
202
203//////////////////////////////////////////////////////////////////////////////
204
205static SkView* MyFactory() { return new ColorFilterView; }
206static SkViewRegister reg(MyFactory);