Home | History | Annotate | Download | only in gm
      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