blob: 7c181df8005afc6f32a109c080e6371a0776dcf9 [file] [log] [blame]
fmalitacad54b52015-12-11 11:03:27 -08001/*
2 * Copyright 2015 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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -04009#include "include/core/SkCanvas.h"
10#include "include/core/SkColor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkImage.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040012#include "include/core/SkPaint.h"
13#include "include/core/SkPoint.h"
14#include "include/core/SkRect.h"
15#include "include/core/SkRefCnt.h"
16#include "include/core/SkScalar.h"
17#include "include/core/SkSize.h"
18#include "include/core/SkString.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050019#include "include/core/SkSurface.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040020#include "include/core/SkTypes.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050021#include "include/private/SkTArray.h"
fmalitacad54b52015-12-11 11:03:27 -080022
23class ImageScaleAlignedGM : public skiagm::GM {
24protected:
25 void onOnceBeforeDraw() override {
26 const SkVector vectors[] = { { 1, 0 }, { 0, 1 } };
27
28 for (size_t i = 0; i < SK_ARRAY_COUNT(vectors); ++i) {
29 auto& set = fSets.push_back();
30
31 set.fVector = vectors[i];
reed9ce9d672016-03-17 10:51:11 -070032 set.fImages.push_back() = MakeImage(vectors[i], SK_ColorGREEN);
fmalitacad54b52015-12-11 11:03:27 -080033 set.fScales.push_back() = 1;
reed9ce9d672016-03-17 10:51:11 -070034 set.fImages.push_back() = MakeImage(vectors[i], SK_ColorRED);
fmalitacad54b52015-12-11 11:03:27 -080035 set.fScales.push_back() = kStretchFactor;
reed9ce9d672016-03-17 10:51:11 -070036 set.fImages.push_back() = MakeImage(vectors[i], SK_ColorGREEN);
fmalitacad54b52015-12-11 11:03:27 -080037 set.fScales.push_back() = 1;
38 }
39 }
40
41 SkString onShortName() override {
42 return SkString("image_scale_aligned");
43 }
44
45 SkISize onISize() override {
fmalitaaed4d322015-12-15 06:48:48 -080046 return SkISize::Make(580, 780);
fmalitacad54b52015-12-11 11:03:27 -080047 }
48
49 void onDraw(SkCanvas* canvas) override {
50 struct {
51 SkPoint offset;
fmalitaaed4d322015-12-15 06:48:48 -080052 SkVector scale;
fmalitacad54b52015-12-11 11:03:27 -080053 } cfgs[] = {
fmalitaaed4d322015-12-15 06:48:48 -080054 {{ 10, 10 }, { 1, 1 }},
55 {{ 300.5f, 10 }, { 1, 1 }},
56 {{ 10, 200.5f }, { 1, 1 }},
57 {{ 300.5f, 200.5f }, { 1, 1 }},
fmalitacad54b52015-12-11 11:03:27 -080058
fmalitaaed4d322015-12-15 06:48:48 -080059 {{ 10.5f, 400.5f }, { 1, 1 }},
60 {{ 550.5f, 400.5f }, { -1, 1 }},
61 {{ 10.5f, 750.5f }, { 1, -1 }},
62 {{ 550.5f, 750.5f }, { -1, -1 }},
fmalitacad54b52015-12-11 11:03:27 -080063 };
64
65 for (size_t i = 0; i < SK_ARRAY_COUNT(cfgs); ++i) {
66 SkAutoCanvasRestore acr(canvas, true);
67 canvas->translate(cfgs[i].offset.x(), cfgs[i].offset.y());
fmalitaaed4d322015-12-15 06:48:48 -080068 canvas->scale(cfgs[i].scale.x(), cfgs[i].scale.y());
fmalitacad54b52015-12-11 11:03:27 -080069 drawSets(canvas);
70 }
71 }
72
73private:
74 struct ImageSet {
reed9ce9d672016-03-17 10:51:11 -070075 SkSTArray<3, sk_sp<SkImage>, true> fImages;
76 SkSTArray<3, SkScalar> fScales;
77 SkVector fVector;
fmalitacad54b52015-12-11 11:03:27 -080078 };
79
reed9ce9d672016-03-17 10:51:11 -070080 static sk_sp<SkImage> MakeImage(const SkVector& vec, SkColor color) {
fmalitacad54b52015-12-11 11:03:27 -080081 const SkPoint start = SkPoint::Make(vec.y() * kSegLen / 2, vec.x() * kSegLen / 2);
82 const SkPoint end = SkPoint::Make(start.x() + vec.x() * (kSegLen - 1),
83 start.y() + vec.y() * (kSegLen - 1));
84
reede8f30622016-03-23 18:59:25 -070085 auto surface(SkSurface::MakeRasterN32Premul(kSegLen, kSegLen));
fmalitacad54b52015-12-11 11:03:27 -080086 surface->getCanvas()->clear(SK_ColorTRANSPARENT);
87
88 SkPaint paint;
89 paint.setAntiAlias(true);
fmalitaaed4d322015-12-15 06:48:48 -080090 const SkRect border = SkRect::MakeIWH(kSegLen, kSegLen).makeInset(.5f, .5f);
91 paint.setColor(SK_ColorBLUE);
92 paint.setStyle(SkPaint::kStroke_Style);
93 surface->getCanvas()->drawRect(border, paint);
94
fmalitacad54b52015-12-11 11:03:27 -080095 paint.setColor(SK_ColorBLACK);
Hal Canary23e474c2017-05-15 13:35:35 -040096 surface->getCanvas()->drawLine(start, end, paint);
Mike Reed3661bc92017-02-22 13:21:42 -050097
98 paint.reset();
99 paint.setColor(color);
100 const SkPoint pts[] = { start, end };
101 surface->getCanvas()->drawPoints(SkCanvas::kPoints_PointMode, 2, pts, paint);
fmalitacad54b52015-12-11 11:03:27 -0800102
reed9ce9d672016-03-17 10:51:11 -0700103 return surface->makeImageSnapshot();
fmalitacad54b52015-12-11 11:03:27 -0800104 }
105
106 void drawSets(SkCanvas* canvas) const {
107 SkAutoCanvasRestore acr(canvas, true);
108
Mike Reed07c5f522021-01-23 12:23:23 -0500109 const SkSamplingOptions samplings[] = {
110 SkSamplingOptions(SkFilterMode::kNearest),
111 SkSamplingOptions(SkFilterMode::kLinear),
112 SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear),
Mike Reedf3ac2af2021-02-05 12:55:38 -0500113 SkSamplingOptions(SkCubicResampler::Mitchell()),
fmalitacad54b52015-12-11 11:03:27 -0800114 };
115 const bool AAs[] = { false, true };
116
117 SkPaint paint;
118 for (int i = 0; i < fSets.count(); ++i) {
119 auto& set = fSets[i];
120 SkPoint lastPt;
121 for (size_t j = 0; j < SK_ARRAY_COUNT(AAs); ++j) {
122 paint.setAntiAlias(AAs[j]);
Mike Reed07c5f522021-01-23 12:23:23 -0500123 for (size_t k = 0; k < SK_ARRAY_COUNT(samplings); ++k) {
124 lastPt = drawSet(canvas, set, samplings[k], paint);
fmalitaaed4d322015-12-15 06:48:48 -0800125 canvas->translate((kSegLen + 4) * set.fVector.y(),
126 (kSegLen + 4) * set.fVector.x());
fmalitacad54b52015-12-11 11:03:27 -0800127 }
128 }
129 canvas->translate(lastPt.x() + kSegLen,
Mike Reed07c5f522021-01-23 12:23:23 -0500130 - SkIntToScalar(kSegLen + 4) * SK_ARRAY_COUNT(samplings) * SK_ARRAY_COUNT(AAs));
fmalitacad54b52015-12-11 11:03:27 -0800131 }
132 }
133
Mike Reed07c5f522021-01-23 12:23:23 -0500134 SkPoint drawSet(SkCanvas* canvas, const ImageSet& set, const SkSamplingOptions& sampling,
135 const SkPaint& paint) const {
fmalitacad54b52015-12-11 11:03:27 -0800136 SkASSERT(set.fImages.count() == set.fScales.count());
137
138 SkPoint pt = SkPoint::Make(0, 0);
139 for (int i = 0; i < set.fImages.count(); ++i) {
140 auto& img = set.fImages[i];
141 const SkRect dst =
142 SkRect::MakeXYWH(pt.x(), pt.y(),
143 img->width() * (1 + (set.fScales[i] - 1) * set.fVector.x()),
144 img->height() * (1 + (set.fScales[i] - 1) * set.fVector.y()));
145
Mike Reed07c5f522021-01-23 12:23:23 -0500146 canvas->drawImageRect(img.get(), dst, sampling, &paint);
fmalitacad54b52015-12-11 11:03:27 -0800147 pt.offset(dst.width() * set.fVector.x(), dst.height() * set.fVector.y());
148 }
149
150 return pt;
151 }
152
mtkleindbfd7ab2016-09-01 11:24:54 -0700153 static constexpr unsigned kSegLen = 15;
154 static constexpr unsigned kStretchFactor = 4;
fmalitacad54b52015-12-11 11:03:27 -0800155 SkSTArray<2, ImageSet> fSets;
156
John Stiles7571f9e2020-09-02 22:42:33 -0400157 using INHERITED = GM;
fmalitacad54b52015-12-11 11:03:27 -0800158};
159
160DEF_GM(return new ImageScaleAlignedGM();)