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