1 /* 2 * Copyright 2014 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 "SkCanvas.h" 10 #include "SkColorFilter.h" 11 #include "SkColorPriv.h" 12 #include "SkShader.h" 13 14 #include "SkBlurImageFilter.h" 15 #include "SkColorMatrixFilter.h" 16 #include "SkDisplacementMapEffect.h" 17 #include "SkDropShadowImageFilter.h" 18 #include "SkGradientShader.h" 19 #include "SkImageSource.h" 20 #include "SkMorphologyImageFilter.h" 21 #include "SkColorFilterImageFilter.h" 22 #include "SkLightingImageFilter.h" 23 #include "SkMergeImageFilter.h" 24 #include "SkOffsetImageFilter.h" 25 #include "SkPoint3.h" 26 #include "SkSurface.h" 27 28 namespace { 29 30 void make_checkerboard(SkBitmap* bitmap); 31 sk_sp<SkImage> make_gradient_circle(int width, int height); 32 void draw(SkCanvas* canvas, const SkBitmap& bitmap, const SkRect& rect, 33 sk_sp<SkImageFilter> filter); 34 35 }; 36 37 /////////////////////////////////////////////////////////////////////////////// 38 39 DEF_SIMPLE_GM(imagefilterscropexpand, canvas, 730, 650) { 40 SkImageFilter::CropRect cropRect( 41 SkRect::Make(SkIRect::MakeXYWH(10, 10, 44, 44)), 42 SkImageFilter::CropRect::kHasAll_CropEdge); 43 44 sk_sp<SkImage> gradientCircle(make_gradient_circle(64, 64)); 45 SkBitmap checkerboard; 46 make_checkerboard(&checkerboard); 47 48 sk_sp<SkImageFilter> gradientCircleSource(SkImageSource::Make(std::move(gradientCircle))); 49 sk_sp<SkImageFilter> noopCropped(SkOffsetImageFilter::Make(0, 0, nullptr, &cropRect)); 50 // This color matrix saturates the green component but only partly increases the opacity. 51 // For the opaque checkerboard, the opacity boost doesn't matter but it does impact the 52 // area outside the checkerboard. 53 SkScalar matrix[20] = { 1, 0, 0, 0, 0, 54 0, 1, 0, 0, 255, 55 0, 0, 1, 0, 0, 56 0, 0, 0, 1, 32 }; 57 sk_sp<SkColorFilter> cfAlphaTrans(SkColorFilter::MakeMatrixFilterRowMajor255(matrix)); 58 59 SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64)); 60 SkScalar MARGIN = SkIntToScalar(12); 61 62 SkPoint3 pointLocation = SkPoint3::Make(0, 0, SkIntToScalar(10)); 63 SkScalar kd = SkIntToScalar(2); 64 SkScalar surfaceScale = SkIntToScalar(1); 65 SkIRect bounds; 66 r.roundOut(&bounds); 67 68 SkPaint paint; 69 canvas->translate(MARGIN, MARGIN); 70 for (int outset = -15; outset <= 20; outset += 5) { 71 canvas->save(); 72 SkRect rect = cropRect.rect(); 73 rect.outset(SkIntToScalar(outset), 74 SkIntToScalar(outset)); 75 SkImageFilter::CropRect bigRect(rect, SkImageFilter::CropRect::kHasAll_CropEdge); 76 77 draw(canvas, checkerboard, rect, SkColorFilterImageFilter::Make(cfAlphaTrans, 78 noopCropped, 79 &bigRect)); 80 81 draw(canvas, checkerboard, rect, SkBlurImageFilter::Make(0.3f, 0.3f, 82 noopCropped, 83 &bigRect)); 84 85 draw(canvas, checkerboard, rect, SkBlurImageFilter::Make(8.0f, 8.0f, 86 noopCropped, 87 &bigRect)); 88 89 draw(canvas, checkerboard, rect, SkDilateImageFilter::Make(2, 2, 90 noopCropped, 91 &bigRect)); 92 93 draw(canvas, checkerboard, rect, SkErodeImageFilter::Make(2, 2, 94 noopCropped, 95 &bigRect)); 96 97 draw(canvas, checkerboard, rect, 98 SkDropShadowImageFilter::Make( 99 SkIntToScalar(10), 100 SkIntToScalar(10), 101 SkIntToScalar(3), 102 SkIntToScalar(3), 103 SK_ColorBLUE, 104 SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, 105 noopCropped, 106 &bigRect)); 107 108 draw(canvas, checkerboard, rect, 109 SkDisplacementMapEffect::Make(SkDisplacementMapEffect::kR_ChannelSelectorType, 110 SkDisplacementMapEffect::kR_ChannelSelectorType, 111 SkIntToScalar(12), 112 gradientCircleSource, 113 noopCropped, 114 &bigRect)); 115 116 draw(canvas, checkerboard, rect, 117 SkOffsetImageFilter::Make(SkIntToScalar(-8), SkIntToScalar(16), 118 noopCropped, 119 &bigRect)); 120 121 draw(canvas, checkerboard, rect, 122 SkLightingImageFilter::MakePointLitDiffuse(pointLocation, 123 SK_ColorWHITE, 124 surfaceScale, 125 kd, 126 noopCropped, 127 &bigRect)); 128 129 canvas->restore(); 130 canvas->translate(0, SkIntToScalar(80)); 131 } 132 } 133 134 namespace { make_checkerboard(SkBitmap * bitmap)135 void make_checkerboard(SkBitmap* bitmap) { 136 bitmap->allocN32Pixels(64, 64); 137 SkCanvas canvas(*bitmap); 138 canvas.clear(0xFFFF0000); 139 SkPaint darkPaint; 140 darkPaint.setColor(0xFF404040); 141 SkPaint lightPaint; 142 lightPaint.setColor(0xFFA0A0A0); 143 for (int y = 8; y < 48; y += 16) { 144 for (int x = 8; x < 48; x += 16) { 145 canvas.save(); 146 canvas.translate(SkIntToScalar(x), SkIntToScalar(y)); 147 canvas.drawRect(SkRect::MakeXYWH(0, 0, 8, 8), darkPaint); 148 canvas.drawRect(SkRect::MakeXYWH(8, 0, 8, 8), lightPaint); 149 canvas.drawRect(SkRect::MakeXYWH(0, 8, 8, 8), lightPaint); 150 canvas.drawRect(SkRect::MakeXYWH(8, 8, 8, 8), darkPaint); 151 canvas.restore(); 152 } 153 } 154 } 155 make_gradient_circle(int width,int height)156 sk_sp<SkImage> make_gradient_circle(int width, int height) { 157 SkScalar x = SkIntToScalar(width / 2); 158 SkScalar y = SkIntToScalar(height / 2); 159 SkScalar radius = SkMinScalar(x, y) * 0.8f; 160 auto surface(SkSurface::MakeRasterN32Premul(width, height)); 161 SkCanvas* canvas = surface->getCanvas(); 162 canvas->clear(0x00000000); 163 SkColor colors[2]; 164 colors[0] = SK_ColorWHITE; 165 colors[1] = SK_ColorBLACK; 166 SkPaint paint; 167 paint.setShader(SkGradientShader::MakeRadial(SkPoint::Make(x, y), radius, colors, nullptr, 168 2, SkShader::kClamp_TileMode)); 169 canvas->drawCircle(x, y, radius, paint); 170 171 return surface->makeImageSnapshot(); 172 } 173 draw(SkCanvas * canvas,const SkBitmap & bitmap,const SkRect & rect,sk_sp<SkImageFilter> filter)174 void draw(SkCanvas* canvas, const SkBitmap& bitmap, const SkRect& rect, 175 sk_sp<SkImageFilter> filter) { 176 SkPaint paint; 177 paint.setImageFilter(std::move(filter)); 178 canvas->saveLayer(&rect, &paint); 179 canvas->drawBitmap(bitmap, 0, 0); 180 canvas->restore(); 181 182 SkPaint strokePaint; 183 strokePaint.setColor(0xFFFF0000); 184 strokePaint.setStyle(SkPaint::kStroke_Style); 185 canvas->drawRect(rect, strokePaint); 186 187 canvas->translate(SkIntToScalar(80), 0); 188 } 189 }; 190