Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2015 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 "SkBlurImageFilter.h"
     10 #include "SkColor.h"
     11 #include "SkDisplacementMapEffect.h"
     12 #include "SkDropShadowImageFilter.h"
     13 #include "SkGradientShader.h"
     14 #include "SkImage.h"
     15 #include "SkImageSource.h"
     16 #include "SkMorphologyImageFilter.h"
     17 #include "SkScalar.h"
     18 #include "SkSurface.h"
     19 #include "gm.h"
     20 
     21 namespace skiagm {
     22 
     23 // This GM draws image filters with a CTM containing shearing / rotation.
     24 // It checks that the scale portion of the CTM is correctly extracted
     25 // and applied to the image inputs separately from the non-scale portion.
     26 
     27 static SkImage* make_gradient_circle(int width, int height) {
     28     SkScalar x = SkIntToScalar(width / 2);
     29     SkScalar y = SkIntToScalar(height / 2);
     30     SkScalar radius = SkMinScalar(x, y) * 0.8f;
     31 
     32     SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(width, height));
     33     SkCanvas* canvas = surface->getCanvas();
     34 
     35     canvas->clear(0x00000000);
     36     SkColor colors[2];
     37     colors[0] = SK_ColorWHITE;
     38     colors[1] = SK_ColorBLACK;
     39     SkAutoTUnref<SkShader> shader(
     40         SkGradientShader::CreateRadial(SkPoint::Make(x, y), radius, colors, nullptr, 2,
     41                                        SkShader::kClamp_TileMode)
     42     );
     43     SkPaint paint;
     44     paint.setShader(shader);
     45     canvas->drawCircle(x, y, radius, paint);
     46 
     47     return surface->newImageSnapshot();
     48 }
     49 
     50 class ImageFiltersTransformedGM : public GM {
     51 public:
     52     ImageFiltersTransformedGM() {
     53         this->setBGColor(SK_ColorBLACK);
     54     }
     55 
     56 protected:
     57 
     58     SkString onShortName() override { return SkString("imagefilterstransformed"); }
     59 
     60     SkISize onISize() override { return SkISize::Make(420, 240); }
     61 
     62     void onOnceBeforeDraw() override {
     63         fCheckerboard.reset(SkImage::NewFromBitmap(
     64             sk_tool_utils::create_checkerboard_bitmap(64, 64, 0xFFA0A0A0, 0xFF404040, 8)));
     65         fGradientCircle.reset(make_gradient_circle(64, 64));
     66     }
     67 
     68     void onDraw(SkCanvas* canvas) override {
     69         SkAutoTUnref<SkImageFilter> gradient(SkImageSource::Create(fGradientCircle));
     70         SkAutoTUnref<SkImageFilter> checkerboard(SkImageSource::Create(fCheckerboard));
     71         SkImageFilter* filters[] = {
     72             SkBlurImageFilter::Create(12, 0),
     73             SkDropShadowImageFilter::Create(0, 15, 8, 0, SK_ColorGREEN,
     74                 SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode),
     75             SkDisplacementMapEffect::Create(SkDisplacementMapEffect::kR_ChannelSelectorType,
     76                                             SkDisplacementMapEffect::kR_ChannelSelectorType,
     77                                             12,
     78                                             gradient.get(),
     79                                             checkerboard.get()),
     80             SkDilateImageFilter::Create(2, 2, checkerboard.get()),
     81             SkErodeImageFilter::Create(2, 2, checkerboard.get()),
     82         };
     83 
     84         const SkScalar margin = SkIntToScalar(20);
     85         const SkScalar size = SkIntToScalar(60);
     86 
     87         for (size_t j = 0; j < 3; j++) {
     88             canvas->save();
     89             canvas->translate(margin, 0);
     90             for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
     91                 SkPaint paint;
     92                 paint.setColor(SK_ColorWHITE);
     93                 paint.setImageFilter(filters[i]);
     94                 paint.setAntiAlias(true);
     95                 canvas->save();
     96                 canvas->translate(size * SK_ScalarHalf, size * SK_ScalarHalf);
     97                 canvas->scale(SkDoubleToScalar(0.8), SkDoubleToScalar(0.8));
     98                 if (j == 1) {
     99                     canvas->rotate(SkIntToScalar(45));
    100                 } else if (j == 2) {
    101                     canvas->skew(SkDoubleToScalar(0.5), SkDoubleToScalar(0.2));
    102                 }
    103                 canvas->translate(-size * SK_ScalarHalf, -size * SK_ScalarHalf);
    104                 canvas->drawOval(SkRect::MakeXYWH(0, size * SkDoubleToScalar(0.1),
    105                                                   size, size * SkDoubleToScalar(0.6)), paint);
    106                 canvas->restore();
    107                 canvas->translate(size + margin, 0);
    108             }
    109             canvas->restore();
    110             canvas->translate(0, size + margin);
    111         }
    112 
    113         for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
    114             SkSafeUnref(filters[i]);
    115         }
    116     }
    117 
    118 private:
    119     SkAutoTUnref<SkImage> fCheckerboard;
    120     SkAutoTUnref<SkImage> fGradientCircle;
    121     typedef GM INHERITED;
    122 };
    123 
    124 //////////////////////////////////////////////////////////////////////////////
    125 
    126 DEF_GM( return new ImageFiltersTransformedGM; )
    127 
    128 }
    129