blob: 7a8540bc33a24e508f1688224693f9286a47f65c [file] [log] [blame]
scroggo@google.com32f20eb2012-06-29 17:28:50 +00001/*
2 * Copyright 2012 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 "gm.h"
9
10#include "SkCanvas.h"
scroggo@google.com32f20eb2012-06-29 17:28:50 +000011#include "SkGradientShader.h"
12#include "SkGraphics.h"
13#include "SkShader.h"
14#include "SkString.h"
scroggo@google.com32f20eb2012-06-29 17:28:50 +000015
Mike Reed7d954ad2016-10-28 15:42:34 -040016static sk_sp<SkShader> make_shader(SkBlendMode mode) {
commit-bot@chromium.org58e42872014-05-05 18:23:54 +000017 SkPoint pts[2];
18 SkColor colors[2];
skia.committer@gmail.comedda70e2014-05-06 03:06:53 +000019
commit-bot@chromium.org58e42872014-05-05 18:23:54 +000020 pts[0].set(0, 0);
21 pts[1].set(SkIntToScalar(100), 0);
22 colors[0] = SK_ColorRED;
23 colors[1] = SK_ColorBLUE;
reed2ad1aa62016-03-09 09:50:50 -080024 auto shaderA = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkShader::kClamp_TileMode);
skia.committer@gmail.comedda70e2014-05-06 03:06:53 +000025
commit-bot@chromium.org58e42872014-05-05 18:23:54 +000026 pts[0].set(0, 0);
27 pts[1].set(0, SkIntToScalar(100));
28 colors[0] = SK_ColorBLACK;
29 colors[1] = SkColorSetARGB(0x80, 0, 0, 0);
reed2ad1aa62016-03-09 09:50:50 -080030 auto shaderB = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkShader::kClamp_TileMode);
skia.committer@gmail.comedda70e2014-05-06 03:06:53 +000031
Mike Reed7d954ad2016-10-28 15:42:34 -040032 return SkShader::MakeComposeShader(std::move(shaderA), std::move(shaderB), mode);
commit-bot@chromium.org58e42872014-05-05 18:23:54 +000033}
34
commit-bot@chromium.orgec7d6732014-05-05 16:19:08 +000035class ComposeShaderGM : public skiagm::GM {
scroggo@google.com32f20eb2012-06-29 17:28:50 +000036public:
commit-bot@chromium.orgec7d6732014-05-05 16:19:08 +000037 ComposeShaderGM() {
Mike Reed7d954ad2016-10-28 15:42:34 -040038 fShader = make_shader(SkBlendMode::kDstIn);
scroggo@google.com32f20eb2012-06-29 17:28:50 +000039 }
40
scroggo@google.com32f20eb2012-06-29 17:28:50 +000041protected:
mtklein36352bf2015-03-25 18:17:31 -070042 SkString onShortName() override {
scroggo@google.com32f20eb2012-06-29 17:28:50 +000043 return SkString("composeshader");
44 }
45
mtklein36352bf2015-03-25 18:17:31 -070046 SkISize onISize() override {
commit-bot@chromium.orgec7d6732014-05-05 16:19:08 +000047 return SkISize::Make(120, 120);
scroggo@google.com32f20eb2012-06-29 17:28:50 +000048 }
49
mtklein36352bf2015-03-25 18:17:31 -070050 void onDraw(SkCanvas* canvas) override {
scroggo@google.com32f20eb2012-06-29 17:28:50 +000051 SkPaint paint;
scroggo@google.com32f20eb2012-06-29 17:28:50 +000052 paint.setColor(SK_ColorGREEN);
53 canvas->drawRectCoords(0, 0, SkIntToScalar(100), SkIntToScalar(100), paint);
54 paint.setShader(fShader);
55 canvas->drawRectCoords(0, 0, SkIntToScalar(100), SkIntToScalar(100), paint);
56 }
57
commit-bot@chromium.orgec7d6732014-05-05 16:19:08 +000058protected:
reed2ad1aa62016-03-09 09:50:50 -080059 sk_sp<SkShader> fShader;
commit-bot@chromium.orgec7d6732014-05-05 16:19:08 +000060
61private:
scroggo@google.com32f20eb2012-06-29 17:28:50 +000062 typedef GM INHERITED ;
63};
64
commit-bot@chromium.org58e42872014-05-05 18:23:54 +000065class ComposeShaderAlphaGM : public skiagm::GM {
commit-bot@chromium.orgec7d6732014-05-05 16:19:08 +000066public:
67 ComposeShaderAlphaGM() {}
68
69protected:
mtklein36352bf2015-03-25 18:17:31 -070070 SkString onShortName() override {
commit-bot@chromium.orgec7d6732014-05-05 16:19:08 +000071 return SkString("composeshader_alpha");
72 }
skia.committer@gmail.comedda70e2014-05-06 03:06:53 +000073
mtklein36352bf2015-03-25 18:17:31 -070074 SkISize onISize() override {
wangyixd7059582015-09-03 08:32:22 -070075 return SkISize::Make(750, 220);
commit-bot@chromium.orgec7d6732014-05-05 16:19:08 +000076 }
reed@google.com775bf662014-05-05 19:37:22 +000077
mtklein36352bf2015-03-25 18:17:31 -070078 void onDraw(SkCanvas* canvas) override {
reed2ad1aa62016-03-09 09:50:50 -080079 sk_sp<SkShader> shaders[] = {
Mike Reed7d954ad2016-10-28 15:42:34 -040080 make_shader(SkBlendMode::kDstIn),
81 make_shader(SkBlendMode::kSrcOver),
reed2ad1aa62016-03-09 09:50:50 -080082 };
commit-bot@chromium.org58e42872014-05-05 18:23:54 +000083
commit-bot@chromium.orgec7d6732014-05-05 16:19:08 +000084 SkPaint paint;
85 paint.setColor(SK_ColorGREEN);
skia.committer@gmail.comedda70e2014-05-06 03:06:53 +000086
commit-bot@chromium.orgec7d6732014-05-05 16:19:08 +000087 const SkRect r = SkRect::MakeXYWH(5, 5, 100, 100);
skia.committer@gmail.comedda70e2014-05-06 03:06:53 +000088
commit-bot@chromium.org58e42872014-05-05 18:23:54 +000089 for (size_t y = 0; y < SK_ARRAY_COUNT(shaders); ++y) {
commit-bot@chromium.org58e42872014-05-05 18:23:54 +000090 canvas->save();
91 for (int alpha = 0xFF; alpha > 0; alpha -= 0x28) {
92 paint.setAlpha(0xFF);
halcanary96fcdcc2015-08-27 07:41:13 -070093 paint.setShader(nullptr);
commit-bot@chromium.org58e42872014-05-05 18:23:54 +000094 canvas->drawRect(r, paint);
skia.committer@gmail.comedda70e2014-05-06 03:06:53 +000095
commit-bot@chromium.org58e42872014-05-05 18:23:54 +000096 paint.setAlpha(alpha);
reed2ad1aa62016-03-09 09:50:50 -080097 paint.setShader(shaders[y]);
commit-bot@chromium.org58e42872014-05-05 18:23:54 +000098 canvas->drawRect(r, paint);
skia.committer@gmail.comedda70e2014-05-06 03:06:53 +000099
commit-bot@chromium.org58e42872014-05-05 18:23:54 +0000100 canvas->translate(r.width() + 5, 0);
101 }
102 canvas->restore();
103 canvas->translate(0, r.height() + 5);
commit-bot@chromium.orgec7d6732014-05-05 16:19:08 +0000104 }
105 }
wangyixd7059582015-09-03 08:32:22 -0700106
107private:
108 typedef GM INHERITED ;
109};
110
111
112// creates a square bitmap with red background and a green circle in the center
113static void draw_color_bm(SkBitmap* bm, int length) {
114 SkPaint paint;
115 paint.setColor(SK_ColorGREEN);
116
117 bm->allocN32Pixels(length, length);
118 bm->eraseColor(SK_ColorRED);
119
120 SkCanvas canvas(*bm);
121 canvas.drawCircle(SkIntToScalar(length/2), SkIntToScalar(length/2), SkIntToScalar(length/2),
122 paint);
123}
124
125// creates a square alpha8 bitmap with transparent background and an opaque circle in the center
126static void draw_alpha8_bm(SkBitmap* bm, int length) {
127 SkPaint circlePaint;
128 circlePaint.setColor(SK_ColorBLACK);
129
130 bm->allocPixels(SkImageInfo::MakeA8(length, length));
131 bm->eraseColor(SK_ColorTRANSPARENT);
132
133 SkCanvas canvas(*bm);
134 canvas.drawCircle(SkIntToScalar(length/2), SkIntToScalar(length/2), SkIntToScalar(length/4),
135 circlePaint);
136}
137
138// creates a linear gradient shader
reed2ad1aa62016-03-09 09:50:50 -0800139static sk_sp<SkShader> make_linear_gradient_shader(int length) {
wangyixd7059582015-09-03 08:32:22 -0700140 SkPoint pts[2];
141 SkColor colors[2];
142 pts[0].set(0, 0);
143 pts[1].set(SkIntToScalar(length), 0);
144 colors[0] = SK_ColorBLUE;
145 colors[1] = SkColorSetARGB(0, 0, 0, 0xFF);
reed2ad1aa62016-03-09 09:50:50 -0800146 return SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkShader::kClamp_TileMode);
wangyixd7059582015-09-03 08:32:22 -0700147}
148
149
150class ComposeShaderBitmapGM : public skiagm::GM {
151public:
herbb10fe492016-01-08 13:48:43 -0800152 ComposeShaderBitmapGM() {}
caryclark6df61152016-01-04 14:17:47 -0800153
herbb10fe492016-01-08 13:48:43 -0800154protected:
caryclark6df61152016-01-04 14:17:47 -0800155 void onOnceBeforeDraw() override {
wangyixd7059582015-09-03 08:32:22 -0700156 draw_color_bm(&fColorBitmap, squareLength);
157 draw_alpha8_bm(&fAlpha8Bitmap, squareLength);
158 SkMatrix s;
159 s.reset();
reed2ad1aa62016-03-09 09:50:50 -0800160 fColorBitmapShader = SkShader::MakeBitmapShader(fColorBitmap, SkShader::kRepeat_TileMode,
161 SkShader::kRepeat_TileMode, &s);
162 fAlpha8BitmapShader = SkShader::MakeBitmapShader(fAlpha8Bitmap, SkShader::kRepeat_TileMode,
163 SkShader::kRepeat_TileMode, &s);
wangyixd7059582015-09-03 08:32:22 -0700164 fLinearGradientShader = make_linear_gradient_shader(squareLength);
165 }
caryclark6df61152016-01-04 14:17:47 -0800166
wangyixd7059582015-09-03 08:32:22 -0700167 SkString onShortName() override {
168 return SkString("composeshader_bitmap");
169 }
170
171 SkISize onISize() override {
172 return SkISize::Make(7 * (squareLength + 5), 2 * (squareLength + 5));
173 }
174
175 void onDraw(SkCanvas* canvas) override {
Mike Reed7d954ad2016-10-28 15:42:34 -0400176 SkBlendMode mode = SkBlendMode::kDstOver;
wangyixd7059582015-09-03 08:32:22 -0700177
reed2ad1aa62016-03-09 09:50:50 -0800178 sk_sp<SkShader> shaders[] = {
179 // gradient should appear over color bitmap
Mike Reed7d954ad2016-10-28 15:42:34 -0400180 SkShader::MakeComposeShader(fLinearGradientShader, fColorBitmapShader, mode),
reed2ad1aa62016-03-09 09:50:50 -0800181 // gradient should appear over alpha8 bitmap colorized by the paint color
Mike Reed7d954ad2016-10-28 15:42:34 -0400182 SkShader::MakeComposeShader(fLinearGradientShader, fAlpha8BitmapShader, mode),
reed2ad1aa62016-03-09 09:50:50 -0800183 };
wangyixd7059582015-09-03 08:32:22 -0700184
185 SkPaint paint;
186 paint.setColor(SK_ColorYELLOW);
187
188 const SkRect r = SkRect::MakeXYWH(0, 0, SkIntToScalar(squareLength),
189 SkIntToScalar(squareLength));
190
191 for (size_t y = 0; y < SK_ARRAY_COUNT(shaders); ++y) {
wangyixd7059582015-09-03 08:32:22 -0700192 canvas->save();
193 for (int alpha = 0xFF; alpha > 0; alpha -= 0x28) {
194 paint.setAlpha(alpha);
reed2ad1aa62016-03-09 09:50:50 -0800195 paint.setShader(shaders[y]);
wangyixd7059582015-09-03 08:32:22 -0700196 canvas->drawRect(r, paint);
197
198 canvas->translate(r.width() + 5, 0);
199 }
200 canvas->restore();
201 canvas->translate(0, r.height() + 5);
202 }
203 }
halcanary9d524f22016-03-29 09:03:52 -0700204
wangyixd7059582015-09-03 08:32:22 -0700205private:
reed8681e602016-02-15 08:27:14 -0800206 /** This determines the length and width of the bitmaps used in the ComposeShaders. Values
wangyixd7059582015-09-03 08:32:22 -0700207 * above 20 may cause an SkASSERT to fail in SkSmallAllocator. However, larger values will
208 * work in a release build. You can change this parameter and then compile a release build
209 * to have this GM draw larger bitmaps for easier visual inspection.
210 */
mtkleindbfd7ab2016-09-01 11:24:54 -0700211 static constexpr int squareLength = 20;
wangyixd7059582015-09-03 08:32:22 -0700212
213 SkBitmap fColorBitmap;
214 SkBitmap fAlpha8Bitmap;
reed2ad1aa62016-03-09 09:50:50 -0800215 sk_sp<SkShader> fColorBitmapShader;
216 sk_sp<SkShader> fAlpha8BitmapShader;
217 sk_sp<SkShader> fLinearGradientShader;
wangyixd7059582015-09-03 08:32:22 -0700218
219 typedef GM INHERITED;
commit-bot@chromium.orgec7d6732014-05-05 16:19:08 +0000220};
221
caryclarkc2ad65e2016-08-15 12:03:33 -0700222DEF_SIMPLE_GM(composeshader_bitmap2, canvas, 200, 200) {
223 int width = 255;
224 int height = 255;
225 SkTDArray<uint8_t> dst8Storage;
226 dst8Storage.setCount(width * height);
227 SkTDArray<uint32_t> dst32Storage;
228 dst32Storage.setCount(width * height * sizeof(int32_t));
229 for (int y = 0; y < height; ++y) {
230 for (int x = 0; x < width; ++x) {
231 dst8Storage[y * width + x] = (y + x) / 2;
232 dst32Storage[y * width + x] = SkPackARGB32(0xFF, x, y, 0);
233 }
234 }
235 SkPaint paint;
236 paint.setAntiAlias(true);
237 paint.setColor(SK_ColorBLUE);
238 SkRect r = {0, 0, SkIntToScalar(width), SkIntToScalar(height)};
239 canvas->drawRect(r, paint);
240 SkBitmap skBitmap, skMask;
241 SkImageInfo imageInfo = SkImageInfo::Make(width, height,
242 SkColorType::kN32_SkColorType, kPremul_SkAlphaType);
243 skBitmap.installPixels(imageInfo, dst32Storage.begin(), width * sizeof(int32_t),
244 nullptr, nullptr, nullptr);
245 imageInfo = SkImageInfo::Make(width, height,
246 SkColorType::kAlpha_8_SkColorType, kPremul_SkAlphaType);
247 skMask.installPixels(imageInfo, dst8Storage.begin(), width, nullptr, nullptr, nullptr);
248 sk_sp<SkImage> skSrc = SkImage::MakeFromBitmap(skBitmap);
249 sk_sp<SkShader> skSrcShader =
250 skSrc->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
251 sk_sp<SkImage> skMaskImage = SkImage::MakeFromBitmap(skMask);
252 sk_sp<SkShader> skMaskShader = skMaskImage->makeShader(
253 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
caryclarkc2ad65e2016-08-15 12:03:33 -0700254 paint.setShader(
Mike Reed7d954ad2016-10-28 15:42:34 -0400255 SkShader::MakeComposeShader(skMaskShader, skSrcShader, SkBlendMode::kSrcIn));
caryclarkc2ad65e2016-08-15 12:03:33 -0700256 canvas->drawRect(r, paint);
257}
258
scroggo@google.com32f20eb2012-06-29 17:28:50 +0000259//////////////////////////////////////////////////////////////////////////////
260
commit-bot@chromium.orgec7d6732014-05-05 16:19:08 +0000261DEF_GM( return new ComposeShaderGM; )
262DEF_GM( return new ComposeShaderAlphaGM; )
wangyixd7059582015-09-03 08:32:22 -0700263DEF_GM( return new ComposeShaderBitmapGM; )