1 /*
2 * Copyright 2018 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 #include "SkCanvas.h"
10 #include "SkShader.h"
11 #include "SkSurface.h"
12 #include "sk_tool_utils.h"
13
make_image(SkCanvas * rootCanvas)14 static sk_sp<SkImage> make_image(SkCanvas* rootCanvas) {
15 static constexpr SkScalar kSize = 50;
16 SkImageInfo info = SkImageInfo::MakeN32Premul(kSize, kSize);
17 auto surface = sk_tool_utils::makeSurface(rootCanvas, info);
18
19 SkPaint p;
20 p.setAntiAlias(true);
21 p.setColor(SK_ColorGREEN);
22
23 surface->getCanvas()->drawCircle(kSize / 2, kSize / 2, kSize / 2, p);
24
25 p.setStyle(SkPaint::kStroke_Style);
26 p.setColor(SK_ColorRED);
27 surface->getCanvas()->drawLine(kSize * .25f, kSize * .50f, kSize * .75f, kSize * .50f, p);
28 surface->getCanvas()->drawLine(kSize * .50f, kSize * .25f, kSize * .50f, kSize * .75f, p);
29
30 return surface->makeImageSnapshot();
31 }
32
33 DEF_SIMPLE_GM(localmatrixshader_nested, canvas, 450, 1200) {
34 auto image = make_image(canvas);
35
36 using FactoryT = sk_sp<SkShader> (*)(const sk_sp<SkImage>&,
37 const SkMatrix& inner,
38 const SkMatrix& outer);
39 static const FactoryT gFactories[] = {
40 // SkLocalMatrixShader(SkImageShader(inner), outer)
__anon1a544d110102() 41 [](const sk_sp<SkImage>& img, const SkMatrix& inner, const SkMatrix& outer) {
42 return img->makeShader(&inner)->makeWithLocalMatrix(outer);
43 },
44
45 // SkLocalMatrixShader(SkLocalMatrixShader(SkImageShader(I), inner), outer)
__anon1a544d110202() 46 [](const sk_sp<SkImage>& img, const SkMatrix& inner, const SkMatrix& outer) {
47 return img->makeShader()->makeWithLocalMatrix(inner)->makeWithLocalMatrix(outer);
48 },
49
50 // SkLocalMatrixShader(SkComposeShader(SkImageShader(inner)), outer)
__anon1a544d110302() 51 [](const sk_sp<SkImage>& img, const SkMatrix& inner, const SkMatrix& outer) {
52 return SkShader::MakeCompose(SkShader::MakeColorShader(SK_ColorTRANSPARENT),
53 img->makeShader(&inner),
54 SkBlendMode::kSrcOver)
55 ->makeWithLocalMatrix(outer);
56 },
57
58 // SkLocalMatrixShader(SkComposeShader(SkLocalMatrixShader(SkImageShader(I), inner)), outer)
__anon1a544d110402() 59 [](const sk_sp<SkImage>& img, const SkMatrix& inner, const SkMatrix& outer) {
60 return SkShader::MakeCompose(SkShader::MakeColorShader(SK_ColorTRANSPARENT),
61 img->makeShader()->makeWithLocalMatrix(inner),
62 SkBlendMode::kSrcOver)
63 ->makeWithLocalMatrix(outer);
64 },
65 };
66
67 static const auto inner = SkMatrix::MakeScale(2, 2),
68 outer = SkMatrix::MakeTrans(20, 20);
69
70 SkPaint border;
71 border.setAntiAlias(true);
72 border.setStyle(SkPaint::kStroke_Style);
73
74 auto rect = SkRect::Make(image->bounds());
75 SkAssertResult(SkMatrix::Concat(inner, outer).mapRect(&rect));
76
__anon1a544d110502() 77 const auto drawColumn = [&]() {
78 SkAutoCanvasRestore acr(canvas, true);
79 for (const auto& f : gFactories) {
80 SkPaint p;
81 p.setShader(f(image, inner, outer));
82
83 canvas->drawRect(rect, p);
84 canvas->drawRect(rect, border);
85
86 canvas->translate(0, rect.height() * 1.5f);
87 }
88 };
89
90 drawColumn();
91
92 {
93 SkAutoCanvasRestore acr(canvas, true);
94 canvas->translate(0, rect.height() * SK_ARRAY_COUNT(gFactories) * 1.5f);
95 drawColumn();
96 }
97
98 canvas->translate(rect.width() * 1.5f, 0);
99 canvas->scale(2, 2);
100 drawColumn();
101 }
102