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