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