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 "SkBlurMask.h"
10#include "SkBlurMaskFilter.h"
11#include "SkReadBuffer.h"
12#include "SkWriteBuffer.h"
13#include "SkLayerRasterizer.h"
14
15static void r0(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
16    p.setMaskFilter(SkBlurMaskFilter::Create(kNormal_SkBlurStyle,
17                              SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3))))->unref();
18    rastBuilder->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
19
20    p.setMaskFilter(NULL);
21    p.setStyle(SkPaint::kStroke_Style);
22    p.setStrokeWidth(SK_Scalar1);
23    rastBuilder->addLayer(p);
24
25    p.setAlpha(0x11);
26    p.setStyle(SkPaint::kFill_Style);
27    p.setXfermodeMode(SkXfermode::kSrc_Mode);
28    rastBuilder->addLayer(p);
29}
30
31static void r1(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
32    rastBuilder->addLayer(p);
33
34    p.setAlpha(0x40);
35    p.setXfermodeMode(SkXfermode::kSrc_Mode);
36    p.setStyle(SkPaint::kStroke_Style);
37    p.setStrokeWidth(SK_Scalar1*2);
38    rastBuilder->addLayer(p);
39}
40
41static void r2(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
42    p.setStyle(SkPaint::kStrokeAndFill_Style);
43    p.setStrokeWidth(SK_Scalar1*4);
44    rastBuilder->addLayer(p);
45
46    p.setStyle(SkPaint::kStroke_Style);
47    p.setStrokeWidth(SK_Scalar1*3/2);
48    p.setXfermodeMode(SkXfermode::kClear_Mode);
49    rastBuilder->addLayer(p);
50}
51
52static void r3(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
53    p.setStyle(SkPaint::kStroke_Style);
54    p.setStrokeWidth(SK_Scalar1*3);
55    rastBuilder->addLayer(p);
56
57    p.setAlpha(0x20);
58    p.setStyle(SkPaint::kFill_Style);
59    p.setXfermodeMode(SkXfermode::kSrc_Mode);
60    rastBuilder->addLayer(p);
61}
62
63static void r4(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
64    p.setAlpha(0x60);
65    rastBuilder->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
66
67    p.setAlpha(0xFF);
68    p.setXfermodeMode(SkXfermode::kClear_Mode);
69    rastBuilder->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2);
70
71    p.setXfermode(NULL);
72    rastBuilder->addLayer(p);
73}
74
75#include "SkDiscretePathEffect.h"
76
77static void r5(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
78    rastBuilder->addLayer(p);
79
80    p.setPathEffect(SkDiscretePathEffect::Create(SK_Scalar1*4, SK_Scalar1*3))->unref();
81    p.setXfermodeMode(SkXfermode::kSrcOut_Mode);
82    rastBuilder->addLayer(p);
83}
84
85static void r6(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
86    rastBuilder->addLayer(p);
87
88    p.setAntiAlias(false);
89    SkLayerRasterizer::Builder rastBuilder2;
90    r5(&rastBuilder2, p);
91    p.setRasterizer(rastBuilder2.detachRasterizer())->unref();
92    p.setXfermodeMode(SkXfermode::kClear_Mode);
93    rastBuilder->addLayer(p);
94}
95
96#include "Sk2DPathEffect.h"
97
98static SkPathEffect* MakeDotEffect(SkScalar radius, const SkMatrix& matrix) {
99    SkPath path;
100    path.addCircle(0, 0, radius);
101    return SkPath2DPathEffect::Create(matrix, path);
102}
103
104static void r7(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
105    SkMatrix    lattice;
106    lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
107    lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
108    p.setPathEffect(MakeDotEffect(SK_Scalar1*4, lattice))->unref();
109    rastBuilder->addLayer(p);
110}
111
112static void r8(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
113    rastBuilder->addLayer(p);
114
115    SkMatrix    lattice;
116    lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
117    lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
118    p.setPathEffect(MakeDotEffect(SK_Scalar1*2, lattice))->unref();
119    p.setXfermodeMode(SkXfermode::kClear_Mode);
120    rastBuilder->addLayer(p);
121
122    p.setPathEffect(NULL);
123    p.setXfermode(NULL);
124    p.setStyle(SkPaint::kStroke_Style);
125    p.setStrokeWidth(SK_Scalar1);
126    rastBuilder->addLayer(p);
127}
128
129static void r9(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
130    rastBuilder->addLayer(p);
131
132    SkMatrix    lattice;
133    lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0);
134    lattice.postRotate(SkIntToScalar(30), 0, 0);
135    p.setPathEffect(SkLine2DPathEffect::Create(SK_Scalar1*2, lattice))->unref();
136    p.setXfermodeMode(SkXfermode::kClear_Mode);
137    rastBuilder->addLayer(p);
138
139    p.setPathEffect(NULL);
140    p.setXfermode(NULL);
141    p.setStyle(SkPaint::kStroke_Style);
142    p.setStrokeWidth(SK_Scalar1);
143    rastBuilder->addLayer(p);
144}
145
146typedef void (*raster_proc)(SkLayerRasterizer::Builder*, SkPaint&);
147
148static const raster_proc gRastProcs[] = {
149    r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
150};
151
152#include "SkXfermode.h"
153
154static void apply_shader(SkPaint* paint, int index) {
155    raster_proc proc = gRastProcs[index];
156    if (proc)
157    {
158        SkPaint p;
159        SkLayerRasterizer::Builder rastBuilder;
160
161        p.setAntiAlias(true);
162        proc(&rastBuilder, p);
163        paint->setRasterizer(rastBuilder.detachRasterizer())->unref();
164    }
165
166#if 0
167    SkScalar dir[] = { SK_Scalar1, SK_Scalar1, SK_Scalar1 };
168    paint->setMaskFilter(SkBlurMaskFilter::CreateEmboss(dir, SK_Scalar1/4, SkIntToScalar(4), SkIntToScalar(3)))->unref();
169#endif
170    paint->setColor(SK_ColorBLUE);
171}
172
173class TextEffectsGM : public skiagm::GM {
174public:
175    TextEffectsGM() {}
176
177protected:
178    virtual SkString onShortName() SK_OVERRIDE {
179        return SkString("texteffects");
180    }
181
182    virtual SkISize onISize() SK_OVERRIDE {
183        return SkISize::Make(460, 680);
184    }
185
186    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
187        canvas->save();
188
189        SkPaint     paint;
190        paint.setAntiAlias(true);
191        sk_tool_utils::set_portable_typeface(&paint);
192        paint.setTextSize(SkIntToScalar(56));
193
194        SkScalar    x = SkIntToScalar(20);
195        SkScalar    y = paint.getTextSize();
196
197        SkString str("Hamburgefons");
198
199        for (int i = 0; i < static_cast<int>(SK_ARRAY_COUNT(gRastProcs)); i++) {
200            apply_shader(&paint, i);
201
202            //  paint.setMaskFilter(NULL);
203            //  paint.setColor(SK_ColorBLACK);
204
205            canvas->drawText(str.c_str(), str.size(), x, y, paint);
206
207            y += paint.getFontSpacing();
208        }
209
210        canvas->restore();
211    }
212
213private:
214    typedef skiagm::GM INHERITED;
215};
216
217//////////////////////////////////////////////////////////////////////////////
218
219static skiagm::GM* MyFactory(void*) { return new TextEffectsGM; }
220static skiagm::GMRegistry reg(MyFactory);
221