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 11 static sk_sp<SkSurface> make_surface(SkCanvas* root, int N) { 12 SkImageInfo info = SkImageInfo::MakeN32Premul(N, N); 13 auto surface = root->makeSurface(info); 14 if (!surface) { 15 surface = SkSurface::MakeRaster(info); 16 } 17 return surface; 18 } 19 20 static sk_sp<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 auto 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->makeImageSnapshot(); 47 } 48 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 sk_sp<SkImage> fImage; 58 SkBitmap fBitmap; 59 SkIRect fCenter; 60 61 NinePatchStretchGM() {} 62 63 protected: 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 = make_image(canvas, &fCenter); 75 image_to_bitmap(fImage.get(), &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.get(), 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