ninepatchstretch.cpp revision 33a5fce6126dc5d3927a71fdc6c35af6f5893fd5
1/*
2 * Copyright 2011 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 "SkSurface.h"
10
11static SkSurface* make_surface(SkCanvas* root, int N) {
12    SkImageInfo info = SkImageInfo::MakeN32Premul(N, N);
13    SkSurface* surface = root->newSurface(info);
14    if (!surface) {
15        surface = SkSurface::NewRaster(info);
16    }
17    return surface;
18}
19
20static SkImage* make_image(SkCanvas* root, SkIRect* center) {
21    const int kFixed = 28;
22    const int kStretchy = 8;
23    const int kSize = 2*kFixed + kStretchy;
24
25    SkAutoTUnref<SkSurface> surface(make_surface(root, kSize));
26    SkCanvas* canvas = surface->getCanvas();
27
28    SkRect r = SkRect::MakeWH(SkIntToScalar(kSize), SkIntToScalar(kSize));
29    const SkScalar strokeWidth = SkIntToScalar(6);
30    const SkScalar radius = SkIntToScalar(kFixed) - strokeWidth/2;
31
32    center->setXYWH(kFixed, kFixed, kStretchy, kStretchy);
33
34    SkPaint paint;
35    paint.setAntiAlias(true);
36
37    paint.setColor(0xFFFF0000);
38    canvas->drawRoundRect(r, radius, radius, paint);
39    r.setXYWH(SkIntToScalar(kFixed), 0, SkIntToScalar(kStretchy), SkIntToScalar(kSize));
40    paint.setColor(0x8800FF00);
41    canvas->drawRect(r, paint);
42    r.setXYWH(0, SkIntToScalar(kFixed), SkIntToScalar(kSize), SkIntToScalar(kStretchy));
43    paint.setColor(0x880000FF);
44    canvas->drawRect(r, paint);
45
46    return surface->newImageSnapshot();
47}
48
49static void image_to_bitmap(const SkImage* image, SkBitmap* bm) {
50    SkImageInfo info = SkImageInfo::MakeN32Premul(image->width(), image->height());
51    bm->allocPixels(info);
52    image->readPixels(info, bm->getPixels(), bm->rowBytes(), 0, 0);
53}
54
55class NinePatchStretchGM : public skiagm::GM {
56public:
57    SkAutoTUnref<SkImage> fImage;
58    SkBitmap    fBitmap;
59    SkIRect     fCenter;
60
61    NinePatchStretchGM() {}
62
63protected:
64    SkString onShortName() override {
65        return SkString("ninepatch-stretch");
66    }
67
68    SkISize onISize() override {
69        return SkISize::Make(760, 800);
70    }
71
72    void onDraw(SkCanvas* canvas) override {
73        if (nullptr == fBitmap.pixelRef()) {
74            fImage.reset(make_image(canvas, &fCenter));
75            image_to_bitmap(fImage, &fBitmap);
76        }
77
78        // amount of bm that should not be stretched (unless we have to)
79        const SkScalar fixed = SkIntToScalar(fBitmap.width() - fCenter.width());
80
81        const SkTSize<SkScalar> size[] = {
82            { fixed * 4 / 5, fixed * 4 / 5 },   // shrink in both axes
83            { fixed * 4 / 5, fixed * 4 },       // shrink in X
84            { fixed * 4,     fixed * 4 / 5 },   // shrink in Y
85            { fixed * 4,     fixed * 4 }
86        };
87
88        canvas->drawBitmap(fBitmap, 10, 10, nullptr);
89
90        SkScalar x = SkIntToScalar(100);
91        SkScalar y = SkIntToScalar(100);
92
93        SkPaint paint;
94        for (int filter = 0; filter < 2; filter++) {
95            paint.setFilterQuality(filter == 0 ? kLow_SkFilterQuality : kNone_SkFilterQuality);
96            canvas->translate(0, filter * SkIntToScalar(400));
97            for (int iy = 0; iy < 2; ++iy) {
98                for (int ix = 0; ix < 2; ++ix) {
99                    int i = ix * 2 + iy;
100                    SkRect r = SkRect::MakeXYWH(x + ix * fixed, y + iy * fixed,
101                                                size[i].width(), size[i].height());
102                    canvas->drawBitmapNine(fBitmap, fCenter, r, &paint);
103                    canvas->drawImageNine(fImage, fCenter, r.makeOffset(360, 0), &paint);
104                }
105            }
106        }
107    }
108
109private:
110    typedef skiagm::GM INHERITED;
111};
112DEF_GM( return new NinePatchStretchGM; )
113
114