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"
1046596ae50559e89a0a2462573ac9448cf309cf56Mike Reed#include "sk_tool_utils.h"
11b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com
12e8f3062a36d3682f4019309a32b5b84dc9eddf8creedstatic sk_sp<SkSurface> make_surface(SkCanvas* root, int N) {
134c21dc5ddf3b482293ed34eead876d8d61a662c3reed    SkImageInfo info = SkImageInfo::MakeN32Premul(N, N);
1446596ae50559e89a0a2462573ac9448cf309cf56Mike Reed    return sk_tool_utils::makeSurface(root, info);
154c21dc5ddf3b482293ed34eead876d8d61a662c3reed}
164c21dc5ddf3b482293ed34eead876d8d61a662c3reed
179ce9d6772df650ceb0511f275e1a83dffa78ff72reedstatic sk_sp<SkImage> make_image(SkCanvas* root, SkIRect* center) {
18b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    const int kFixed = 28;
19b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    const int kStretchy = 8;
20b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    const int kSize = 2*kFixed + kStretchy;
21cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com
22e8f3062a36d3682f4019309a32b5b84dc9eddf8creed    auto surface(make_surface(root, kSize));
234c21dc5ddf3b482293ed34eead876d8d61a662c3reed    SkCanvas* canvas = surface->getCanvas();
24d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
25b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    SkRect r = SkRect::MakeWH(SkIntToScalar(kSize), SkIntToScalar(kSize));
26b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    const SkScalar strokeWidth = SkIntToScalar(6);
27b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    const SkScalar radius = SkIntToScalar(kFixed) - strokeWidth/2;
28d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
29b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    center->setXYWH(kFixed, kFixed, kStretchy, kStretchy);
30d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
31b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    SkPaint paint;
32b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    paint.setAntiAlias(true);
33d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
34b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    paint.setColor(0xFFFF0000);
354c21dc5ddf3b482293ed34eead876d8d61a662c3reed    canvas->drawRoundRect(r, radius, radius, paint);
36b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    r.setXYWH(SkIntToScalar(kFixed), 0, SkIntToScalar(kStretchy), SkIntToScalar(kSize));
37b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    paint.setColor(0x8800FF00);
384c21dc5ddf3b482293ed34eead876d8d61a662c3reed    canvas->drawRect(r, paint);
39b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    r.setXYWH(0, SkIntToScalar(kFixed), SkIntToScalar(kSize), SkIntToScalar(kStretchy));
40b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    paint.setColor(0x880000FF);
414c21dc5ddf3b482293ed34eead876d8d61a662c3reed    canvas->drawRect(r, paint);
424c21dc5ddf3b482293ed34eead876d8d61a662c3reed
439ce9d6772df650ceb0511f275e1a83dffa78ff72reed    return surface->makeImageSnapshot();
44b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com}
45b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com
464c21dc5ddf3b482293ed34eead876d8d61a662c3reedstatic void image_to_bitmap(const SkImage* image, SkBitmap* bm) {
474c21dc5ddf3b482293ed34eead876d8d61a662c3reed    SkImageInfo info = SkImageInfo::MakeN32Premul(image->width(), image->height());
484c21dc5ddf3b482293ed34eead876d8d61a662c3reed    bm->allocPixels(info);
494c21dc5ddf3b482293ed34eead876d8d61a662c3reed    image->readPixels(info, bm->getPixels(), bm->rowBytes(), 0, 0);
504c21dc5ddf3b482293ed34eead876d8d61a662c3reed}
51d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
524c21dc5ddf3b482293ed34eead876d8d61a662c3reedclass NinePatchStretchGM : public skiagm::GM {
53b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.compublic:
549ce9d6772df650ceb0511f275e1a83dffa78ff72reed    sk_sp<SkImage>  fImage;
559ce9d6772df650ceb0511f275e1a83dffa78ff72reed    SkBitmap        fBitmap;
569ce9d6772df650ceb0511f275e1a83dffa78ff72reed    SkIRect         fCenter;
57b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com
58d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    NinePatchStretchGM() {}
59b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com
60b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.comprotected:
614c21dc5ddf3b482293ed34eead876d8d61a662c3reed    SkString onShortName() override {
62b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com        return SkString("ninepatch-stretch");
63b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    }
64b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com
654c21dc5ddf3b482293ed34eead876d8d61a662c3reed    SkISize onISize() override {
6633a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt        return SkISize::Make(760, 800);
67b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    }
68b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com
694c21dc5ddf3b482293ed34eead876d8d61a662c3reed    void onDraw(SkCanvas* canvas) override {
7096fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (nullptr == fBitmap.pixelRef()) {
719ce9d6772df650ceb0511f275e1a83dffa78ff72reed            fImage = make_image(canvas, &fCenter);
729ce9d6772df650ceb0511f275e1a83dffa78ff72reed            image_to_bitmap(fImage.get(), &fBitmap);
734c21dc5ddf3b482293ed34eead876d8d61a662c3reed        }
74d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
75b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com        // amount of bm that should not be stretched (unless we have to)
764c21dc5ddf3b482293ed34eead876d8d61a662c3reed        const SkScalar fixed = SkIntToScalar(fBitmap.width() - fCenter.width());
77d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
78fafe135349bd34961a12bfd8185733709cd0e45eHal Canary        const SkSize size[] = {
79b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com            { fixed * 4 / 5, fixed * 4 / 5 },   // shrink in both axes
80b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com            { fixed * 4 / 5, fixed * 4 },       // shrink in X
81b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com            { fixed * 4,     fixed * 4 / 5 },   // shrink in Y
82b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com            { fixed * 4,     fixed * 4 }
83b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com        };
84d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
8596fcdcc219d2a0d3579719b84b28bede76efba64halcanary        canvas->drawBitmap(fBitmap, 10, 10, nullptr);
86d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
87b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com        SkScalar x = SkIntToScalar(100);
88b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com        SkScalar y = SkIntToScalar(100);
89d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
90b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com        SkPaint paint;
9133a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt        for (int filter = 0; filter < 2; filter++) {
9233a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            paint.setFilterQuality(filter == 0 ? kLow_SkFilterQuality : kNone_SkFilterQuality);
9333a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            canvas->translate(0, filter * SkIntToScalar(400));
9433a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt            for (int iy = 0; iy < 2; ++iy) {
9533a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                for (int ix = 0; ix < 2; ++ix) {
9633a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                    int i = ix * 2 + iy;
9733a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                    SkRect r = SkRect::MakeXYWH(x + ix * fixed, y + iy * fixed,
9833a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                                                size[i].width(), size[i].height());
9933a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                    canvas->drawBitmapNine(fBitmap, fCenter, r, &paint);
1009ce9d6772df650ceb0511f275e1a83dffa78ff72reed                    canvas->drawImageNine(fImage.get(), fCenter, r.makeOffset(360, 0), &paint);
10133a5fce6126dc5d3927a71fdc6c35af6f5893fd5joshualitt                }
102b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com            }
103b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com        }
104b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com    }
105d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
106b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.comprivate:
1074c21dc5ddf3b482293ed34eead876d8d61a662c3reed    typedef skiagm::GM INHERITED;
108b67052596f8abebbbc6399c682b20a7dffeeecefreed@google.com};
1094c21dc5ddf3b482293ed34eead876d8d61a662c3reedDEF_GM( return new NinePatchStretchGM; )
110