Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / gm / imagefiltersgraph.cpp
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 "SkDevice.h"
12 #include "SkBitmapSource.h"
13 #include "SkBlurImageFilter.h"
14 #include "SkColorFilter.h"
15 #include "SkColorFilterImageFilter.h"
16 #include "SkColorMatrixFilter.h"
17 #include "SkReadBuffer.h"
18 #include "SkWriteBuffer.h"
19 #include "SkMergeImageFilter.h"
20 #include "SkMorphologyImageFilter.h"
21 #include "SkTestImageFilters.h"
22 #include "SkXfermodeImageFilter.h"
23
24 // More closely models how Blink's OffsetFilter works as of 10/23/13. SkOffsetImageFilter doesn't
25 // perform a draw and this one does.
26 class SimpleOffsetFilter : public SkImageFilter {
27 public:
28     class Registrar {
29     public:
30         Registrar() {
31             SkFlattenable::Register("SimpleOffsetFilter",
32 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
33                                     SimpleOffsetFilter::DeepCreateProc,
34 #else
35                                     SimpleOffsetFilter::CreateProc,
36 #endif
37                                     SimpleOffsetFilter::GetFlattenableType());
38         }
39     };
40     static SkImageFilter* Create(SkScalar dx, SkScalar dy, SkImageFilter* input) {
41         return SkNEW_ARGS(SimpleOffsetFilter, (dx, dy, input));
42     }
43
44     virtual bool onFilterImage(Proxy* proxy, const SkBitmap& src, const Context& ctx,
45                                SkBitmap* dst, SkIPoint* offset) const SK_OVERRIDE {
46         SkBitmap source = src;
47         SkImageFilter* input = getInput(0);
48         SkIPoint srcOffset = SkIPoint::Make(0, 0);
49         if (input && !input->filterImage(proxy, src, ctx, &source, &srcOffset)) {
50             return false;
51         }
52
53         SkIRect bounds;
54         if (!this->applyCropRect(ctx, proxy, source, &srcOffset, &bounds, &source)) {
55             return false;
56         }
57
58         SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
59         SkCanvas canvas(device);
60         SkPaint paint;
61         paint.setXfermodeMode(SkXfermode::kSrc_Mode);
62         canvas.drawBitmap(source, fDX - bounds.left(), fDY - bounds.top(), &paint);
63         *dst = device->accessBitmap(false);
64         offset->fX += bounds.left();
65         offset->fY += bounds.top();
66         return true;
67     }
68
69     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SimpleOffsetFilter);
70
71 protected:
72 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
73     explicit SimpleOffsetFilter(SkReadBuffer& buffer)
74     : SkImageFilter(1, buffer) {
75         fDX = buffer.readScalar();
76         fDY = buffer.readScalar();
77     }
78 #endif
79
80     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
81         this->INHERITED::flatten(buffer);
82         buffer.writeScalar(fDX);
83         buffer.writeScalar(fDY);
84     }
85
86 private:
87     SimpleOffsetFilter(SkScalar dx, SkScalar dy, SkImageFilter* input)
88         : SkImageFilter(1, &input), fDX(dx), fDY(dy) {}
89
90     SkScalar fDX, fDY;
91
92     typedef SkImageFilter INHERITED;
93 };
94
95 static SimpleOffsetFilter::Registrar gReg;
96
97 SkFlattenable* SimpleOffsetFilter::CreateProc(SkReadBuffer& buffer) {
98     SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
99     SkScalar dx = buffer.readScalar();
100     SkScalar dy = buffer.readScalar();
101     return Create(dx, dy, common.getInput(0));
102 }
103
104 class ImageFiltersGraphGM : public skiagm::GM {
105 public:
106     ImageFiltersGraphGM() {}
107
108 protected:
109     virtual uint32_t onGetFlags() const SK_OVERRIDE {
110         return kSkipTiled_Flag;
111     }
112
113     virtual SkString onShortName() {
114         return SkString("imagefiltersgraph");
115     }
116
117     void make_bitmap() {
118         fBitmap.allocN32Pixels(100, 100);
119         SkCanvas canvas(fBitmap);
120         canvas.clear(0x00000000);
121         SkPaint paint;
122         paint.setAntiAlias(true);
123         sk_tool_utils::set_portable_typeface(&paint);
124         paint.setColor(0xFFFFFFFF);
125         paint.setTextSize(SkIntToScalar(96));
126         const char* str = "e";
127         canvas.drawText(str, strlen(str), SkIntToScalar(20), SkIntToScalar(70), paint);
128     }
129
130     void drawClippedBitmap(SkCanvas* canvas, const SkBitmap& bitmap, const SkPaint& paint) {
131         canvas->save();
132         canvas->clipRect(SkRect::MakeXYWH(0, 0,
133             SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height())));
134         canvas->drawBitmap(bitmap, 0, 0, &paint);
135         canvas->restore();
136     }
137
138     virtual SkISize onISize() { return SkISize::Make(500, 150); }
139
140     virtual void onOnceBeforeDraw() {
141         this->make_bitmap();
142     }
143
144     virtual void onDraw(SkCanvas* canvas) {
145         canvas->clear(0x00000000);
146         {
147             SkAutoTUnref<SkImageFilter> bitmapSource(SkBitmapSource::Create(fBitmap));
148             SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(SK_ColorRED,
149                                                          SkXfermode::kSrcIn_Mode));
150             SkAutoTUnref<SkImageFilter> blur(SkBlurImageFilter::Create(4.0f, 4.0f, bitmapSource));
151             SkAutoTUnref<SkImageFilter> erode(SkErodeImageFilter::Create(4, 4, blur));
152             SkAutoTUnref<SkImageFilter> color(SkColorFilterImageFilter::Create(cf, erode));
153             SkAutoTUnref<SkImageFilter> merge(SkMergeImageFilter::Create(blur, color));
154
155             SkPaint paint;
156             paint.setImageFilter(merge);
157             canvas->drawPaint(paint);
158             canvas->translate(SkIntToScalar(100), 0);
159         }
160         {
161             SkAutoTUnref<SkImageFilter> morph(SkDilateImageFilter::Create(5, 5));
162
163             SkScalar matrix[20] = { SK_Scalar1, 0, 0, 0, 0,
164                                     0, SK_Scalar1, 0, 0, 0,
165                                     0, 0, SK_Scalar1, 0, 0,
166                                     0, 0, 0, 0.5f, 0 };
167
168             SkAutoTUnref<SkColorFilter> matrixFilter(SkColorMatrixFilter::Create(matrix));
169             SkAutoTUnref<SkImageFilter> colorMorph(SkColorFilterImageFilter::Create(matrixFilter, morph));
170             SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(SkXfermode::kSrcOver_Mode));
171             SkAutoTUnref<SkImageFilter> blendColor(SkXfermodeImageFilter::Create(mode, colorMorph));
172
173             SkPaint paint;
174             paint.setImageFilter(blendColor);
175             drawClippedBitmap(canvas, fBitmap, paint);
176             canvas->translate(SkIntToScalar(100), 0);
177         }
178         {
179             SkScalar matrix[20] = { SK_Scalar1, 0, 0, 0, 0,
180                                     0, SK_Scalar1, 0, 0, 0,
181                                     0, 0, SK_Scalar1, 0, 0,
182                                     0, 0, 0, 0.5f, 0 };
183             SkAutoTUnref<SkColorMatrixFilter> matrixCF(SkColorMatrixFilter::Create(matrix));
184             SkAutoTUnref<SkImageFilter> matrixFilter(SkColorFilterImageFilter::Create(matrixCF));
185             SkAutoTUnref<SkImageFilter> offsetFilter(
186                 SimpleOffsetFilter::Create(10.0f, 10.f, matrixFilter));
187
188             SkAutoTUnref<SkXfermode> arith(SkArithmeticMode::Create(0, SK_Scalar1, SK_Scalar1, 0));
189             SkAutoTUnref<SkXfermodeImageFilter> arithFilter(
190                 SkXfermodeImageFilter::Create(arith, matrixFilter, offsetFilter));
191
192             SkPaint paint;
193             paint.setImageFilter(arithFilter);
194             drawClippedBitmap(canvas, fBitmap, paint);
195             canvas->translate(SkIntToScalar(100), 0);
196         }
197         {
198             SkAutoTUnref<SkImageFilter> blur(SkBlurImageFilter::Create(
199               SkIntToScalar(10), SkIntToScalar(10)));
200
201             SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(SkXfermode::kSrcIn_Mode));
202             SkImageFilter::CropRect cropRect(SkRect::MakeWH(SkIntToScalar(95), SkIntToScalar(100)));
203             SkAutoTUnref<SkImageFilter> blend(
204                 SkXfermodeImageFilter::Create(mode, blur, NULL, &cropRect));
205
206             SkPaint paint;
207             paint.setImageFilter(blend);
208             drawClippedBitmap(canvas, fBitmap, paint);
209             canvas->translate(SkIntToScalar(100), 0);
210         }
211         {
212             // Test that crop offsets are absolute, not relative to the parent's crop rect.
213             SkAutoTUnref<SkColorFilter> cf1(SkColorFilter::CreateModeFilter(SK_ColorBLUE,
214                                                                             SkXfermode::kSrcIn_Mode));
215             SkAutoTUnref<SkColorFilter> cf2(SkColorFilter::CreateModeFilter(SK_ColorGREEN,
216                                                                             SkXfermode::kSrcIn_Mode));
217             SkImageFilter::CropRect outerRect(SkRect::MakeXYWH(SkIntToScalar(10), SkIntToScalar(10),
218                                                                SkIntToScalar(80), SkIntToScalar(80)));
219             SkImageFilter::CropRect innerRect(SkRect::MakeXYWH(SkIntToScalar(20), SkIntToScalar(20),
220                                                                SkIntToScalar(60), SkIntToScalar(60)));
221             SkAutoTUnref<SkImageFilter> color1(SkColorFilterImageFilter::Create(cf1, NULL, &outerRect));
222             SkAutoTUnref<SkImageFilter> color2(SkColorFilterImageFilter::Create(cf2, color1, &innerRect));
223
224             SkPaint paint;
225             paint.setImageFilter(color2);
226             paint.setColor(0xFFFF0000);
227             canvas->drawRect(SkRect::MakeXYWH(0, 0, 100, 100), paint);
228             canvas->translate(SkIntToScalar(100), 0);
229         }
230     }
231
232 private:
233     typedef GM INHERITED;
234     SkBitmap fBitmap;
235 };
236
237 ///////////////////////////////////////////////////////////////////////////////
238
239 static skiagm::GM* MyFactory(void*) { return new ImageFiltersGraphGM; }
240 static skiagm::GMRegistry reg(MyFactory);