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