blob: 9b9e0551ed842de4b32c70514818d2365256a6ba [file] [log] [blame]
senorblanco@chromium.orgf1369ce2012-08-20 14:53:21 +00001/*
2 * Copyright 2012 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
commit-bot@chromium.orgbbfe4542013-10-24 01:46:11 +000010#include "SkArithmeticMode.h"
senorblanco@chromium.orgf1369ce2012-08-20 14:53:21 +000011#include "SkBitmapSource.h"
12#include "SkBlurImageFilter.h"
senorblanco@chromium.org44888c62012-08-20 19:23:24 +000013#include "SkColorFilter.h"
senorblanco@chromium.org985fa792012-10-24 15:14:26 +000014#include "SkColorMatrixFilter.h"
senorblanco@chromium.org44888c62012-08-20 19:23:24 +000015#include "SkColorFilterImageFilter.h"
commit-bot@chromium.orgbbfe4542013-10-24 01:46:11 +000016#include "SkFlattenableBuffers.h"
senorblanco@chromium.org4a9a6122012-12-04 14:18:50 +000017#include "SkMergeImageFilter.h"
senorblanco@chromium.orgf1369ce2012-08-20 14:53:21 +000018#include "SkMorphologyImageFilter.h"
commit-bot@chromium.orgbbfe4542013-10-24 01:46:11 +000019#include "SkOnce.h"
senorblanco@chromium.org350b4d52013-08-01 14:59:05 +000020#include "SkXfermodeImageFilter.h"
senorblanco@chromium.orgf1369ce2012-08-20 14:53:21 +000021
22#include "SkTestImageFilters.h"
23
24///////////////////////////////////////////////////////////////////////////////
25
commit-bot@chromium.orgbbfe4542013-10-24 01:46:11 +000026namespace {
27// More closely models how Blink's OffsetFilter works as of 10/23/13. SkOffsetImageFilter doesn't
28// perform a draw and this one does.
29class SimpleOffsetFilter : public SkImageFilter {
30public:
31 SimpleOffsetFilter(SkScalar dx, SkScalar dy, SkImageFilter* input)
32 : SkImageFilter(input), fDX(dx), fDY(dy) {}
33
34 virtual bool onFilterImage(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm,
35 SkBitmap* dst, SkIPoint* offset) SK_OVERRIDE {
36 SkBitmap source = src;
37 SkImageFilter* input = getInput(0);
38 SkIPoint srcOffset = SkIPoint::Make(0, 0);
39 if (NULL != input && !input->filterImage(proxy, src, ctm, &source, &srcOffset)) {
40 return false;
41 }
42
43 SkIRect bounds;
44 source.getBounds(&bounds);
45
46 if (!this->applyCropRect(&bounds, ctm)) {
47 return false;
48 }
49
50 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
51 SkCanvas canvas(device);
52 SkPaint paint;
53 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
54 canvas.drawBitmap(source, fDX - bounds.left(), fDY - bounds.top(), &paint);
55 *dst = device->accessBitmap(false);
56 offset->fX += bounds.left();
57 offset->fY += bounds.top();
58 return true;
59 }
60
61 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SimpleOffsetFilter);
62
63protected:
64 explicit SimpleOffsetFilter(SkFlattenableReadBuffer& buffer)
65 : SkImageFilter(buffer) {
66 fDX = buffer.readScalar();
67 fDY = buffer.readScalar();
68 }
69
70 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
71 this->SkImageFilter::flatten(buffer);
72 buffer.writeScalar(fDX);
73 buffer.writeScalar(fDY);
74 }
75
76private:
77 SkScalar fDX, fDY;
78};
79}
80
81static void init_flattenable(int*) {
82 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SimpleOffsetFilter)
83}
84
senorblanco@chromium.orgf1369ce2012-08-20 14:53:21 +000085class ImageFiltersGraphGM : public skiagm::GM {
86public:
commit-bot@chromium.orgbbfe4542013-10-24 01:46:11 +000087 ImageFiltersGraphGM() : fInitialized(false) {
88 int dummy;
89 SK_DECLARE_STATIC_ONCE(once);
90 SkOnce(&once, init_flattenable, &dummy);
91 }
senorblanco@chromium.orgf1369ce2012-08-20 14:53:21 +000092
93protected:
senorblanco@chromium.orgf1369ce2012-08-20 14:53:21 +000094 virtual SkString onShortName() {
95 return SkString("imagefiltersgraph");
96 }
97
98 void make_bitmap() {
99 fBitmap.setConfig(SkBitmap::kARGB_8888_Config, 100, 100);
100 fBitmap.allocPixels();
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000101 SkBitmapDevice device(fBitmap);
senorblanco@chromium.orgf1369ce2012-08-20 14:53:21 +0000102 SkCanvas canvas(&device);
103 canvas.clear(0x00000000);
104 SkPaint paint;
105 paint.setAntiAlias(true);
106 paint.setColor(0xFFFFFFFF);
107 paint.setTextSize(SkIntToScalar(96));
108 const char* str = "e";
109 canvas.drawText(str, strlen(str), SkIntToScalar(20), SkIntToScalar(70), paint);
110 }
111
senorblanco@chromium.org34a849d2013-10-24 15:59:31 +0000112 void drawClippedBitmap(SkCanvas* canvas, const SkBitmap& bitmap, const SkPaint& paint) {
113 canvas->save();
114 canvas->clipRect(SkRect::MakeXYWH(0, 0,
115 SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height())));
116 canvas->drawBitmap(bitmap, 0, 0, &paint);
117 canvas->restore();
118 }
119
commit-bot@chromium.orgbbfe4542013-10-24 01:46:11 +0000120 virtual SkISize onISize() { return SkISize::Make(500, 150); }
senorblanco@chromium.orgf1369ce2012-08-20 14:53:21 +0000121
122 virtual void onDraw(SkCanvas* canvas) {
123 if (!fInitialized) {
124 this->make_bitmap();
125 fInitialized = true;
126 }
127 canvas->clear(0x00000000);
senorblanco@chromium.org985fa792012-10-24 15:14:26 +0000128 {
129 SkAutoTUnref<SkImageFilter> bitmapSource(new SkBitmapSource(fBitmap));
130 SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(SK_ColorRED,
131 SkXfermode::kSrcIn_Mode));
132 SkAutoTUnref<SkImageFilter> blur(new SkBlurImageFilter(4.0f, 4.0f, bitmapSource));
133 SkAutoTUnref<SkImageFilter> erode(new SkErodeImageFilter(4, 4, blur));
senorblanco@chromium.orgcd9f5592012-10-26 19:37:00 +0000134 SkAutoTUnref<SkImageFilter> color(SkColorFilterImageFilter::Create(cf, erode));
senorblanco@chromium.org985fa792012-10-24 15:14:26 +0000135 SkAutoTUnref<SkImageFilter> merge(new SkMergeImageFilter(blur, color));
rmistry@google.comae933ce2012-08-23 18:19:56 +0000136
senorblanco@chromium.org985fa792012-10-24 15:14:26 +0000137 SkPaint paint;
138 paint.setImageFilter(merge);
139 canvas->drawPaint(paint);
senorblanco@chromium.org34a849d2013-10-24 15:59:31 +0000140 canvas->translate(SkIntToScalar(100), 0);
senorblanco@chromium.org985fa792012-10-24 15:14:26 +0000141 }
142 {
143 SkAutoTUnref<SkImageFilter> morph(new SkDilateImageFilter(5, 5));
senorblanco@chromium.orgf1369ce2012-08-20 14:53:21 +0000144
senorblanco@chromium.org985fa792012-10-24 15:14:26 +0000145 SkScalar matrix[20] = { SK_Scalar1, 0, 0, 0, 0,
146 0, SK_Scalar1, 0, 0, 0,
147 0, 0, SK_Scalar1, 0, 0,
148 0, 0, 0, SkFloatToScalar(0.5f), 0 };
senorblanco@chromium.orgf1369ce2012-08-20 14:53:21 +0000149
senorblanco@chromium.org985fa792012-10-24 15:14:26 +0000150 SkAutoTUnref<SkColorFilter> matrixFilter(new SkColorMatrixFilter(matrix));
senorblanco@chromium.orgcd9f5592012-10-26 19:37:00 +0000151 SkAutoTUnref<SkImageFilter> colorMorph(SkColorFilterImageFilter::Create(matrixFilter, morph));
senorblanco@chromium.org350b4d52013-08-01 14:59:05 +0000152 SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(SkXfermode::kSrcOver_Mode));
153 SkAutoTUnref<SkImageFilter> blendColor(new SkXfermodeImageFilter(mode, colorMorph));
senorblanco@chromium.org985fa792012-10-24 15:14:26 +0000154
155 SkPaint paint;
156 paint.setImageFilter(blendColor);
senorblanco@chromium.org34a849d2013-10-24 15:59:31 +0000157 drawClippedBitmap(canvas, fBitmap, paint);
158 canvas->translate(SkIntToScalar(100), 0);
senorblanco@chromium.org985fa792012-10-24 15:14:26 +0000159 }
commit-bot@chromium.orgbbfe4542013-10-24 01:46:11 +0000160 {
161 SkScalar matrix[20] = { SK_Scalar1, 0, 0, 0, 0,
162 0, SK_Scalar1, 0, 0, 0,
163 0, 0, SK_Scalar1, 0, 0,
164 0, 0, 0, SkFloatToScalar(0.5f), 0 };
165 SkColorMatrixFilter matrixCF(matrix);
166 SkAutoTUnref<SkImageFilter> matrixFilter(SkColorFilterImageFilter::Create(&matrixCF));
167 SimpleOffsetFilter offsetFilter(SkIntToScalar(10), SkIntToScalar(10), matrixFilter);
168
169 SkAutoTUnref<SkXfermode> arith(SkArithmeticMode::Create(0, SK_Scalar1, SK_Scalar1, 0));
170 SkXfermodeImageFilter arithFilter(arith, matrixFilter, &offsetFilter);
171
172 SkPaint paint;
173 paint.setImageFilter(&arithFilter);
senorblanco@chromium.org34a849d2013-10-24 15:59:31 +0000174 drawClippedBitmap(canvas, fBitmap, paint);
175 canvas->translate(SkIntToScalar(100), 0);
176 }
177 {
178 SkAutoTUnref<SkImageFilter> blur(new SkBlurImageFilter(
179 SkIntToScalar(10), SkIntToScalar(10)));
180
181 SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(SkXfermode::kSrcIn_Mode));
182 SkImageFilter::CropRect cropRect(SkRect::MakeWH(SkIntToScalar(95), SkIntToScalar(100)));
183 SkAutoTUnref<SkImageFilter> blend(new SkXfermodeImageFilter(mode, blur, NULL, &cropRect));
184
185 SkPaint paint;
186 paint.setImageFilter(blend);
187 drawClippedBitmap(canvas, fBitmap, paint);
188 canvas->translate(SkIntToScalar(100), 0);
commit-bot@chromium.orgbbfe4542013-10-24 01:46:11 +0000189 }
senorblanco@chromium.orgf1369ce2012-08-20 14:53:21 +0000190 }
191
192private:
193 typedef GM INHERITED;
194 SkBitmap fBitmap;
195 bool fInitialized;
196};
197
198///////////////////////////////////////////////////////////////////////////////
199
200static skiagm::GM* MyFactory(void*) { return new ImageFiltersGraphGM; }
201static skiagm::GMRegistry reg(MyFactory);