1/* 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 */ 7#include "sk_tool_utils.h" 8#include "SampleCode.h" 9#include "SkView.h" 10#include "SkCanvas.h" 11#include "SkColorFilter.h" 12#include "SkPaint.h" 13#include "SkShader.h" 14 15static int inflate5To8(int x) { 16 return (x << 3) | (x >> 2); 17} 18 19static int trunc5(int x) { 20 return x >> 3; 21} 22 23#define SK_R16_BITS 5 24 25#ifdef SK_DEBUG 26static 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#endif 42 43static int round5_fast(int x) { 44 int result = x + 3 - (x >> 5) + (x >> 7); 45 result >>= 3; 46#ifdef SK_DEBUG 47 { 48 int r2 = round5_slow(x); 49 SkASSERT(r2 == result); 50 } 51#endif 52 return result; 53} 54 55static void test_5bits() { 56 int e0 = 0; 57 int e1 = 0; 58 int e2 = 0; 59 int ae0 = 0; 60 int ae1 = 0; 61 int ae2 = 0; 62 for (int i = 0; i < 256; i++) { 63 int t0 = trunc5(i); 64 int t1 = round5_fast(i); 65 int t2 = trunc5(i); 66 int v0 = inflate5To8(t0); 67 int v1 = inflate5To8(t1); 68 int v2 = inflate5To8(t2); 69 int err0 = i - v0; 70 int err1 = i - v1; 71 int err2 = i - v2; 72 SkDebugf("--- %3d : trunc=%3d (%2d) round:%3d (%2d) \n"/*new:%d (%2d)\n"*/, i, 73 v0, err0, v1, err1, v2, err2); 74 75 76 e0 += err0; 77 e1 += err1; 78 e2 += err2; 79 ae0 += SkAbs32(err0); 80 ae1 += SkAbs32(err1); 81 ae2 += SkAbs32(err2); 82 } 83 SkDebugf("--- trunc: %d %d round: %d %d new: %d %d\n", e0, ae0, e1, ae1, e2, ae2); 84} 85 86static SkBitmap createBitmap(int n) { 87 SkBitmap bitmap; 88 bitmap.allocN32Pixels(n, n); 89 bitmap.eraseColor(SK_ColorTRANSPARENT); 90 91 SkCanvas canvas(bitmap); 92 SkRect r; 93 r.set(0, 0, SkIntToScalar(n), SkIntToScalar(n)); 94 r.inset(SK_Scalar1, SK_Scalar1); 95 96 SkPaint paint; 97 paint.setAntiAlias(true); 98 99 paint.setColor(SK_ColorRED); 100 canvas.drawOval(r, paint); 101 102 r.inset(SK_Scalar1*n/4, SK_Scalar1*n/4); 103 paint.setBlendMode(SkBlendMode::kSrc); 104 paint.setColor(0x800000FF); 105 canvas.drawOval(r, paint); 106 107 return bitmap; 108} 109 110class ColorFilterView : public SampleView { 111 SkBitmap fBitmap; 112 sk_sp<SkShader> fShader; 113 enum { 114 N = 64 115 }; 116public: 117 ColorFilterView() { 118 fBitmap = createBitmap(N); 119 fShader = sk_tool_utils::create_checkerboard_shader( 120 0xFFCCCCCC, 0xFFFFFFFF, 12); 121 122 if (false) { // avoid bit rot, suppress warning 123 test_5bits(); 124 } 125 } 126 127protected: 128 // overrides from SkEventSink 129 virtual bool onQuery(SkEvent* evt) { 130 if (SampleCode::TitleQ(*evt)) { 131 SampleCode::TitleR(evt, "ColorFilter"); 132 return true; 133 } 134 return this->INHERITED::onQuery(evt); 135 } 136 137 virtual void onDrawBackground(SkCanvas* canvas) { 138 SkPaint paint; 139 paint.setShader(fShader); 140 canvas->drawPaint(paint); 141 } 142 143 virtual void onDrawContent(SkCanvas* canvas) { 144 if (false) { 145 SkPaint p; 146 p.setAntiAlias(true); 147 SkRect r = { 20.4f, 10, 20.6f, 20 }; 148 canvas->drawRect(r, p); 149 r.set(30.9f, 10, 31.1f, 20); 150 canvas->drawRect(r, p); 151 return; 152 } 153 154 static const SkBlendMode gModes[] = { 155 SkBlendMode::kClear, 156 SkBlendMode::kSrc, 157 SkBlendMode::kDst, 158 SkBlendMode::kSrcOver, 159 SkBlendMode::kDstOver, 160 SkBlendMode::kSrcIn, 161 SkBlendMode::kDstIn, 162 SkBlendMode::kSrcOut, 163 SkBlendMode::kDstOut, 164 SkBlendMode::kSrcATop, 165 SkBlendMode::kDstATop, 166 SkBlendMode::kXor, 167 SkBlendMode::kPlus, 168 SkBlendMode::kModulate, 169 }; 170 171 static const SkColor gColors[] = { 172 0xFF000000, 173 0x80000000, 174 0xFF00FF00, 175 0x8000FF00, 176 0x00000000, 177 }; 178 179 float scale = 1.5f; 180 SkPaint paint; 181 canvas->translate(N / 8, N / 8); 182 183 for (size_t y = 0; y < SK_ARRAY_COUNT(gColors); y++) { 184 for (size_t x = 0; x < SK_ARRAY_COUNT(gModes); x++) { 185 paint.setColorFilter(SkColorFilter::MakeModeFilter(gColors[y], gModes[x])); 186 canvas->drawBitmap(fBitmap, x * N * 1.25f, y * N * scale, &paint); 187 } 188 } 189 190 } 191 192private: 193 typedef SampleView INHERITED; 194}; 195 196////////////////////////////////////////////////////////////////////////////// 197 198static SkView* MyFactory() { return new ColorFilterView; } 199static SkViewRegister reg(MyFactory); 200