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