• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
10 #include "SkArithmeticMode.h"
11 #include "SkBitmapSource.h"
12 #include "SkBlurImageFilter.h"
13 #include "SkColorFilter.h"
14 #include "SkColorFilterImageFilter.h"
15 #include "SkColorMatrixFilter.h"
16 #include "SkFlattenableBuffers.h"
17 #include "SkMergeImageFilter.h"
18 #include "SkMorphologyImageFilter.h"
19 #include "SkOnce.h"
20 #include "SkTestImageFilters.h"
21 #include "SkXfermodeImageFilter.h"
22 
23 // More closely models how Blink's OffsetFilter works as of 10/23/13. SkOffsetImageFilter doesn't
24 // perform a draw and this one does.
25 class SimpleOffsetFilter : public SkImageFilter {
26 public:
SimpleOffsetFilter(SkScalar dx,SkScalar dy,SkImageFilter * input)27     SimpleOffsetFilter(SkScalar dx, SkScalar dy, SkImageFilter* input)
28     : SkImageFilter(input), fDX(dx), fDY(dy) {}
29 
onFilterImage(Proxy * proxy,const SkBitmap & src,const SkMatrix & ctm,SkBitmap * dst,SkIPoint * offset)30     virtual bool onFilterImage(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm,
31                                SkBitmap* dst, SkIPoint* offset) SK_OVERRIDE {
32         SkBitmap source = src;
33         SkImageFilter* input = getInput(0);
34         SkIPoint srcOffset = SkIPoint::Make(0, 0);
35         if (NULL != input && !input->filterImage(proxy, src, ctm, &source, &srcOffset)) {
36             return false;
37         }
38 
39         SkIRect bounds;
40         source.getBounds(&bounds);
41 
42         if (!this->applyCropRect(&bounds, ctm)) {
43             return false;
44         }
45 
46         SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
47         SkCanvas canvas(device);
48         SkPaint paint;
49         paint.setXfermodeMode(SkXfermode::kSrc_Mode);
50         canvas.drawBitmap(source, fDX - bounds.left(), fDY - bounds.top(), &paint);
51         *dst = device->accessBitmap(false);
52         offset->fX += bounds.left();
53         offset->fY += bounds.top();
54         return true;
55     }
56 
57     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SimpleOffsetFilter);
58 
59 protected:
SimpleOffsetFilter(SkFlattenableReadBuffer & buffer)60     explicit SimpleOffsetFilter(SkFlattenableReadBuffer& buffer)
61     : SkImageFilter(1, buffer) {
62         fDX = buffer.readScalar();
63         fDY = buffer.readScalar();
64     }
65 
flatten(SkFlattenableWriteBuffer & buffer) const66     virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
67         this->SkImageFilter::flatten(buffer);
68         buffer.writeScalar(fDX);
69         buffer.writeScalar(fDY);
70     }
71 
72 private:
73     SkScalar fDX, fDY;
74 };
75 
init_flattenable(int *)76 static void init_flattenable(int*) {
77     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SimpleOffsetFilter)
78 }
79 
80 class ImageFiltersGraphGM : public skiagm::GM {
81 public:
ImageFiltersGraphGM()82     ImageFiltersGraphGM() : fInitialized(false) {
83         int dummy;
84         SK_DECLARE_STATIC_ONCE(once);
85         SkOnce(&once, init_flattenable, &dummy);
86     }
87 
88 protected:
onShortName()89     virtual SkString onShortName() {
90         return SkString("imagefiltersgraph");
91     }
92 
make_bitmap()93     void make_bitmap() {
94         fBitmap.setConfig(SkBitmap::kARGB_8888_Config, 100, 100);
95         fBitmap.allocPixels();
96         SkBitmapDevice device(fBitmap);
97         SkCanvas canvas(&device);
98         canvas.clear(0x00000000);
99         SkPaint paint;
100         paint.setAntiAlias(true);
101         paint.setColor(0xFFFFFFFF);
102         paint.setTextSize(SkIntToScalar(96));
103         const char* str = "e";
104         canvas.drawText(str, strlen(str), SkIntToScalar(20), SkIntToScalar(70), paint);
105     }
106 
drawClippedBitmap(SkCanvas * canvas,const SkBitmap & bitmap,const SkPaint & paint)107     void drawClippedBitmap(SkCanvas* canvas, const SkBitmap& bitmap, const SkPaint& paint) {
108         canvas->save();
109         canvas->clipRect(SkRect::MakeXYWH(0, 0,
110             SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height())));
111         canvas->drawBitmap(bitmap, 0, 0, &paint);
112         canvas->restore();
113     }
114 
onISize()115     virtual SkISize onISize() { return SkISize::Make(500, 150); }
116 
onDraw(SkCanvas * canvas)117     virtual void onDraw(SkCanvas* canvas) {
118         if (!fInitialized) {
119             this->make_bitmap();
120             fInitialized = true;
121         }
122         canvas->clear(0x00000000);
123         {
124             SkAutoTUnref<SkImageFilter> bitmapSource(new SkBitmapSource(fBitmap));
125             SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(SK_ColorRED,
126                                                          SkXfermode::kSrcIn_Mode));
127             SkAutoTUnref<SkImageFilter> blur(new SkBlurImageFilter(4.0f, 4.0f, bitmapSource));
128             SkAutoTUnref<SkImageFilter> erode(new SkErodeImageFilter(4, 4, blur));
129             SkAutoTUnref<SkImageFilter> color(SkColorFilterImageFilter::Create(cf, erode));
130             SkAutoTUnref<SkImageFilter> merge(new SkMergeImageFilter(blur, color));
131 
132             SkPaint paint;
133             paint.setImageFilter(merge);
134             canvas->drawPaint(paint);
135             canvas->translate(SkIntToScalar(100), 0);
136         }
137         {
138             SkAutoTUnref<SkImageFilter> morph(new SkDilateImageFilter(5, 5));
139 
140             SkScalar matrix[20] = { SK_Scalar1, 0, 0, 0, 0,
141                                     0, SK_Scalar1, 0, 0, 0,
142                                     0, 0, SK_Scalar1, 0, 0,
143                                     0, 0, 0, 0.5f, 0 };
144 
145             SkAutoTUnref<SkColorFilter> matrixFilter(new SkColorMatrixFilter(matrix));
146             SkAutoTUnref<SkImageFilter> colorMorph(SkColorFilterImageFilter::Create(matrixFilter, morph));
147             SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(SkXfermode::kSrcOver_Mode));
148             SkAutoTUnref<SkImageFilter> blendColor(new SkXfermodeImageFilter(mode, colorMorph));
149 
150             SkPaint paint;
151             paint.setImageFilter(blendColor);
152             drawClippedBitmap(canvas, fBitmap, paint);
153             canvas->translate(SkIntToScalar(100), 0);
154         }
155         {
156             SkScalar matrix[20] = { SK_Scalar1, 0, 0, 0, 0,
157                                     0, SK_Scalar1, 0, 0, 0,
158                                     0, 0, SK_Scalar1, 0, 0,
159                                     0, 0, 0, 0.5f, 0 };
160             SkColorMatrixFilter matrixCF(matrix);
161             SkAutoTUnref<SkImageFilter> matrixFilter(SkColorFilterImageFilter::Create(&matrixCF));
162             SimpleOffsetFilter offsetFilter(SkIntToScalar(10), SkIntToScalar(10), matrixFilter);
163 
164             SkAutoTUnref<SkXfermode> arith(SkArithmeticMode::Create(0, SK_Scalar1, SK_Scalar1, 0));
165             SkXfermodeImageFilter arithFilter(arith, matrixFilter, &offsetFilter);
166 
167             SkPaint paint;
168             paint.setImageFilter(&arithFilter);
169             drawClippedBitmap(canvas, fBitmap, paint);
170             canvas->translate(SkIntToScalar(100), 0);
171         }
172         {
173             SkAutoTUnref<SkImageFilter> blur(new SkBlurImageFilter(
174               SkIntToScalar(10), SkIntToScalar(10)));
175 
176             SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(SkXfermode::kSrcIn_Mode));
177             SkImageFilter::CropRect cropRect(SkRect::MakeWH(SkIntToScalar(95), SkIntToScalar(100)));
178             SkAutoTUnref<SkImageFilter> blend(new SkXfermodeImageFilter(mode, blur, NULL, &cropRect));
179 
180             SkPaint paint;
181             paint.setImageFilter(blend);
182             drawClippedBitmap(canvas, fBitmap, paint);
183             canvas->translate(SkIntToScalar(100), 0);
184         }
185     }
186 
187 private:
188     typedef GM INHERITED;
189     SkBitmap fBitmap;
190     bool fInitialized;
191 };
192 
193 ///////////////////////////////////////////////////////////////////////////////
194 
MyFactory(void *)195 static skiagm::GM* MyFactory(void*) { return new ImageFiltersGraphGM; }
196 static skiagm::GMRegistry reg(MyFactory);
197