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