Add fixes & test for isConfigTexturable and isConfigRenderable
[platform/upstream/libSkiaSharp.git] / gm / imagescalealigned.cpp
1 /*
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
8 #include "gm.h"
9
10 #include "SkImage.h"
11 #include "SkSurface.h"
12 #include "SkTArray.h"
13
14 class ImageScaleAlignedGM : public skiagm::GM {
15 protected:
16     void onOnceBeforeDraw() override {
17         const SkVector vectors[] = { { 1, 0 }, { 0, 1 } };
18
19         for (size_t i = 0; i < SK_ARRAY_COUNT(vectors); ++i) {
20            auto& set = fSets.push_back();
21
22            set.fVector = vectors[i];
23            set.fImages.push_back() = MakeImage(vectors[i], SK_ColorGREEN);
24            set.fScales.push_back() = 1;
25            set.fImages.push_back() = MakeImage(vectors[i], SK_ColorRED);
26            set.fScales.push_back() = kStretchFactor;
27            set.fImages.push_back() = MakeImage(vectors[i], SK_ColorGREEN);
28            set.fScales.push_back() = 1;
29         }
30     }
31
32     SkString onShortName() override {
33         return SkString("image_scale_aligned");
34     }
35
36     SkISize onISize() override {
37         return SkISize::Make(580, 780);
38     }
39
40     void onDraw(SkCanvas* canvas) override {
41         struct {
42             SkPoint offset;
43             SkVector scale;
44         } cfgs[] = {
45             {{  10,    10    }, { 1, 1 }},
46             {{ 300.5f, 10    }, { 1, 1 }},
47             {{  10,    200.5f }, { 1, 1 }},
48             {{ 300.5f, 200.5f }, { 1, 1 }},
49
50             {{  10.5f, 400.5f }, {  1,  1 }},
51             {{ 550.5f, 400.5f }, { -1,  1 }},
52             {{  10.5f, 750.5f }, {  1, -1 }},
53             {{ 550.5f, 750.5f }, { -1, -1 }},
54         };
55
56         for (size_t i = 0; i < SK_ARRAY_COUNT(cfgs); ++i) {
57             SkAutoCanvasRestore acr(canvas, true);
58             canvas->translate(cfgs[i].offset.x(), cfgs[i].offset.y());
59             canvas->scale(cfgs[i].scale.x(), cfgs[i].scale.y());
60             drawSets(canvas);
61         }
62     }
63
64 private:
65     struct ImageSet {
66         SkSTArray<3, sk_sp<SkImage>, true>  fImages;
67         SkSTArray<3, SkScalar>              fScales;
68         SkVector                            fVector;
69     };
70
71     static sk_sp<SkImage> MakeImage(const SkVector& vec, SkColor color) {
72         const SkPoint start = SkPoint::Make(vec.y() * kSegLen / 2, vec.x() * kSegLen / 2);
73         const SkPoint end   = SkPoint::Make(start.x() + vec.x() * (kSegLen - 1),
74                                             start.y() + vec.y() * (kSegLen - 1));
75
76         auto surface(SkSurface::MakeRasterN32Premul(kSegLen, kSegLen));
77         surface->getCanvas()->clear(SK_ColorTRANSPARENT);
78
79         SkPaint paint;
80         paint.setAntiAlias(true);
81         const SkRect border = SkRect::MakeIWH(kSegLen, kSegLen).makeInset(.5f, .5f);
82         paint.setColor(SK_ColorBLUE);
83         paint.setStyle(SkPaint::kStroke_Style);
84         surface->getCanvas()->drawRect(border, paint);
85
86         paint.setColor(SK_ColorBLACK);
87         surface->getCanvas()->drawLine(start, end, paint);
88
89         paint.reset();
90         paint.setColor(color);
91         const SkPoint pts[] = { start, end };
92         surface->getCanvas()->drawPoints(SkCanvas::kPoints_PointMode, 2, pts, paint);
93
94         return surface->makeImageSnapshot();
95     }
96
97     void drawSets(SkCanvas* canvas) const {
98         SkAutoCanvasRestore acr(canvas, true);
99
100         const SkFilterQuality filters[] = {
101             kNone_SkFilterQuality,
102             kLow_SkFilterQuality,
103             kMedium_SkFilterQuality,
104             kHigh_SkFilterQuality
105         };
106         const bool AAs[] = { false, true };
107
108         SkPaint paint;
109         for (int i = 0; i < fSets.count(); ++i) {
110             auto& set = fSets[i];
111             SkPoint lastPt;
112             for (size_t j = 0; j < SK_ARRAY_COUNT(AAs); ++j) {
113                 paint.setAntiAlias(AAs[j]);
114                 for (size_t k = 0; k < SK_ARRAY_COUNT(filters); ++k) {
115                     paint.setFilterQuality(filters[k]);
116                     lastPt = drawSet(canvas, set, paint);
117                     canvas->translate((kSegLen + 4) * set.fVector.y(),
118                                       (kSegLen + 4) * set.fVector.x());
119                 }
120             }
121             canvas->translate(lastPt.x() + kSegLen,
122                 - SkIntToScalar(kSegLen + 4) * SK_ARRAY_COUNT(filters) * SK_ARRAY_COUNT(AAs));
123         }
124     }
125
126     SkPoint drawSet(SkCanvas* canvas, const ImageSet& set, const SkPaint& paint) const {
127         SkASSERT(set.fImages.count() == set.fScales.count());
128
129         SkPoint pt = SkPoint::Make(0, 0);
130         for (int i = 0; i < set.fImages.count(); ++i) {
131             auto& img = set.fImages[i];
132             const SkRect dst =
133                 SkRect::MakeXYWH(pt.x(), pt.y(),
134                     img->width() * (1 + (set.fScales[i] - 1) * set.fVector.x()),
135                     img->height() * (1 + (set.fScales[i] - 1) * set.fVector.y()));
136
137             canvas->drawImageRect(img.get(), dst, &paint);
138             pt.offset(dst.width() * set.fVector.x(), dst.height() * set.fVector.y());
139         }
140
141         return pt;
142     }
143
144     static constexpr unsigned  kSegLen = 15;
145     static constexpr unsigned  kStretchFactor = 4;
146     SkSTArray<2, ImageSet> fSets;
147
148     typedef GM INHERITED;
149 };
150
151 DEF_GM(return new ImageScaleAlignedGM();)