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 17 static int inflate5To8(int x) { 18 return (x << 3) | (x >> 2); 19 } 20 21 static int trunc5(int x) { 22 return x >> 3; 23 } 24 25 #define SK_R16_BITS 5 26 27 #ifdef SK_DEBUG 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 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 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 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: 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 129 virtual ~ColorFilterView() { 130 fShader->unref(); 131 } 132 133 protected: 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 } 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 205 static SkView* MyFactory() { return new ColorFilterView; } 206 static SkViewRegister reg(MyFactory); 207