Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2011 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 "SkColorFilterImageFilter.h"
     16 #include "SkDropShadowImageFilter.h"
     17 #include "SkTestImageFilters.h"
     18 
     19 class FailImageFilter : public SkImageFilter {
     20 public:
     21     class Registrar {
     22     public:
     23         Registrar() {
     24             SkFlattenable::Register("FailImageFilter",
     25 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     26                                     FailImageFilter::DeepCreateProc,
     27 #else
     28                                     FailImageFilter::CreateProc,
     29 #endif
     30                                     FailImageFilter::GetFlattenableType());
     31         }
     32     };
     33     static FailImageFilter* Create() {
     34         return SkNEW(FailImageFilter);
     35     }
     36 
     37     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(FailImageFilter)
     38 
     39 protected:
     40     FailImageFilter() : INHERITED(0, NULL) {}
     41 
     42     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
     43                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE {
     44         return false;
     45     }
     46 
     47 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     48     FailImageFilter(SkReadBuffer& buffer) : INHERITED(0, buffer) {}
     49 #endif
     50 
     51 private:
     52     typedef SkImageFilter INHERITED;
     53 };
     54 
     55 static FailImageFilter::Registrar gReg0;
     56 
     57 SkFlattenable* FailImageFilter::CreateProc(SkReadBuffer& buffer) {
     58     SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
     59     return FailImageFilter::Create();
     60 }
     61 
     62 class IdentityImageFilter : public SkImageFilter {
     63 public:
     64     class Registrar {
     65     public:
     66         Registrar() {
     67             SkFlattenable::Register("IdentityImageFilter",
     68 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     69                                     IdentityImageFilter::DeepCreateProc,
     70 #else
     71                                     IdentityImageFilter::CreateProc,
     72 #endif
     73                                     IdentityImageFilter::GetFlattenableType());
     74         }
     75     };
     76     static IdentityImageFilter* Create(SkImageFilter* input = NULL) {
     77         return SkNEW_ARGS(IdentityImageFilter, (input));
     78     }
     79 
     80     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(IdentityImageFilter)
     81 protected:
     82     IdentityImageFilter(SkImageFilter* input) : INHERITED(1, &input) {}
     83 
     84     virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
     85                                SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE {
     86         *result = src;
     87         offset->set(0, 0);
     88         return true;
     89     }
     90 
     91 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
     92     IdentityImageFilter(SkReadBuffer& buffer) : INHERITED(1, buffer) {}
     93 #endif
     94 
     95 private:
     96     typedef SkImageFilter INHERITED;
     97 };
     98 
     99 static IdentityImageFilter::Registrar gReg1;
    100 
    101 SkFlattenable* IdentityImageFilter::CreateProc(SkReadBuffer& buffer) {
    102     SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
    103     return IdentityImageFilter::Create(common.getInput(0));
    104 }
    105 
    106 ///////////////////////////////////////////////////////////////////////////////
    107 
    108 static void draw_paint(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
    109     SkPaint paint;
    110     paint.setImageFilter(imf);
    111     paint.setColor(SK_ColorGREEN);
    112     canvas->save();
    113     canvas->clipRect(r);
    114     canvas->drawPaint(paint);
    115     canvas->restore();
    116 }
    117 
    118 static void draw_line(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
    119     SkPaint paint;
    120     paint.setColor(SK_ColorBLUE);
    121     paint.setImageFilter(imf);
    122     paint.setStrokeWidth(r.width()/10);
    123     canvas->drawLine(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
    124 }
    125 
    126 static void draw_rect(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
    127     SkPaint paint;
    128     paint.setColor(SK_ColorYELLOW);
    129     paint.setImageFilter(imf);
    130     SkRect rr(r);
    131     rr.inset(r.width()/10, r.height()/10);
    132     canvas->drawRect(rr, paint);
    133 }
    134 
    135 static void draw_path(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
    136     SkPaint paint;
    137     paint.setColor(SK_ColorMAGENTA);
    138     paint.setImageFilter(imf);
    139     paint.setAntiAlias(true);
    140     canvas->drawCircle(r.centerX(), r.centerY(), r.width()*2/5, paint);
    141 }
    142 
    143 static void draw_text(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
    144     SkPaint paint;
    145     paint.setImageFilter(imf);
    146     paint.setColor(SK_ColorCYAN);
    147     paint.setAntiAlias(true);
    148     sk_tool_utils::set_portable_typeface(&paint);
    149     paint.setTextSize(r.height()/2);
    150     paint.setTextAlign(SkPaint::kCenter_Align);
    151     canvas->drawText("Text", 4, r.centerX(), r.centerY(), paint);
    152 }
    153 
    154 static void draw_bitmap(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
    155     SkPaint paint;
    156     paint.setImageFilter(imf);
    157 
    158     SkIRect bounds;
    159     r.roundOut(&bounds);
    160 
    161     SkBitmap bm;
    162     bm.allocN32Pixels(bounds.width(), bounds.height());
    163     bm.eraseColor(SK_ColorTRANSPARENT);
    164     SkCanvas c(bm);
    165     draw_path(&c, r, NULL);
    166 
    167     canvas->drawBitmap(bm, 0, 0, &paint);
    168 }
    169 
    170 static void draw_sprite(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
    171     SkPaint paint;
    172     paint.setImageFilter(imf);
    173 
    174     SkIRect bounds;
    175     r.roundOut(&bounds);
    176 
    177     SkBitmap bm;
    178     bm.allocN32Pixels(bounds.width(), bounds.height());
    179     bm.eraseColor(SK_ColorTRANSPARENT);
    180     SkCanvas c(bm);
    181     draw_path(&c, r, NULL);
    182 
    183     SkPoint loc = { r.fLeft, r.fTop };
    184     canvas->getTotalMatrix().mapPoints(&loc, 1);
    185     canvas->drawSprite(bm,
    186                        SkScalarRoundToInt(loc.fX), SkScalarRoundToInt(loc.fY),
    187                        &paint);
    188 }
    189 
    190 ///////////////////////////////////////////////////////////////////////////////
    191 
    192 class ImageFiltersBaseGM : public skiagm::GM {
    193 public:
    194     ImageFiltersBaseGM () {}
    195 
    196 protected:
    197     virtual SkString onShortName() {
    198         return SkString("imagefiltersbase");
    199     }
    200 
    201     virtual SkISize onISize() { return SkISize::Make(700, 500); }
    202 
    203     void draw_frame(SkCanvas* canvas, const SkRect& r) {
    204         SkPaint paint;
    205         paint.setStyle(SkPaint::kStroke_Style);
    206         paint.setColor(SK_ColorRED);
    207         canvas->drawRect(r, paint);
    208     }
    209 
    210     virtual uint32_t onGetFlags() const {
    211         // Because of the use of drawSprite, this test is excluded
    212         // from scaled replay tests because drawSprite ignores the
    213         // reciprocal scale that is applied at record time, which is
    214         // the intended behavior of drawSprite.
    215         return kSkipScaledReplay_Flag | kSkipTiled_Flag;
    216     }
    217 
    218     virtual void onDraw(SkCanvas* canvas) {
    219         void (*drawProc[])(SkCanvas*, const SkRect&, SkImageFilter*) = {
    220             draw_paint,
    221             draw_line, draw_rect, draw_path, draw_text,
    222             draw_bitmap,
    223             draw_sprite
    224         };
    225 
    226         SkColorFilter* cf = SkColorFilter::CreateModeFilter(SK_ColorRED,
    227                                                      SkXfermode::kSrcIn_Mode);
    228         SkImageFilter* filters[] = {
    229             NULL,
    230             IdentityImageFilter::Create(),
    231             FailImageFilter::Create(),
    232             SkColorFilterImageFilter::Create(cf),
    233             SkBlurImageFilter::Create(12.0f, 0.0f),
    234             SkDropShadowImageFilter::Create(10.0f, 5.0f, 3.0f, 3.0f, SK_ColorBLUE),
    235         };
    236         cf->unref();
    237 
    238         SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
    239         SkScalar MARGIN = SkIntToScalar(16);
    240         SkScalar DX = r.width() + MARGIN;
    241         SkScalar DY = r.height() + MARGIN;
    242 
    243         canvas->translate(MARGIN, MARGIN);
    244         for (size_t i = 0; i < SK_ARRAY_COUNT(drawProc); ++i) {
    245             canvas->save();
    246             for (size_t j = 0; j < SK_ARRAY_COUNT(filters); ++j) {
    247                 drawProc[i](canvas, r, filters[j]);
    248 
    249                 draw_frame(canvas, r);
    250                 canvas->translate(0, DY);
    251             }
    252             canvas->restore();
    253             canvas->translate(DX, 0);
    254         }
    255 
    256         for(size_t j = 0; j < SK_ARRAY_COUNT(filters); ++j) {
    257             SkSafeUnref(filters[j]);
    258         }
    259     }
    260 
    261 private:
    262     typedef GM INHERITED;
    263 };
    264 
    265 ///////////////////////////////////////////////////////////////////////////////
    266 
    267 static skiagm::GM* MyFactory(void*) { return new ImageFiltersBaseGM; }
    268 static skiagm::GMRegistry reg(MyFactory);
    269