/* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SampleCode.h" #include "SkView.h" #include "SkCanvas.h" #include "SkColorFilter.h" #include "SkDevice.h" #include "SkPaint.h" #include "SkShader.h" static int inflate5To8(int x) { return (x << 3) | (x >> 2); } static int trunc5(int x) { return x >> 3; } #define SK_R16_BITS 5 static int round5_slow(int x) { int orig = x & 7; int fake = x >> 5; int trunc = x >> 3; int diff = fake - orig; int bias = 0; if (diff > 4) { bias = -1; } else if (diff < -4) { bias = 1; } return trunc + bias; } static int round5_fast(int x) { int result = x + 3 - (x >> 5) + (x >> 7); result >>= 3; { int r2 = round5_slow(x); SkASSERT(r2 == result); } return result; } static void test_5bits() { int e0 = 0; int e1 = 0; int e2 = 0; int ae0 = 0; int ae1 = 0; int ae2 = 0; for (int i = 0; i < 256; i++) { int t0 = trunc5(i); int t1 = round5_fast(i); int t2 = trunc5(i); int v0 = inflate5To8(t0); int v1 = inflate5To8(t1); int v2 = inflate5To8(t2); int err0 = i - v0; int err1 = i - v1; int err2 = i - v2; SkDebugf("--- %3d : trunc=%3d (%2d) round:%3d (%2d) \n"/*new:%d (%2d)\n"*/, i, v0, err0, v1, err1, v2, err2); e0 += err0; e1 += err1; e2 += err2; ae0 += SkAbs32(err0); ae1 += SkAbs32(err1); ae2 += SkAbs32(err2); } SkDebugf("--- trunc: %d %d round: %d %d new: %d %d\n", e0, ae0, e1, ae1, e2, ae2); } static SkShader* createChecker() { SkBitmap bm; bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); bm.allocPixels(); bm.lockPixels(); *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = SkPreMultiplyColor(0xFFFFFFFF); *bm.getAddr32(0, 1) = *bm.getAddr32(1, 0) = SkPreMultiplyColor(0xFFCCCCCC); SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); SkMatrix m; m.setScale(12, 12); s->setLocalMatrix(m); return s; } static SkBitmap createBitmap(int n) { SkBitmap bitmap; bitmap.setConfig(SkBitmap::kARGB_8888_Config, n, n); bitmap.allocPixels(); bitmap.eraseColor(0); SkCanvas canvas(bitmap); SkRect r; r.set(0, 0, SkIntToScalar(n), SkIntToScalar(n)); r.inset(SK_Scalar1, SK_Scalar1); SkPaint paint; paint.setAntiAlias(true); paint.setColor(SK_ColorRED); canvas.drawOval(r, paint); r.inset(SK_Scalar1*n/4, SK_Scalar1*n/4); paint.setXfermodeMode(SkXfermode::kSrc_Mode); paint.setColor(0x800000FF); canvas.drawOval(r, paint); return bitmap; } class ColorFilterView : public SampleView { SkBitmap fBitmap; SkShader* fShader; enum { N = 64 }; public: ColorFilterView() { fBitmap = createBitmap(N); fShader = createChecker(); // test_5bits(); } virtual ~ColorFilterView() { fShader->unref(); } protected: // overrides from SkEventSink virtual bool onQuery(SkEvent* evt) { if (SampleCode::TitleQ(*evt)) { SampleCode::TitleR(evt, "ColorFilter"); return true; } return this->INHERITED::onQuery(evt); } virtual void onDrawBackground(SkCanvas* canvas) { SkPaint paint; paint.setShader(fShader); canvas->drawPaint(paint); } virtual void onDrawContent(SkCanvas* canvas) { if (false) { SkPaint p; p.setAntiAlias(true); SkRect r = { 20.4f, 10, 20.6f, 20 }; canvas->drawRect(r, p); r.set(30.9f, 10, 31.1f, 20); canvas->drawRect(r, p); return; } static const SkXfermode::Mode gModes[] = { SkXfermode::kClear_Mode, SkXfermode::kSrc_Mode, SkXfermode::kDst_Mode, SkXfermode::kSrcOver_Mode, SkXfermode::kDstOver_Mode, SkXfermode::kSrcIn_Mode, SkXfermode::kDstIn_Mode, SkXfermode::kSrcOut_Mode, SkXfermode::kDstOut_Mode, SkXfermode::kSrcATop_Mode, SkXfermode::kDstATop_Mode, SkXfermode::kXor_Mode, SkXfermode::kPlus_Mode, SkXfermode::kMultiply_Mode, }; static const SkColor gColors[] = { 0xFF000000, 0x80000000, 0xFF00FF00, 0x8000FF00, 0x00000000, }; float scale = 1.5f; SkPaint paint; canvas->translate(N / 8, N / 8); for (size_t y = 0; y < SK_ARRAY_COUNT(gColors); y++) { for (size_t x = 0; x < SK_ARRAY_COUNT(gModes); x++) { SkColorFilter* cf = SkColorFilter::CreateModeFilter(gColors[y], gModes[x]); SkSafeUnref(paint.setColorFilter(cf)); canvas->drawBitmap(fBitmap, x * N * 1.25f, y * N * scale, &paint); } } } private: typedef SampleView INHERITED; }; ////////////////////////////////////////////////////////////////////////////// static SkView* MyFactory() { return new ColorFilterView; } static SkViewRegister reg(MyFactory);