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#include "SkCanvas.h"
10#include "SkRSXform.h"
11#include "SkSurface.h"
12
13class DrawAtlasGM : public skiagm::GM {
14    static SkImage* MakeAtlas(SkCanvas* caller, const SkRect& target) {
15        SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
16        SkAutoTUnref<SkSurface> surface(caller->newSurface(info));
17        if (nullptr == surface) {
18            surface.reset(SkSurface::NewRaster(info));
19        }
20        SkCanvas* canvas = surface->getCanvas();
21        // draw red everywhere, but we don't expect to see it in the draw, testing the notion
22        // that drawAtlas draws a subset-region of the atlas.
23        canvas->clear(SK_ColorRED);
24
25        SkPaint paint;
26        paint.setXfermodeMode(SkXfermode::kClear_Mode);
27        SkRect r(target);
28        r.inset(-1, -1);
29        // zero out a place (with a 1-pixel border) to land our drawing.
30        canvas->drawRect(r, paint);
31        paint.setXfermode(nullptr);
32        paint.setColor(SK_ColorBLUE);
33        paint.setAntiAlias(true);
34        canvas->drawOval(target, paint);
35        return surface->newImageSnapshot();
36    }
37
38    SkAutoTUnref<SkImage> fAtlas;
39
40public:
41    DrawAtlasGM() {}
42
43protected:
44
45    SkString onShortName() override {
46        return SkString("draw-atlas");
47    }
48
49    SkISize onISize() override {
50        return SkISize::Make(640, 480);
51    }
52
53    void onDraw(SkCanvas* canvas) override {
54        const SkRect target = { 50, 50, 80, 90 };
55        if (nullptr == fAtlas) {
56            fAtlas.reset(MakeAtlas(canvas, target));
57        }
58
59        const struct {
60            SkScalar fScale;
61            SkScalar fDegrees;
62            SkScalar fTx;
63            SkScalar fTy;
64
65            void apply(SkRSXform* xform) const {
66                const SkScalar rad = SkDegreesToRadians(fDegrees);
67                xform->fSCos = fScale * SkScalarCos(rad);
68                xform->fSSin = fScale * SkScalarSin(rad);
69                xform->fTx   = fTx;
70                xform->fTy   = fTy;
71            }
72        } rec[] = {
73            { 1, 0, 10, 10 },       // just translate
74            { 2, 0, 110, 10 },      // scale + translate
75            { 1, 30, 210, 10 },     // rotate + translate
76            { 2, -30, 310, 30 },    // scale + rotate + translate
77        };
78
79        const int N = SK_ARRAY_COUNT(rec);
80        SkRSXform xform[N];
81        SkRect tex[N];
82        SkColor colors[N];
83
84        for (int i = 0; i < N; ++i) {
85            rec[i].apply(&xform[i]);
86            tex[i] = target;
87            colors[i] = 0x80FF0000 + (i * 40 * 256);
88        }
89
90        SkPaint paint;
91        paint.setFilterQuality(kLow_SkFilterQuality);
92        paint.setAntiAlias(true);
93
94        canvas->drawAtlas(fAtlas, xform, tex, N, nullptr, &paint);
95        canvas->translate(0, 100);
96        canvas->drawAtlas(fAtlas, xform, tex, colors, N, SkXfermode::kSrcIn_Mode, nullptr, &paint);
97    }
98
99private:
100    typedef GM INHERITED;
101};
102DEF_GM( return new DrawAtlasGM; )
103
104