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