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