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 "SkBlurMaskFilter.h" 12#include "SkCamera.h" 13#include "SkColorFilter.h" 14#include "SkColorPriv.h" 15#include "SkDevice.h" 16#include "SkGradientShader.h" 17#include "SkImageDecoder.h" 18#include "SkInterpolator.h" 19#include "SkMaskFilter.h" 20#include "SkPath.h" 21#include "SkRegion.h" 22#include "SkShader.h" 23#include "SkTime.h" 24#include "SkTypeface.h" 25#include "SkUtils.h" 26#include "SkKey.h" 27#include "SkXfermode.h" 28#include "SkDrawFilter.h" 29 30static void make_paint(SkPaint* paint, const SkMatrix& localMatrix) { 31 SkColor colors[] = { 0, SK_ColorWHITE }; 32 SkPoint pts[] = { { 0, 0 }, { 0, SK_Scalar1*20 } }; 33 SkShader* s = SkGradientShader::CreateLinear(pts, colors, nullptr, 2, SkShader::kClamp_TileMode, 34 0, &localMatrix); 35 36 paint->setShader(s)->unref(); 37 paint->setXfermodeMode(SkXfermode::kDstIn_Mode); 38} 39 40static void dump_layers(const char label[], SkCanvas* canvas) { 41 SkDebugf("Dump Layers(%s)\n", label); 42 43 SkCanvas::LayerIter iter(canvas, true); 44 int index = 0; 45 while (!iter.done()) { 46 SkImageInfo info = iter.device()->imageInfo(); 47 const SkIRect& clip = iter.clip().getBounds(); 48 SkDebugf("Layer[%d] bitmap [%d %d] X=%d Y=%d clip=[%d %d %d %d] alpha=%d\n", index++, 49 info.width(), info.height(), iter.x(), iter.y(), 50 clip.fLeft, clip.fTop, clip.fRight, clip.fBottom, 51 iter.paint().getAlpha()); 52 iter.next(); 53 } 54} 55 56// test drawing with strips of fading gradient above and below 57static void test_fade(SkCanvas* canvas) { 58 SkAutoCanvasRestore ar(canvas, true); 59 60 SkRect r; 61 62 SkPaint p; 63 p.setAlpha(0x88); 64 65 SkAutoCanvasRestore ar2(canvas, false); 66 67 // create the layers 68 69 r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100)); 70 canvas->clipRect(r); 71 72 r.fBottom = SkIntToScalar(20); 73 canvas->saveLayer(&r, nullptr); 74 75 r.fTop = SkIntToScalar(80); 76 r.fBottom = SkIntToScalar(100); 77 canvas->saveLayer(&r, nullptr); 78 79 // now draw the "content" 80 81 if (true) { 82 r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100)); 83 84 canvas->saveLayerAlpha(&r, 0x80); 85 86 SkPaint p; 87 p.setColor(SK_ColorRED); 88 p.setAntiAlias(true); 89 canvas->drawOval(r, p); 90 91 dump_layers("inside layer alpha", canvas); 92 93 canvas->restore(); 94 } else { 95 r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100)); 96 97 SkPaint p; 98 p.setColor(SK_ColorRED); 99 p.setAntiAlias(true); 100 canvas->drawOval(r, p); 101 } 102 103// return; 104 105 dump_layers("outside layer alpha", canvas); 106 107 // now apply an effect 108 SkMatrix m; 109 m.setScale(SK_Scalar1, -SK_Scalar1); 110 m.postTranslate(0, SkIntToScalar(100)); 111 112 SkPaint paint; 113 make_paint(&paint, m); 114 r.set(0, 0, SkIntToScalar(100), SkIntToScalar(20)); 115// SkDebugf("--------- draw top grad\n"); 116 canvas->drawRect(r, paint); 117 118 r.fTop = SkIntToScalar(80); 119 r.fBottom = SkIntToScalar(100); 120// SkDebugf("--------- draw bot grad\n"); 121 canvas->drawRect(r, paint); 122} 123 124class RedFilter : public SkDrawFilter { 125public: 126 bool filter(SkPaint* p, SkDrawFilter::Type) override { 127 fColor = p->getColor(); 128 if (fColor == SK_ColorRED) { 129 p->setColor(SK_ColorGREEN); 130 } 131 return true; 132 } 133 134private: 135 SkColor fColor; 136}; 137 138class LayersView : public SkView { 139public: 140 LayersView() {} 141 142protected: 143 // overrides from SkEventSink 144 bool onQuery(SkEvent* evt) override { 145 if (SampleCode::TitleQ(*evt)) { 146 SampleCode::TitleR(evt, "Layers"); 147 return true; 148 } 149 return this->INHERITED::onQuery(evt); 150 } 151 152 void drawBG(SkCanvas* canvas) { 153 canvas->drawColor(SK_ColorGRAY); 154 } 155 156 void onDraw(SkCanvas* canvas) override { 157 this->drawBG(canvas); 158 159 if (true) { 160 SkRect r; 161 r.set(SkIntToScalar(0), SkIntToScalar(0), 162 SkIntToScalar(220), SkIntToScalar(120)); 163 SkPaint p; 164 canvas->saveLayer(&r, &p); 165 canvas->drawColor(0xFFFF0000); 166 p.setAlpha(0); // or 0 167 p.setXfermodeMode(SkXfermode::kSrc_Mode); 168 canvas->drawOval(r, p); 169 canvas->restore(); 170 return; 171 } 172 173 if (false) { 174 SkRect r; 175 r.set(SkIntToScalar(0), SkIntToScalar(0), 176 SkIntToScalar(220), SkIntToScalar(120)); 177 SkPaint p; 178 p.setAlpha(0x88); 179 p.setAntiAlias(true); 180 181 if (true) { 182 canvas->saveLayer(&r, &p); 183 p.setColor(0xFFFF0000); 184 canvas->drawOval(r, p); 185 canvas->restore(); 186 } 187 188 p.setColor(0xFF0000FF); 189 r.offset(SkIntToScalar(20), SkIntToScalar(50)); 190 canvas->drawOval(r, p); 191 } 192 193 if (false) { 194 SkPaint p; 195 p.setAlpha(0x88); 196 p.setAntiAlias(true); 197 198 canvas->translate(SkIntToScalar(300), 0); 199 200 SkRect r; 201 r.set(SkIntToScalar(0), SkIntToScalar(0), 202 SkIntToScalar(220), SkIntToScalar(60)); 203 204 canvas->saveLayer(&r, &p); 205 206 r.set(SkIntToScalar(0), SkIntToScalar(0), 207 SkIntToScalar(220), SkIntToScalar(120)); 208 p.setColor(SK_ColorBLUE); 209 canvas->drawOval(r, p); 210 canvas->restore(); 211 return; 212 } 213 214 test_fade(canvas); 215 } 216 217 SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override { 218 this->inval(nullptr); 219 220 return this->INHERITED::onFindClickHandler(x, y, modi); 221 } 222 223 bool onClick(Click* click) override { 224 return this->INHERITED::onClick(click); 225 } 226 227 virtual bool handleKey(SkKey) { 228 this->inval(nullptr); 229 return true; 230 } 231 232private: 233 typedef SkView INHERITED; 234}; 235DEF_SAMPLE( return new LayersView; ) 236 237////////////////////////////////////////////////////////////////////////////// 238 239#include "SkBlurImageFilter.h" 240#include "SkMatrixConvolutionImageFilter.h" 241#include "SkMorphologyImageFilter.h" 242 243#include "Resources.h" 244#include "SkAnimTimer.h" 245 246class BackdropView : public SampleView { 247 SkPoint fCenter; 248 SkScalar fAngle; 249 SkAutoTUnref<SkImage> fImage; 250 SkAutoTUnref<SkImageFilter> fFilter; 251public: 252 BackdropView() { 253 fCenter.set(200, 150); 254 fAngle = 0; 255 fImage.reset(GetResourceAsImage("mandrill_512.png")); 256 fFilter.reset(SkDilateImageFilter::Create(8, 8)); 257 } 258 259protected: 260 // overrides from SkEventSink 261 bool onQuery(SkEvent* evt) override { 262 if (SampleCode::TitleQ(*evt)) { 263 SampleCode::TitleR(evt, "Backdrop"); 264 return true; 265 } 266 return this->INHERITED::onQuery(evt); 267 } 268 269 void onDrawContent(SkCanvas* canvas) override { 270 canvas->drawImage(fImage, 0, 0, nullptr); 271 272 const SkScalar w = 250; 273 const SkScalar h = 150; 274 SkPath path; 275 path.addOval(SkRect::MakeXYWH(-w/2, -h/2, w, h)); 276 SkMatrix m; 277 m.setRotate(fAngle); 278 m.postTranslate(fCenter.x(), fCenter.y()); 279 path.transform(m); 280 281 canvas->clipPath(path, SkRegion::kIntersect_Op, true); 282 const SkRect bounds = path.getBounds(); 283 284 SkPaint paint; 285 paint.setAlpha(0xCC); 286 canvas->saveLayer({ &bounds, &paint, fFilter, 0 }); 287 288 canvas->restore(); 289 } 290 291 bool onAnimate(const SkAnimTimer& timer) override { 292 fAngle = SkDoubleToScalar(fmod(timer.secs() * 360 / 5, 360)); 293 return true; 294 } 295 296 SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override { 297 this->inval(nullptr); 298 return new Click(this); 299 } 300 301 bool onClick(Click* click) override { 302 this->inval(nullptr); 303 fCenter = click->fCurr; 304 return this->INHERITED::onClick(click); 305 } 306 307private: 308 typedef SampleView INHERITED; 309}; 310DEF_SAMPLE( return new BackdropView; ) 311 312