Upstream version 9.38.198.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     static SkImageFilter* Create(SkScalar dx, SkScalar dy, SkImageFilter* input) {
29         return SkNEW_ARGS(SimpleOffsetFilter, (dx, dy, input));
30     }
31
32     virtual bool onFilterImage(Proxy* proxy, const SkBitmap& src, const Context& ctx,
33                                SkBitmap* dst, SkIPoint* offset) const SK_OVERRIDE {
34         SkBitmap source = src;
35         SkImageFilter* input = getInput(0);
36         SkIPoint srcOffset = SkIPoint::Make(0, 0);
37         if (NULL != input && !input->filterImage(proxy, src, ctx, &source, &srcOffset)) {
38             return false;
39         }
40
41         SkIRect bounds;
42         if (!this->applyCropRect(ctx, proxy, source, &srcOffset, &bounds, &source)) {
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:
60     explicit SimpleOffsetFilter(SkReadBuffer& buffer)
61     : SkImageFilter(1, buffer) {
62         fDX = buffer.readScalar();
63         fDY = buffer.readScalar();
64     }
65
66     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
67         this->SkImageFilter::flatten(buffer);
68         buffer.writeScalar(fDX);
69         buffer.writeScalar(fDY);
70     }
71
72 private:
73     SimpleOffsetFilter(SkScalar dx, SkScalar dy, SkImageFilter* input)
74     : SkImageFilter(1, &input), fDX(dx), fDY(dy) {}
75
76     SkScalar fDX, fDY;
77 };
78
79 SkFlattenable::Registrar registrar("SimpleOffsetFilter",
80                                    SimpleOffsetFilter::CreateProc,
81                                    SimpleOffsetFilter::GetFlattenableType());
82
83 class ImageFiltersGraphGM : public skiagm::GM {
84 public:
85     ImageFiltersGraphGM() {}
86
87 protected:
88     virtual uint32_t onGetFlags() const SK_OVERRIDE {
89         return kSkipTiled_Flag;
90     }
91
92     virtual SkString onShortName() {
93         return SkString("imagefiltersgraph");
94     }
95
96     void make_bitmap() {
97         fBitmap.allocN32Pixels(100, 100);
98         SkCanvas canvas(fBitmap);
99         canvas.clear(0x00000000);
100         SkPaint paint;
101         paint.setAntiAlias(true);
102         sk_tool_utils::set_portable_typeface(&paint);
103         paint.setColor(0xFFFFFFFF);
104         paint.setTextSize(SkIntToScalar(96));
105         const char* str = "e";
106         canvas.drawText(str, strlen(str), SkIntToScalar(20), SkIntToScalar(70), paint);
107     }
108
109     void drawClippedBitmap(SkCanvas* canvas, const SkBitmap& bitmap, const SkPaint& paint) {
110         canvas->save();
111         canvas->clipRect(SkRect::MakeXYWH(0, 0,
112             SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height())));
113         canvas->drawBitmap(bitmap, 0, 0, &paint);
114         canvas->restore();
115     }
116
117     virtual SkISize onISize() { return SkISize::Make(500, 150); }
118
119     virtual void onOnceBeforeDraw() {
120         this->make_bitmap();
121     }
122
123     virtual void onDraw(SkCanvas* canvas) {
124         canvas->clear(0x00000000);
125         {
126             SkAutoTUnref<SkImageFilter> bitmapSource(SkBitmapSource::Create(fBitmap));
127             SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(SK_ColorRED,
128                                                          SkXfermode::kSrcIn_Mode));
129             SkAutoTUnref<SkImageFilter> blur(SkBlurImageFilter::Create(4.0f, 4.0f, bitmapSource));
130             SkAutoTUnref<SkImageFilter> erode(SkErodeImageFilter::Create(4, 4, blur));
131             SkAutoTUnref<SkImageFilter> color(SkColorFilterImageFilter::Create(cf, erode));
132             SkAutoTUnref<SkImageFilter> merge(SkMergeImageFilter::Create(blur, color));
133
134             SkPaint paint;
135             paint.setImageFilter(merge);
136             canvas->drawPaint(paint);
137             canvas->translate(SkIntToScalar(100), 0);
138         }
139         {
140             SkAutoTUnref<SkImageFilter> morph(SkDilateImageFilter::Create(5, 5));
141
142             SkScalar matrix[20] = { SK_Scalar1, 0, 0, 0, 0,
143                                     0, SK_Scalar1, 0, 0, 0,
144                                     0, 0, SK_Scalar1, 0, 0,
145                                     0, 0, 0, 0.5f, 0 };
146
147             SkAutoTUnref<SkColorFilter> matrixFilter(SkColorMatrixFilter::Create(matrix));
148             SkAutoTUnref<SkImageFilter> colorMorph(SkColorFilterImageFilter::Create(matrixFilter, morph));
149             SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(SkXfermode::kSrcOver_Mode));
150             SkAutoTUnref<SkImageFilter> blendColor(SkXfermodeImageFilter::Create(mode, colorMorph));
151
152             SkPaint paint;
153             paint.setImageFilter(blendColor);
154             drawClippedBitmap(canvas, fBitmap, paint);
155             canvas->translate(SkIntToScalar(100), 0);
156         }
157         {
158             SkScalar matrix[20] = { SK_Scalar1, 0, 0, 0, 0,
159                                     0, SK_Scalar1, 0, 0, 0,
160                                     0, 0, SK_Scalar1, 0, 0,
161                                     0, 0, 0, 0.5f, 0 };
162             SkAutoTUnref<SkColorMatrixFilter> matrixCF(SkColorMatrixFilter::Create(matrix));
163             SkAutoTUnref<SkImageFilter> matrixFilter(SkColorFilterImageFilter::Create(matrixCF));
164             SkAutoTUnref<SkImageFilter> offsetFilter(
165                 SimpleOffsetFilter::Create(10.0f, 10.f, matrixFilter));
166
167             SkAutoTUnref<SkXfermode> arith(SkArithmeticMode::Create(0, SK_Scalar1, SK_Scalar1, 0));
168             SkAutoTUnref<SkXfermodeImageFilter> arithFilter(
169                 SkXfermodeImageFilter::Create(arith, matrixFilter, offsetFilter));
170
171             SkPaint paint;
172             paint.setImageFilter(arithFilter);
173             drawClippedBitmap(canvas, fBitmap, paint);
174             canvas->translate(SkIntToScalar(100), 0);
175         }
176         {
177             SkAutoTUnref<SkImageFilter> blur(SkBlurImageFilter::Create(
178               SkIntToScalar(10), SkIntToScalar(10)));
179
180             SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(SkXfermode::kSrcIn_Mode));
181             SkImageFilter::CropRect cropRect(SkRect::MakeWH(SkIntToScalar(95), SkIntToScalar(100)));
182             SkAutoTUnref<SkImageFilter> blend(
183                 SkXfermodeImageFilter::Create(mode, blur, NULL, &cropRect));
184
185             SkPaint paint;
186             paint.setImageFilter(blend);
187             drawClippedBitmap(canvas, fBitmap, paint);
188             canvas->translate(SkIntToScalar(100), 0);
189         }
190         {
191             // Test that crop offsets are absolute, not relative to the parent's crop rect.
192             SkAutoTUnref<SkColorFilter> cf1(SkColorFilter::CreateModeFilter(SK_ColorBLUE,
193                                                                             SkXfermode::kSrcIn_Mode));
194             SkAutoTUnref<SkColorFilter> cf2(SkColorFilter::CreateModeFilter(SK_ColorGREEN,
195                                                                             SkXfermode::kSrcIn_Mode));
196             SkImageFilter::CropRect outerRect(SkRect::MakeXYWH(SkIntToScalar(10), SkIntToScalar(10),
197                                                                SkIntToScalar(80), SkIntToScalar(80)));
198             SkImageFilter::CropRect innerRect(SkRect::MakeXYWH(SkIntToScalar(20), SkIntToScalar(20),
199                                                                SkIntToScalar(60), SkIntToScalar(60)));
200             SkAutoTUnref<SkImageFilter> color1(SkColorFilterImageFilter::Create(cf1, NULL, &outerRect));
201             SkAutoTUnref<SkImageFilter> color2(SkColorFilterImageFilter::Create(cf2, color1, &innerRect));
202
203             SkPaint paint;
204             paint.setImageFilter(color2);
205             paint.setColor(0xFFFF0000);
206             canvas->drawRect(SkRect::MakeXYWH(0, 0, 100, 100), paint);
207             canvas->translate(SkIntToScalar(100), 0);
208         }
209     }
210
211 private:
212     typedef GM INHERITED;
213     SkBitmap fBitmap;
214 };
215
216 ///////////////////////////////////////////////////////////////////////////////
217
218 static skiagm::GM* MyFactory(void*) { return new ImageFiltersGraphGM; }
219 static skiagm::GMRegistry reg(MyFactory);