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