• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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