1 /* 2 * Copyright 2013 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 "sk_tool_utils.h" 9 #include "SkImage.h" 10 #include "SkImageSource.h" 11 #include "SkOffsetImageFilter.h" 12 #include "SkSurface.h" 13 #include "gm.h" 14 15 #define WIDTH 600 16 #define HEIGHT 100 17 #define MARGIN 12 18 19 class OffsetImageFilterGM : public skiagm::GM { 20 public: 21 OffsetImageFilterGM() { 22 this->setBGColor(0xFF000000); 23 } 24 25 protected: 26 SkString onShortName() override { 27 return SkString("offsetimagefilter"); 28 } 29 30 SkISize onISize() override { 31 return SkISize::Make(WIDTH, HEIGHT); 32 } 33 34 void onOnceBeforeDraw() override { 35 fBitmap.reset(SkImage::NewFromBitmap( 36 sk_tool_utils::create_string_bitmap(80, 80, 0xD000D000, 15, 65, 96, "e"))); 37 38 fCheckerboard.reset(SkImage::NewFromBitmap( 39 sk_tool_utils::create_checkerboard_bitmap(80, 80, 40 sk_tool_utils::color_to_565(0xFFA0A0A0), 41 sk_tool_utils::color_to_565(0xFF404040), 42 8))); 43 } 44 45 void onDraw(SkCanvas* canvas) override { 46 canvas->clear(SK_ColorBLACK); 47 SkPaint paint; 48 49 for (int i = 0; i < 4; i++) { 50 const SkImage* image = (i & 0x01) ? fCheckerboard : fBitmap; 51 SkIRect cropRect = SkIRect::MakeXYWH(i * 12, 52 i * 8, 53 image->width() - i * 8, 54 image->height() - i * 12); 55 SkImageFilter::CropRect rect(SkRect::Make(cropRect)); 56 SkAutoTUnref<SkImageFilter> tileInput(SkImageSource::Create(image)); 57 SkScalar dx = SkIntToScalar(i*5); 58 SkScalar dy = SkIntToScalar(i*10); 59 SkAutoTUnref<SkImageFilter> filter(SkOffsetImageFilter::Create(dx, dy, tileInput, 60 &rect)); 61 paint.setImageFilter(filter); 62 DrawClippedImage(canvas, image, paint, 1, cropRect); 63 canvas->translate(SkIntToScalar(image->width() + MARGIN), 0); 64 } 65 66 SkIRect cropRect = SkIRect::MakeXYWH(0, 0, 100, 100); 67 SkImageFilter::CropRect rect(SkRect::Make(cropRect)); 68 SkAutoTUnref<SkImageFilter> filter(SkOffsetImageFilter::Create(-5, -10, nullptr, &rect)); 69 paint.setImageFilter(filter); 70 DrawClippedImage(canvas, fBitmap, paint, 2, cropRect); 71 } 72 private: 73 static void DrawClippedImage(SkCanvas* canvas, const SkImage* image, const SkPaint& paint, 74 SkScalar scale, const SkIRect& cropRect) { 75 SkRect clipRect = SkRect::MakeIWH(image->width(), image->height()); 76 77 canvas->save(); 78 canvas->clipRect(clipRect); 79 canvas->scale(scale, scale); 80 canvas->drawImage(image, 0, 0, &paint); 81 canvas->restore(); 82 83 // Draw a boundary rect around the intersection of the clip rect and crop rect. 84 SkRect cropRectFloat; 85 SkMatrix::MakeScale(scale, scale).mapRect(&cropRectFloat, SkRect::Make(cropRect)); 86 if (clipRect.intersect(cropRectFloat)) { 87 SkPaint strokePaint; 88 strokePaint.setStyle(SkPaint::kStroke_Style); 89 strokePaint.setStrokeWidth(2); 90 strokePaint.setColor(SK_ColorRED); 91 canvas->drawRect(clipRect, strokePaint); 92 } 93 } 94 95 SkAutoTUnref<SkImage> fBitmap, fCheckerboard; 96 97 typedef skiagm::GM INHERITED; 98 }; 99 DEF_GM( return new OffsetImageFilterGM; ) 100 101 ////////////////////////////////////////////////////////////////////////////// 102 103 class SimpleOffsetImageFilterGM : public skiagm::GM { 104 public: 105 SimpleOffsetImageFilterGM() {} 106 107 protected: 108 SkString onShortName() override { 109 return SkString("simple-offsetimagefilter"); 110 } 111 112 SkISize onISize() override { return SkISize::Make(640, 200); } 113 114 void doDraw(SkCanvas* canvas, const SkRect& r, SkImageFilter* imgf, 115 const SkRect* clipR = nullptr) { 116 SkPaint p; 117 118 if (clipR) { 119 p.setColor(0xFF00FF00); 120 p.setStyle(SkPaint::kStroke_Style); 121 canvas->drawRect(clipR->makeInset(SK_ScalarHalf, SK_ScalarHalf), p); 122 p.setStyle(SkPaint::kFill_Style); 123 } 124 125 if (imgf && imgf->cropRectIsSet()) { 126 SkImageFilter::CropRect cr = imgf->getCropRect(); 127 128 p.setColor(0x66FF00FF); 129 p.setStyle(SkPaint::kStroke_Style); 130 canvas->drawRect(cr.rect().makeInset(SK_ScalarHalf, SK_ScalarHalf), p); 131 p.setStyle(SkPaint::kFill_Style); 132 } 133 134 p.setColor(0x660000FF); 135 canvas->drawRect(r, p); 136 137 if (clipR) { 138 canvas->save(); 139 canvas->clipRect(*clipR); 140 } 141 if (imgf) { 142 p.setImageFilter(imgf)->unref(); 143 } 144 p.setColor(0x66FF0000); 145 canvas->drawRect(r, p); 146 147 if (clipR) { 148 canvas->restore(); 149 } 150 } 151 152 void onDraw(SkCanvas* canvas) override { 153 const SkRect r = SkRect::MakeWH(40, 40); 154 SkImageFilter::CropRect cr0(r); 155 SkImageFilter::CropRect cr1(SkRect::MakeWH(20, 20)); 156 const SkRect r2 = SkRect::MakeXYWH(40, 0, 40, 40); 157 SkImageFilter::CropRect cr2(r2); 158 159 canvas->translate(40, 40); 160 161 canvas->save(); 162 this->doDraw(canvas, r, nullptr); 163 164 canvas->translate(100, 0); 165 this->doDraw(canvas, r, SkOffsetImageFilter::Create(20, 20)); 166 167 canvas->translate(100, 0); 168 this->doDraw(canvas, r, SkOffsetImageFilter::Create(20, 20, nullptr, &cr0)); 169 170 canvas->translate(100, 0); 171 this->doDraw(canvas, r, SkOffsetImageFilter::Create(20, 20), &r); 172 173 canvas->translate(100, 0); 174 this->doDraw(canvas, r, SkOffsetImageFilter::Create(20, 20, nullptr, &cr1)); 175 176 SkRect clipR = SkRect::MakeXYWH(40, 40, 40, 40); 177 canvas->translate(100, 0); 178 this->doDraw(canvas, r, SkOffsetImageFilter::Create(20, 20, nullptr, nullptr), &clipR); 179 canvas->restore(); 180 181 // 2nd row 182 canvas->translate(0, 80); 183 184 /* 185 * combos of clip and crop rects that align with src and dst 186 */ 187 188 // crop==clip==src 189 this->doDraw(canvas, r, SkOffsetImageFilter::Create(40, 0, nullptr, &cr0), &r); 190 191 // crop==src, clip==dst 192 canvas->translate(100, 0); 193 this->doDraw(canvas, r, SkOffsetImageFilter::Create(40, 0, nullptr, &cr0), &r2); 194 195 // crop==dst, clip==src 196 canvas->translate(100, 0); 197 this->doDraw(canvas, r, SkOffsetImageFilter::Create(40, 0, nullptr, &cr2), &r); 198 199 // crop==clip==dst 200 canvas->translate(100, 0); 201 this->doDraw(canvas, r, SkOffsetImageFilter::Create(40, 0, nullptr, &cr2), &r2); 202 } 203 204 private: 205 typedef skiagm::GM INHERITED; 206 }; 207 DEF_GM( return new SimpleOffsetImageFilterGM; ) 208