/* * 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 "SkBlurMaskFilter.h" #include "SkCamera.h" #include "SkColorFilter.h" #include "SkColorPriv.h" #include "SkDevice.h" #include "SkGradientShader.h" #include "SkImageDecoder.h" #include "SkInterpolator.h" #include "SkMaskFilter.h" #include "SkPath.h" #include "SkRegion.h" #include "SkShader.h" #include "SkTime.h" #include "SkTypeface.h" #include "SkUtils.h" #include "SkKey.h" #include "SkXfermode.h" #include "SkDrawFilter.h" static void make_paint(SkPaint* paint) { SkColor colors[] = { 0, SK_ColorWHITE }; SkPoint pts[] = { { 0, 0 }, { 0, SK_Scalar1*20 } }; SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kClamp_TileMode); paint->setShader(s)->unref(); paint->setXfermodeMode(SkXfermode::kDstIn_Mode); } static void dump_layers(const char label[], SkCanvas* canvas) { SkDebugf("Dump Layers(%s)\n", label); SkCanvas::LayerIter iter(canvas, true); int index = 0; while (!iter.done()) { const SkBitmap& bm = iter.device()->accessBitmap(false); const SkIRect& clip = iter.clip().getBounds(); SkDebugf("Layer[%d] bitmap [%d %d] X=%d Y=%d clip=[%d %d %d %d] alpha=%d\n", index++, bm.width(), bm.height(), iter.x(), iter.y(), clip.fLeft, clip.fTop, clip.fRight, clip.fBottom, iter.paint().getAlpha()); iter.next(); } } // test drawing with strips of fading gradient above and below static void test_fade(SkCanvas* canvas) { SkAutoCanvasRestore ar(canvas, true); SkRect r; SkPaint p; p.setAlpha(0x88); SkAutoCanvasRestore(canvas, false); // create the layers r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100)); canvas->clipRect(r); r.fBottom = SkIntToScalar(20); canvas->saveLayer(&r, NULL, (SkCanvas::SaveFlags)(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag)); r.fTop = SkIntToScalar(80); r.fBottom = SkIntToScalar(100); canvas->saveLayer(&r, NULL, (SkCanvas::SaveFlags)(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag)); // now draw the "content" if (true) { r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100)); canvas->saveLayerAlpha(&r, 0x80); SkPaint p; p.setColor(SK_ColorRED); p.setAntiAlias(true); canvas->drawOval(r, p); dump_layers("inside layer alpha", canvas); canvas->restore(); } else { r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100)); SkPaint p; p.setColor(SK_ColorRED); p.setAntiAlias(true); canvas->drawOval(r, p); } // return; dump_layers("outside layer alpha", canvas); // now apply an effect SkPaint paint; make_paint(&paint); r.set(0, 0, SkIntToScalar(100), SkIntToScalar(20)); // SkDebugf("--------- draw top grad\n"); canvas->drawRect(r, paint); SkMatrix m; SkShader* s = paint.getShader(); m.setScale(SK_Scalar1, -SK_Scalar1); m.postTranslate(0, SkIntToScalar(100)); s->setLocalMatrix(m); r.fTop = SkIntToScalar(80); r.fBottom = SkIntToScalar(100); // SkDebugf("--------- draw bot grad\n"); canvas->drawRect(r, paint); } class RedFilter : public SkDrawFilter { public: virtual bool filter(SkCanvas*, SkPaint* p, SkDrawFilter::Type) { fColor = p->getColor(); if (fColor == SK_ColorRED) { p->setColor(SK_ColorGREEN); } return true; } virtual void restore(SkCanvas*, SkPaint* p, SkDrawFilter::Type) { p->setColor(fColor); } private: SkColor fColor; }; class LayersView : public SkView { public: LayersView() {} protected: // overrides from SkEventSink virtual bool onQuery(SkEvent* evt) { if (SampleCode::TitleQ(*evt)) { SampleCode::TitleR(evt, "Layers"); return true; } return this->INHERITED::onQuery(evt); } void drawBG(SkCanvas* canvas) { canvas->drawColor(SK_ColorGRAY); } virtual void onDraw(SkCanvas* canvas) { this->drawBG(canvas); if (true) { SkRect r; r.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(220), SkIntToScalar(120)); SkPaint p; canvas->saveLayer(&r, &p); canvas->drawColor(0xFFFF0000); p.setAlpha(0); // or 0 p.setXfermodeMode(SkXfermode::kSrc_Mode); canvas->drawOval(r, p); canvas->restore(); return; } if (false) { SkRect r; r.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(220), SkIntToScalar(120)); SkPaint p; p.setAlpha(0x88); p.setAntiAlias(true); if (true) { canvas->saveLayer(&r, &p); p.setColor(0xFFFF0000); canvas->drawOval(r, p); canvas->restore(); } p.setColor(0xFF0000FF); r.offset(SkIntToScalar(20), SkIntToScalar(50)); canvas->drawOval(r, p); } if (false) { SkPaint p; p.setAlpha(0x88); p.setAntiAlias(true); canvas->translate(SkIntToScalar(300), 0); SkRect r; r.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(220), SkIntToScalar(60)); canvas->saveLayer(&r, &p, (SkCanvas::SaveFlags)(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag)); // canvas->clipRect(r, SkRegion::kDifference_Op); // canvas->clipRect(r, SkRegion::kIntersect_Op); r.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(220), SkIntToScalar(120)); p.setColor(SK_ColorBLUE); canvas->drawOval(r, p); canvas->restore(); return; } //canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); test_fade(canvas); return; // canvas->setDrawFilter(new RedFilter)->unref(); SkRect r; SkPaint p; canvas->translate(SkIntToScalar(220), SkIntToScalar(20)); p.setAntiAlias(true); r.set(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(220), SkIntToScalar(120)); p.setColor(SK_ColorBLUE); // p.setMaskFilter(SkBlurMaskFilter::Create(SkIntToScalar(8), SkBlurMaskFilter::kNormal_BlurStyle))->unref(); canvas->drawRect(r, p); p.setMaskFilter(NULL); SkRect bounds = r; bounds.fBottom = bounds.centerY(); canvas->saveLayer(&bounds, NULL, SkCanvas::kARGB_NoClipLayer_SaveFlag); p.setColor(SK_ColorRED); canvas->drawOval(r, p); p.setAlpha(0x80); p.setXfermodeMode(SkXfermode::kDstIn_Mode); canvas->drawRect(bounds, p); canvas->restore(); } virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) { this->inval(NULL); return this->INHERITED::onFindClickHandler(x, y); } virtual bool onClick(Click* click) { return this->INHERITED::onClick(click); } virtual bool handleKey(SkKey key) { this->inval(NULL); return true; } private: typedef SkView INHERITED; }; ////////////////////////////////////////////////////////////////////////////// static SkView* MyFactory() { return new LayersView; } static SkViewRegister reg(MyFactory);