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