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/gm.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkImage.h"
11 #include "include/core/SkMatrix.h"
12 #include "include/core/SkPaint.h"
13 #include "include/core/SkRect.h"
14 #include "include/core/SkRefCnt.h"
15 #include "include/core/SkSize.h"
16 #include "include/core/SkString.h"
17 #include "include/private/SkTArray.h"
18 #include "include/private/SkTDArray.h"
19 #include "tools/Resources.h"
20
21 #include <initializer_list>
22
make_image1()23 static sk_sp<SkImage> make_image1() { return GetResourceAsImage("images/mandrill_128.png"); }
24
make_image2()25 static sk_sp<SkImage> make_image2() {
26 return GetResourceAsImage("images/brickwork-texture.jpg")->makeSubset({0, 0, 128, 128});
27 }
28
29 namespace skiagm {
30
31 class PerspImages : public GM {
32 public:
33 PerspImages() = default;
34
35 protected:
onShortName()36 SkString onShortName() override { return SkString("persp_images"); }
37
onISize()38 SkISize onISize() override { return SkISize::Make(1150, 1280); }
39
onOnceBeforeDraw()40 void onOnceBeforeDraw() override {
41 fImages.push_back(make_image1());
42 fImages.push_back(make_image2());
43 }
44
onDraw(SkCanvas * canvas)45 void onDraw(SkCanvas* canvas) override {
46 SkTDArray<SkMatrix> matrices;
47 matrices.push()->setAll(1.f, 0.f, 0.f,
48 0.f, 1.f, 0.f,
49 0.f, 0.005f, 1.f);
50 matrices.push()->setAll(1.f, 0.f, 0.f,
51 0.f, 1.f, 0.f,
52 0.007f, -0.005f, 1.f);
53 matrices[1].preSkew(0.2f, -0.1f);
54 matrices[1].preRotate(-65.f);
55 matrices[1].preScale(1.2f, .8f);
56 matrices[1].postTranslate(0.f, 60.f);
57 SkPaint paint;
58 int n = 0;
59 SkRect bounds = SkRect::MakeEmpty();
60 for (const auto& img : fImages) {
61 SkRect imgB = SkRect::MakeWH(img->width(), img->height());
62 for (const auto& m : matrices) {
63 SkRect temp;
64 m.mapRect(&temp, imgB);
65 bounds.join(temp);
66 }
67 }
68 canvas->translate(-bounds.fLeft + 10.f, -bounds.fTop + 10.f);
69 canvas->save();
70 enum class DrawType {
71 kDrawImage,
72 kDrawImageRectStrict,
73 kDrawImageRectFast,
74 };
75 for (auto type :
76 {DrawType::kDrawImage, DrawType::kDrawImageRectStrict, DrawType::kDrawImageRectFast}) {
77 for (const auto& m : matrices) {
78 for (auto aa : {false, true}) {
79 paint.setAntiAlias(aa);
80 for (auto sampling : {
81 SkSamplingOptions(SkFilterMode::kNearest),
82 SkSamplingOptions(SkFilterMode::kLinear),
83 SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear),
84 SkSamplingOptions(SkCubicResampler::Mitchell())}) {
85 for (const auto& img : fImages) {
86 canvas->save();
87 canvas->concat(m);
88 SkRect src = {img->width() / 4.f, img->height() / 4.f,
89 3.f * img->width() / 4.f, 3.f * img->height() / 4};
90 SkRect dst = {0, 0,
91 3.f / 4.f * img->width(), 3.f / 4.f * img->height()};
92 switch (type) {
93 case DrawType::kDrawImage:
94 canvas->drawImage(img, 0, 0, sampling, &paint);
95 break;
96 case DrawType::kDrawImageRectStrict:
97 canvas->drawImageRect(img, src, dst, sampling, &paint,
98 SkCanvas::kStrict_SrcRectConstraint);
99 break;
100 case DrawType::kDrawImageRectFast:
101 canvas->drawImageRect(img, src, dst, sampling, &paint,
102 SkCanvas::kFast_SrcRectConstraint);
103 break;
104 }
105 canvas->restore();
106 ++n;
107 if (n < 8) {
108 canvas->translate(bounds.width() + 10.f, 0);
109 } else {
110 canvas->restore();
111 canvas->translate(0, bounds.height() + 10.f);
112 canvas->save();
113 n = 0;
114 }
115 }
116 }
117 }
118 }
119 }
120 canvas->restore();
121 }
122
123 private:
124 inline static constexpr int kNumImages = 4;
125 SkTArray<sk_sp<SkImage>> fImages;
126
127 using INHERITED = GM;
128 };
129
130 //////////////////////////////////////////////////////////////////////////////
131
132 DEF_GM(return new PerspImages();)
133
134 } // namespace skiagm
135