• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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 "include/core/SkCanvas.h"
9 #include "include/core/SkColorFilter.h"
10 #include "include/core/SkImage.h"
11 #include "include/core/SkPath.h"
12 #include "include/core/SkRegion.h"
13 #include "include/core/SkShader.h"
14 #include "include/effects/SkGradientShader.h"
15 #include "samplecode/Sample.h"
16 #include "src/core/SkUtils.h"
17 #include "tools/Resources.h"
18 
19 const float gMat[] = {
20     .3f, .6f, .1f, 0, 0,
21     .3f, .6f, .1f, 0, 0,
22     .3f, .6f, .1f, 0, 0,
23       0,   0,   0, 1, 0,
24 };
25 
26 class MixerView : public Sample {
27     sk_sp<SkImage>          fImg;
28     sk_sp<SkColorFilter>    fCF0;
29     sk_sp<SkColorFilter>    fCF1;
30 
31     float fWeight = 0;
32     float fDW = 0.02f;
33 
34 public:
MixerView()35     MixerView() {}
36 
37 protected:
name()38     SkString name() override { return SkString("Mixer"); }
39 
dodraw(SkCanvas * canvas,sk_sp<SkColorFilter> cf0,sk_sp<SkColorFilter> cf1,float gap)40     void dodraw(SkCanvas* canvas, sk_sp<SkColorFilter> cf0, sk_sp<SkColorFilter> cf1, float gap) {
41         SkPaint paint;
42         paint.setColorFilter(cf0);
43         canvas->drawImage(fImg, 0, 0, &paint);
44 
45         paint.setColorFilter(SkColorFilters::Lerp(fWeight, cf0, cf1));
46         canvas->drawImage(fImg, fImg->width() + gap * fWeight, 0, &paint);
47 
48         paint.setColorFilter(cf1);
49         canvas->drawImage(fImg, 2*fImg->width() + gap, 0, &paint);
50     }
51 
onDrawContent(SkCanvas * canvas)52     void onDrawContent(SkCanvas* canvas) override {
53         if (!fImg) {
54             fImg = GetResourceAsImage("images/mandrill_256.png");
55             fCF0 = SkColorFilters::Matrix(gMat);
56             fCF1 = SkColorFilters::Blend(0xFF44CC88, SkBlendMode::kScreen);
57         }
58 
59         float gap = fImg->width() * 3;
60 
61         canvas->translate(10, 10);
62         dodraw(canvas, nullptr, fCF1, gap);
63         canvas->translate(0, fImg->height() + 10);
64         dodraw(canvas, fCF0, nullptr, gap);
65         canvas->translate(0, fImg->height() + 10);
66         dodraw(canvas, fCF0, fCF1, gap);
67 
68         fWeight += fDW;
69         if (fWeight > 1 || fWeight < 0) {
70             fDW = -fDW;
71         }
72     }
73 
onFindClickHandler(SkScalar x,SkScalar y,ModifierKey)74     virtual Click* onFindClickHandler(SkScalar x, SkScalar y, ModifierKey) override {
75         return fRect.contains(SkScalarRoundToInt(x),
76                               SkScalarRoundToInt(y)) ? new Click() : nullptr;
77     }
78 
onClick(Click * click)79     bool onClick(Click* click) override {
80         fRect.offset(click->fCurr.fX - click->fPrev.fX,
81                      click->fCurr.fY - click->fPrev.fY);
82         return true;
83     }
84 
85 private:
86     SkIRect fRect;
87 
88     typedef Sample INHERITED;
89 };
DEF_SAMPLE(return new MixerView;)90 DEF_SAMPLE( return new MixerView; )
91 
92 //////////////////////////////////////////////////////////////////////////////
93 
94 #include "include/core/SkMaskFilter.h"
95 #include "include/core/SkSurface.h"
96 
97 static sk_sp<SkShader> make_resource_shader(const char path[], int size) {
98     auto img = GetResourceAsImage(path);
99     if (!img) {
100         return nullptr;
101     }
102     SkRect src = SkRect::MakeIWH(img->width(), img->height());
103     SkRect dst = SkRect::MakeIWH(size, size);
104     SkMatrix m;
105     m.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
106     return img->makeShader(&m);
107 }
108 
109 class ShaderMixerView : public Sample {
110     sk_sp<SkShader>     fSH0;
111     sk_sp<SkShader>     fSH1;
112     sk_sp<SkSurface>    fSurface;
113     SkBlendMode         fMode = SkBlendMode::kClear;
114 
115     enum { SIZE = 256 };
116 
117     const SkRect fRect = SkRect::MakeXYWH(10, 10 + SIZE + 10, SIZE, SIZE);
118 
119 public:
ShaderMixerView()120     ShaderMixerView() {}
121 
onOnceBeforeDraw()122     void onOnceBeforeDraw() override {
123         fSH0 = make_resource_shader("images/mandrill_256.png", SIZE);
124         fSH1 = make_resource_shader("images/baby_tux.png", SIZE);
125     }
126 
127 protected:
name()128     SkString name() override { return SkString("ShaderMixer"); }
129 
onDrawContent(SkCanvas * canvas)130     void onDrawContent(SkCanvas* canvas) override {
131         if (!fSurface) {
132             fSurface = canvas->makeSurface(SkImageInfo::MakeN32Premul(SIZE, SIZE));
133         }
134 
135         SkPaint paint;
136         const SkRect r = SkRect::MakeIWH(SIZE, SIZE);
137 
138         canvas->translate(10, 10);
139 
140         canvas->save();
141         paint.setShader(fSH0); canvas->drawRect(r, paint);
142         canvas->translate(SIZE + 10.f, 0);
143         paint.setShader(fSH1); canvas->drawRect(r, paint);
144         canvas->restore();
145 
146         canvas->translate(0, SIZE + 10.f);
147 
148         auto sh = fSurface->makeImageSnapshot()->makeShader();
149 
150         canvas->save();
151         paint.setShader(sh); canvas->drawRect(r, paint);
152         canvas->translate(SIZE + 10.f, 0);
153         paint.setShader(SkShaders::Lerp(sh, fSH0, fSH1)); canvas->drawRect(r, paint);
154         canvas->restore();
155     }
156 
onFindClickHandler(SkScalar x,SkScalar y,ModifierKey)157     virtual Click* onFindClickHandler(SkScalar x, SkScalar y, ModifierKey) override {
158         fMode = (fMode == SkBlendMode::kSrcOver) ? SkBlendMode::kClear : SkBlendMode::kSrcOver;
159         return fRect.contains(SkScalarRoundToInt(x),
160                               SkScalarRoundToInt(y)) ? new Click() : nullptr;
161     }
162 
onClick(Click * click)163     bool onClick(Click* click) override {
164         SkPaint p;
165         p.setAntiAlias(true);
166         p.setColor(SK_ColorRED);
167         p.setBlendMode(fMode);
168         p.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 12));
169         SkScalar x = click->fCurr.fX - fRect.fLeft;
170         SkScalar y = click->fCurr.fY - fRect.fTop;
171         fSurface->getCanvas()->drawCircle(x, y, 10, p);
172         return true;
173     }
174 
175 private:
176     typedef Sample INHERITED;
177 };
178 DEF_SAMPLE( return new ShaderMixerView; )
179