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 "SampleCode.h" 9 #include "SkView.h" 10 #include "SkCanvas.h" 11 #include "SkColorFilter.h" 12 #include "SkDevice.h" 13 #include "SkPaint.h" 14 #include "SkShader.h" 15 16 static int inflate5To8(int x) { 17 return (x << 3) | (x >> 2); 18 } 19 20 static int trunc5(int x) { 21 return x >> 3; 22 } 23 24 #define SK_R16_BITS 5 25 26 static int round5_slow(int x) { 27 int orig = x & 7; 28 int fake = x >> 5; 29 int trunc = x >> 3; 30 31 int diff = fake - orig; 32 33 int bias = 0; 34 if (diff > 4) { 35 bias = -1; 36 } else if (diff < -4) { 37 bias = 1; 38 } 39 return trunc + bias; 40 } 41 42 static int round5_fast(int x) { 43 int result = x + 3 - (x >> 5) + (x >> 7); 44 result >>= 3; 45 46 { 47 int r2 = round5_slow(x); 48 SkASSERT(r2 == result); 49 } 50 return result; 51 } 52 53 static void test_5bits() { 54 int e0 = 0; 55 int e1 = 0; 56 int e2 = 0; 57 int ae0 = 0; 58 int ae1 = 0; 59 int ae2 = 0; 60 for (int i = 0; i < 256; i++) { 61 int t0 = trunc5(i); 62 int t1 = round5_fast(i); 63 int t2 = trunc5(i); 64 int v0 = inflate5To8(t0); 65 int v1 = inflate5To8(t1); 66 int v2 = inflate5To8(t2); 67 int err0 = i - v0; 68 int err1 = i - v1; 69 int err2 = i - v2; 70 SkDebugf("--- %3d : trunc=%3d (%2d) round:%3d (%2d) \n"/*new:%d (%2d)\n"*/, i, 71 v0, err0, v1, err1, v2, err2); 72 73 74 e0 += err0; 75 e1 += err1; 76 e2 += err2; 77 ae0 += SkAbs32(err0); 78 ae1 += SkAbs32(err1); 79 ae2 += SkAbs32(err2); 80 } 81 SkDebugf("--- trunc: %d %d round: %d %d new: %d %d\n", e0, ae0, e1, ae1, e2, ae2); 82 } 83 84 static SkShader* createChecker() { 85 SkBitmap bm; 86 bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); 87 bm.allocPixels(); 88 bm.lockPixels(); 89 *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = SkPreMultiplyColor(0xFFFFFFFF); 90 *bm.getAddr32(0, 1) = *bm.getAddr32(1, 0) = SkPreMultiplyColor(0xFFCCCCCC); 91 SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode, 92 SkShader::kRepeat_TileMode); 93 94 SkMatrix m; 95 m.setScale(12, 12); 96 s->setLocalMatrix(m); 97 return s; 98 } 99 100 static SkBitmap createBitmap(int n) { 101 SkBitmap bitmap; 102 bitmap.setConfig(SkBitmap::kARGB_8888_Config, n, n); 103 bitmap.allocPixels(); 104 bitmap.eraseColor(0); 105 106 SkCanvas canvas(bitmap); 107 SkRect r; 108 r.set(0, 0, SkIntToScalar(n), SkIntToScalar(n)); 109 r.inset(SK_Scalar1, SK_Scalar1); 110 111 SkPaint paint; 112 paint.setAntiAlias(true); 113 114 paint.setColor(SK_ColorRED); 115 canvas.drawOval(r, paint); 116 117 r.inset(SK_Scalar1*n/4, SK_Scalar1*n/4); 118 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 119 paint.setColor(0x800000FF); 120 canvas.drawOval(r, paint); 121 122 return bitmap; 123 } 124 125 class ColorFilterView : public SampleView { 126 SkBitmap fBitmap; 127 SkShader* fShader; 128 enum { 129 N = 64 130 }; 131 public: 132 ColorFilterView() { 133 fBitmap = createBitmap(N); 134 fShader = createChecker(); 135 136 // test_5bits(); 137 } 138 139 virtual ~ColorFilterView() { 140 fShader->unref(); 141 } 142 143 protected: 144 // overrides from SkEventSink 145 virtual bool onQuery(SkEvent* evt) { 146 if (SampleCode::TitleQ(*evt)) { 147 SampleCode::TitleR(evt, "ColorFilter"); 148 return true; 149 } 150 return this->INHERITED::onQuery(evt); 151 } 152 153 virtual void onDrawBackground(SkCanvas* canvas) { 154 SkPaint paint; 155 paint.setShader(fShader); 156 canvas->drawPaint(paint); 157 } 158 159 virtual void onDrawContent(SkCanvas* canvas) { 160 if (false) { 161 SkPaint p; 162 p.setAntiAlias(true); 163 SkRect r = { 20.4f, 10, 20.6f, 20 }; 164 canvas->drawRect(r, p); 165 r.set(30.9f, 10, 31.1f, 20); 166 canvas->drawRect(r, p); 167 return; 168 } 169 170 static const SkXfermode::Mode gModes[] = { 171 SkXfermode::kClear_Mode, 172 SkXfermode::kSrc_Mode, 173 SkXfermode::kDst_Mode, 174 SkXfermode::kSrcOver_Mode, 175 SkXfermode::kDstOver_Mode, 176 SkXfermode::kSrcIn_Mode, 177 SkXfermode::kDstIn_Mode, 178 SkXfermode::kSrcOut_Mode, 179 SkXfermode::kDstOut_Mode, 180 SkXfermode::kSrcATop_Mode, 181 SkXfermode::kDstATop_Mode, 182 SkXfermode::kXor_Mode, 183 SkXfermode::kPlus_Mode, 184 SkXfermode::kMultiply_Mode, 185 }; 186 187 static const SkColor gColors[] = { 188 0xFF000000, 189 0x80000000, 190 0xFF00FF00, 191 0x8000FF00, 192 0x00000000, 193 }; 194 195 float scale = 1.5f; 196 SkPaint paint; 197 canvas->translate(N / 8, N / 8); 198 199 for (size_t y = 0; y < SK_ARRAY_COUNT(gColors); y++) { 200 for (size_t x = 0; x < SK_ARRAY_COUNT(gModes); x++) { 201 SkColorFilter* cf = SkColorFilter::CreateModeFilter(gColors[y], gModes[x]); 202 SkSafeUnref(paint.setColorFilter(cf)); 203 canvas->drawBitmap(fBitmap, x * N * 1.25f, y * N * scale, &paint); 204 } 205 } 206 207 } 208 209 private: 210 typedef SampleView INHERITED; 211 }; 212 213 ////////////////////////////////////////////////////////////////////////////// 214 215 static SkView* MyFactory() { return new ColorFilterView; } 216 static SkViewRegister reg(MyFactory); 217 218