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 "SkMergeImageFilter.h" 17 #include "SkOffsetImageFilter.h" 18 #include "SkTestImageFilters.h" 19 20 /////////////////////////////////////////////////////////////////////////////// 21 22 static void draw_paint(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) { 23 SkPaint paint; 24 paint.setImageFilter(imf); 25 paint.setColor(SK_ColorBLACK); 26 canvas->save(); 27 canvas->clipRect(r); 28 canvas->drawPaint(paint); 29 canvas->restore(); 30 } 31 32 static void draw_path(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) { 33 SkPaint paint; 34 paint.setColor(SK_ColorMAGENTA); 35 paint.setImageFilter(imf); 36 paint.setAntiAlias(true); 37 canvas->save(); 38 canvas->clipRect(r); 39 canvas->drawCircle(r.centerX(), r.centerY(), r.width()*2/5, paint); 40 canvas->restore(); 41 } 42 43 static void draw_text(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) { 44 SkPaint paint; 45 paint.setImageFilter(imf); 46 paint.setColor(SK_ColorGREEN); 47 paint.setAntiAlias(true); 48 paint.setTextSize(r.height()/2); 49 paint.setTextAlign(SkPaint::kCenter_Align); 50 canvas->save(); 51 canvas->clipRect(r); 52 canvas->drawText("Text", 4, r.centerX(), r.centerY(), paint); 53 canvas->restore(); 54 } 55 56 static void draw_bitmap(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) { 57 SkPaint paint; 58 59 SkIRect bounds; 60 r.roundOut(&bounds); 61 62 SkBitmap bm; 63 bm.setConfig(SkBitmap::kARGB_8888_Config, bounds.width(), bounds.height()); 64 bm.allocPixels(); 65 bm.eraseColor(SK_ColorTRANSPARENT); 66 SkCanvas c(bm); 67 draw_path(&c, r, NULL); 68 69 paint.setImageFilter(imf); 70 canvas->save(); 71 canvas->clipRect(r); 72 canvas->drawBitmap(bm, 0, 0, &paint); 73 canvas->restore(); 74 } 75 76 static void draw_sprite(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) { 77 SkPaint paint; 78 79 SkIRect bounds; 80 r.roundOut(&bounds); 81 82 SkBitmap bm; 83 bm.setConfig(SkBitmap::kARGB_8888_Config, bounds.width(), bounds.height()); 84 bm.allocPixels(); 85 bm.eraseColor(SK_ColorRED); 86 SkCanvas c(bm); 87 88 SkIRect cropRect = SkIRect::MakeXYWH(10, 10, 44, 44); 89 paint.setColor(SK_ColorGREEN); 90 c.drawRect(SkRect::Make(cropRect), paint); 91 92 paint.setImageFilter(imf); 93 SkPoint loc = { r.fLeft, r.fTop }; 94 canvas->getTotalMatrix().mapPoints(&loc, 1); 95 canvas->drawSprite(bm, 96 SkScalarRoundToInt(loc.fX), SkScalarRoundToInt(loc.fY), 97 &paint); 98 } 99 100 /////////////////////////////////////////////////////////////////////////////// 101 102 class ImageFiltersCroppedGM : public skiagm::GM { 103 public: 104 ImageFiltersCroppedGM () {} 105 106 protected: 107 108 virtual SkString onShortName() { 109 return SkString("imagefilterscropped"); 110 } 111 112 virtual SkISize onISize() { return SkISize::Make(400, 640); } 113 114 void draw_frame(SkCanvas* canvas, const SkRect& r) { 115 SkPaint paint; 116 paint.setStyle(SkPaint::kStroke_Style); 117 paint.setColor(SK_ColorRED); 118 canvas->drawRect(r, paint); 119 } 120 121 virtual uint32_t onGetFlags() const { 122 // Because of the use of drawSprite, this test is excluded 123 // from scaled replay tests because drawSprite ignores the 124 // reciprocal scale that is applied at record time, which is 125 // the intended behavior of drawSprite. 126 return kSkipScaledReplay_Flag; 127 } 128 129 virtual void onDraw(SkCanvas* canvas) { 130 void (*drawProc[])(SkCanvas*, const SkRect&, SkImageFilter*) = { 131 draw_sprite, draw_bitmap, draw_path, draw_paint, draw_text 132 }; 133 134 SkAutoTUnref<SkColorFilter> cf( 135 SkColorFilter::CreateModeFilter(SK_ColorBLUE, SkXfermode::kSrcIn_Mode)); 136 SkImageFilter::CropRect cropRect(SkRect::Make(SkIRect::MakeXYWH(10, 10, 44, 44)), SkImageFilter::CropRect::kHasAll_CropEdge); 137 SkImageFilter::CropRect bogusRect(SkRect::Make(SkIRect::MakeXYWH(-100, -100, 10, 10)), SkImageFilter::CropRect::kHasAll_CropEdge); 138 139 SkAutoTUnref<SkImageFilter> offset(new SkOffsetImageFilter( 140 SkIntToScalar(-10), SkIntToScalar(-10))); 141 142 SkAutoTUnref<SkImageFilter> cfOffset(SkColorFilterImageFilter::Create(cf.get(), offset.get())); 143 144 SkImageFilter* filters[] = { 145 NULL, 146 SkColorFilterImageFilter::Create(cf.get(), NULL, &cropRect), 147 new SkBlurImageFilter(1.0f, 1.0f, NULL, &cropRect), 148 new SkBlurImageFilter(8.0f, 0.0f, NULL, &cropRect), 149 new SkBlurImageFilter(0.0f, 8.0f, NULL, &cropRect), 150 new SkBlurImageFilter(8.0f, 8.0f, NULL, &cropRect), 151 new SkMergeImageFilter(NULL, cfOffset.get(), SkXfermode::kSrcOver_Mode, &cropRect), 152 new SkBlurImageFilter(8.0f, 8.0f, NULL, &bogusRect), 153 SkColorFilterImageFilter::Create(cf.get(), NULL, &bogusRect), 154 }; 155 156 SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64)); 157 SkScalar MARGIN = SkIntToScalar(16); 158 SkScalar DX = r.width() + MARGIN; 159 SkScalar DY = r.height() + MARGIN; 160 161 canvas->translate(MARGIN, MARGIN); 162 for (size_t j = 0; j < SK_ARRAY_COUNT(drawProc); ++j) { 163 canvas->save(); 164 for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) { 165 drawProc[j](canvas, r, filters[i]); 166 canvas->translate(0, DY); 167 } 168 canvas->restore(); 169 canvas->translate(DX, 0); 170 } 171 172 for(size_t j = 0; j < SK_ARRAY_COUNT(filters); ++j) { 173 SkSafeUnref(filters[j]); 174 } 175 } 176 177 private: 178 typedef GM INHERITED; 179 }; 180 181 /////////////////////////////////////////////////////////////////////////////// 182 183 static skiagm::GM* MyFactory(void*) { return new ImageFiltersCroppedGM; } 184 static skiagm::GMRegistry reg(MyFactory); 185