blob: bbd2775b7cfca83648db1b893c60aa6c19779e31 [file] [log] [blame]
Florin Malita325ea322018-04-04 14:17:30 -04001/*
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
14static sk_sp<SkImage> make_image(SkCanvas* rootCanvas) {
15 static constexpr SkScalar kSize = 50;
16 SkImageInfo info = SkImageInfo::MakeN32Premul(kSize, kSize);
Cary Clarka24712e2018-09-05 18:41:40 +000017 auto surface = sk_tool_utils::makeSurface(rootCanvas, info);
Florin Malita325ea322018-04-04 14:17:30 -040018
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
33DEF_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)
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)
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)
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)
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
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}