1b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com/*
2b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com * Copyright 2011 Google Inc.
3b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com *
4b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com * Use of this source code is governed by a BSD-style license that can be
5b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com * found in the LICENSE file.
6b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com */
7b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com
8b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com#include "gm.h"
94c21dc5ddf3b482293ed34eead876d8d61a662c3reed#include "SkSurface.h"
10b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com
11e8f3062a36d3682f4019309a32b5b84dc9eddf8creedstatic sk_sp<SkSurface> make_surface(SkCanvas* root, int N) {
124c21dc5ddf3b482293ed34eead876d8d61a662c3reed    SkImageInfo info = SkImageInfo::MakeN32Premul(N, N);
13e8f3062a36d3682f4019309a32b5b84dc9eddf8creed    auto surface = root->makeSurface(info);
144c21dc5ddf3b482293ed34eead876d8d61a662c3reed    if (!surface) {
15e8f3062a36d3682f4019309a32b5b84dc9eddf8creed        surface = SkSurface::MakeRaster(info);
164c21dc5ddf3b482293ed34eead876d8d61a662c3reed    }
174c21dc5ddf3b482293ed34eead876d8d61a662c3reed    return surface;
184c21dc5ddf3b482293ed34eead876d8d61a662c3reed}
194c21dc5ddf3b482293ed34eead876d8d61a662c3reed
209ce9d6772df650ceb0511f275e1a83dffa78ff72reedstatic sk_sp<SkImage> make_image(SkCanvas* root, SkIRect* center) {
21b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    const int kFixed = 28;
22b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    const int kStretchy = 8;
23b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    const int kSize = 2*kFixed + kStretchy;
24cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com
25e8f3062a36d3682f4019309a32b5b84dc9eddf8creed    auto surface(make_surface(root, kSize));
264c21dc5ddf3b482293ed34eead876d8d61a662c3reed    SkCanvas* canvas = surface->getCanvas();
27d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
28b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    SkRect r = SkRect::MakeWH(SkIntToScalar(kSize), SkIntToScalar(kSize));
29b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    const SkScalar strokeWidth = SkIntToScalar(6);
30b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    const SkScalar radius = SkIntToScalar(kFixed) - strokeWidth/2;
31d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
32b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    center->setXYWH(kFixed, kFixed, kStretchy, kStretchy);
33d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
34b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    SkPaint paint;
35b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    paint.setAntiAlias(true);
36d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
37b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    paint.setColor(0xFFFF0000);
384c21dc5ddf3b482293ed34eead876d8d61a662c3reed    canvas->drawRoundRect(r, radius, radius, paint);
39b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    r.setXYWH(SkIntToScalar(kFixed), 0, SkIntToScalar(kStretchy), SkIntToScalar(kSize));
40b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    paint.setColor(0x8800FF00);
414c21dc5ddf3b482293ed34eead876d8d61a662c3reed    canvas->drawRect(r, paint);
42b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    r.setXYWH(0, SkIntToScalar(kFixed), SkIntToScalar(kSize), SkIntToScalar(kStretchy));
43b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    paint.setColor(0x880000FF);
444c21dc5ddf3b482293ed34eead876d8d61a662c3reed    canvas->drawRect(r, paint);
454c21dc5ddf3b482293ed34eead876d8d61a662c3reed
469ce9d6772df650ceb0511f275e1a83dffa78ff72reed    return surface->makeImageSnapshot();
47b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com}
48b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com
494c21dc5ddf3b482293ed34eead876d8d61a662c3reedstatic void image_to_bitmap(const SkImage* image, SkBitmap* bm) {
504c21dc5ddf3b482293ed34eead876d8d61a662c3reed    SkImageInfo info = SkImageInfo::MakeN32Premul(image->width(), image->height());
514c21dc5ddf3b482293ed34eead876d8d61a662c3reed    bm->allocPixels(info);
524c21dc5ddf3b482293ed34eead876d8d61a662c3reed    image->readPixels(info, bm->getPixels(), bm->rowBytes(), 0, 0);
534c21dc5ddf3b482293ed34eead876d8d61a662c3reed}
54d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
554c21dc5ddf3b482293ed34eead876d8d61a662c3reedclass NinePatchStretchGM : public skiagm::GM {
56b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.compublic:
579ce9d6772df650ceb0511f275e1a83dffa78ff72reed    sk_sp<SkImage>  fImage;
589ce9d6772df650ceb0511f275e1a83dffa78ff72reed    SkBitmap        fBitmap;
599ce9d6772df650ceb0511f275e1a83dffa78ff72reed    SkIRect         fCenter;
60b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com
61d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    NinePatchStretchGM() {}
62b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com
63b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.comprotected:
644c21dc5ddf3b482293ed34eead876d8d61a662c3reed    SkString onShortName() override {
65b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com        return SkString("ninepatch-stretch");
66b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    }
67b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com
684c21dc5ddf3b482293ed34eead876d8d61a662c3reed    SkISize onISize() override {
6933a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt        return SkISize::Make(760, 800);
70b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    }
71b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com
724c21dc5ddf3b482293ed34eead876d8d61a662c3reed    void onDraw(SkCanvas* canvas) override {
7396fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (nullptr == fBitmap.pixelRef()) {
749ce9d6772df650ceb0511f275e1a83dffa78ff72reed            fImage = make_image(canvas, &fCenter);
759ce9d6772df650ceb0511f275e1a83dffa78ff72reed            image_to_bitmap(fImage.get(), &fBitmap);
764c21dc5ddf3b482293ed34eead876d8d61a662c3reed        }
77d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
78b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com        // amount of bm that should not be stretched (unless we have to)
794c21dc5ddf3b482293ed34eead876d8d61a662c3reed        const SkScalar fixed = SkIntToScalar(fBitmap.width() - fCenter.width());
80d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
81b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com        const SkTSize<SkScalar> size[] = {
82b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com            { fixed * 4 / 5, fixed * 4 / 5 },   // shrink in both axes
83b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com            { fixed * 4 / 5, fixed * 4 },       // shrink in X
84b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com            { fixed * 4,     fixed * 4 / 5 },   // shrink in Y
85b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com            { fixed * 4,     fixed * 4 }
86b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com        };
87d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
8896fcdcc219d2a0d3579719b84b28bede76efba64halcanary        canvas->drawBitmap(fBitmap, 10, 10, nullptr);
89d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
90b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com        SkScalar x = SkIntToScalar(100);
91b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com        SkScalar y = SkIntToScalar(100);
92d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
93b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com        SkPaint paint;
9433a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt        for (int filter = 0; filter < 2; filter++) {
9533a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            paint.setFilterQuality(filter == 0 ? kLow_SkFilterQuality : kNone_SkFilterQuality);
9633a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            canvas->translate(0, filter * SkIntToScalar(400));
9733a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            for (int iy = 0; iy < 2; ++iy) {
9833a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                for (int ix = 0; ix < 2; ++ix) {
9933a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                    int i = ix * 2 + iy;
10033a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                    SkRect r = SkRect::MakeXYWH(x + ix * fixed, y + iy * fixed,
10133a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                                size[i].width(), size[i].height());
10233a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                    canvas->drawBitmapNine(fBitmap, fCenter, r, &paint);
1039ce9d6772df650ceb0511f275e1a83dffa78ff72reed                    canvas->drawImageNine(fImage.get(), fCenter, r.makeOffset(360, 0), &paint);
10433a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                }
105b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com            }
106b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com        }
107b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    }
108d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
109b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.comprivate:
1104c21dc5ddf3b482293ed34eead876d8d61a662c3reed    typedef skiagm::GM INHERITED;
111b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com};
1124c21dc5ddf3b482293ed34eead876d8d61a662c3reedDEF_GM( return new NinePatchStretchGM; )
113