• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
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  */
8 #include "sk_tool_utils.h"
9 #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 
inflate5To8(int x)17 static int inflate5To8(int x) {
18     return (x << 3) | (x >> 2);
19 }
20 
trunc5(int x)21 static int trunc5(int x) {
22     return x >> 3;
23 }
24 
25 #define SK_R16_BITS 5
26 
27 #ifdef SK_DEBUG
round5_slow(int x)28 static int round5_slow(int x) {
29     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 }
43 #endif
44 
round5_fast(int x)45 static int round5_fast(int x) {
46     int result = x + 3 - (x >> 5) + (x >> 7);
47     result >>= 3;
48 #ifdef SK_DEBUG
49     {
50         int r2 = round5_slow(x);
51         SkASSERT(r2 == result);
52     }
53 #endif
54     return result;
55 }
56 
test_5bits()57 static 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);
76 
77 
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 
createBitmap(int n)88 static SkBitmap createBitmap(int n) {
89     SkBitmap bitmap;
90     bitmap.allocN32Pixels(n, n);
91     bitmap.eraseColor(SK_ColorTRANSPARENT);
92 
93     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);
100 
101     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);
108 
109     return bitmap;
110 }
111 
112 class ColorFilterView : public SampleView {
113     SkBitmap fBitmap;
114     SkShader* fShader;
115     enum {
116         N = 64
117     };
118 public:
ColorFilterView()119     ColorFilterView() {
120         fBitmap = createBitmap(N);
121         fShader = sk_tool_utils::create_checkerboard_shader(
122                 0xFFCCCCCC, 0xFFFFFFFF, 12);
123 
124         if (false) { // avoid bit rot, suppress warning
125             test_5bits();
126         }
127     }
128 
~ColorFilterView()129     virtual ~ColorFilterView() {
130         fShader->unref();
131     }
132 
133 protected:
134     // overrides from SkEventSink
onQuery(SkEvent * evt)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 
onDrawBackground(SkCanvas * canvas)143     virtual void onDrawBackground(SkCanvas* canvas) {
144         SkPaint paint;
145         paint.setShader(fShader);
146         canvas->drawPaint(paint);
147     }
148 
onDrawContent(SkCanvas * canvas)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         }
159 
160         static const SkXfermode::Mode gModes[] = {
161             SkXfermode::kClear_Mode,
162             SkXfermode::kSrc_Mode,
163             SkXfermode::kDst_Mode,
164             SkXfermode::kSrcOver_Mode,
165             SkXfermode::kDstOver_Mode,
166             SkXfermode::kSrcIn_Mode,
167             SkXfermode::kDstIn_Mode,
168             SkXfermode::kSrcOut_Mode,
169             SkXfermode::kDstOut_Mode,
170             SkXfermode::kSrcATop_Mode,
171             SkXfermode::kDstATop_Mode,
172             SkXfermode::kXor_Mode,
173             SkXfermode::kPlus_Mode,
174             SkXfermode::kModulate_Mode,
175         };
176 
177         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         }
196 
197     }
198 
199 private:
200     typedef SampleView INHERITED;
201 };
202 
203 //////////////////////////////////////////////////////////////////////////////
204 
MyFactory()205 static SkView* MyFactory() { return new ColorFilterView; }
206 static SkViewRegister reg(MyFactory);
207