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