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
make_surface(SkCanvas * root,int N)11 static 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
make_image(SkCanvas * root,SkIRect * center)20 static 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
image_to_bitmap(const SkImage * image,SkBitmap * bm)49 static 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
55 class NinePatchStretchGM : public skiagm::GM {
56 public:
57 SkAutoTUnref<SkImage> fImage;
58 SkBitmap fBitmap;
59 SkIRect fCenter;
60
NinePatchStretchGM()61 NinePatchStretchGM() {}
62
63 protected:
onShortName()64 SkString onShortName() override {
65 return SkString("ninepatch-stretch");
66 }
67
onISize()68 SkISize onISize() override {
69 return SkISize::Make(760, 800);
70 }
71
onDraw(SkCanvas * canvas)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
109 private:
110 typedef skiagm::GM INHERITED;
111 };
112 DEF_GM( return new NinePatchStretchGM; )
113
114