• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2011 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 #include "SampleCode.h"
9 #include "SkView.h"
10 #include "SkCanvas.h"
11 #include "SkGradientShader.h"
12 #include "SkPath.h"
13 #include "SkRegion.h"
14 #include "SkShader.h"
15 #include "SkUtils.h"
16 #include "SkColorPriv.h"
17 #include "SkColorFilter.h"
18 #include "SkTypeface.h"
19 #include "SkAvoidXfermode.h"
20 
rgb2gray(SkPMColor c)21 static inline SkPMColor rgb2gray(SkPMColor c) {
22     unsigned r = SkGetPackedR32(c);
23     unsigned g = SkGetPackedG32(c);
24     unsigned b = SkGetPackedB32(c);
25 
26     unsigned x = (r * 5 + g * 7 + b * 4) >> 4;
27 
28     return SkPackARGB32(0, x, x, x) | (c & (SK_A32_MASK << SK_A32_SHIFT));
29 }
30 
31 class SkGrayScaleColorFilter : public SkColorFilter {
32 public:
filterSpan(const SkPMColor src[],int count,SkPMColor result[])33     virtual void filterSpan(const SkPMColor src[], int count,
34                             SkPMColor result[]) {
35         for (int i = 0; i < count; i++) {
36             result[i] = rgb2gray(src[i]);
37         }
38     }
39 };
40 
41 class SkChannelMaskColorFilter : public SkColorFilter {
42 public:
SkChannelMaskColorFilter(U8CPU redMask,U8CPU greenMask,U8CPU blueMask)43     SkChannelMaskColorFilter(U8CPU redMask, U8CPU greenMask, U8CPU blueMask) {
44         fMask = SkPackARGB32(0xFF, redMask, greenMask, blueMask);
45     }
46 
filterSpan(const SkPMColor src[],int count,SkPMColor result[])47     virtual void filterSpan(const SkPMColor src[], int count,
48                             SkPMColor result[]) {
49         SkPMColor mask = fMask;
50         for (int i = 0; i < count; i++) {
51             result[i] = src[i] & mask;
52         }
53     }
54 
55 private:
56     SkPMColor   fMask;
57 };
58 
59 ///////////////////////////////////////////////////////////
60 
61 #include "SkGradientShader.h"
62 #include "SkLayerRasterizer.h"
63 #include "SkBlurMaskFilter.h"
64 
r0(SkLayerRasterizer * rast,SkPaint & p)65 static void r0(SkLayerRasterizer* rast, SkPaint& p) {
66     p.setMaskFilter(SkBlurMaskFilter::Create(SkIntToScalar(3),
67                                              SkBlurMaskFilter::kNormal_BlurStyle))->unref();
68     rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
69 
70     p.setMaskFilter(NULL);
71     p.setStyle(SkPaint::kStroke_Style);
72     p.setStrokeWidth(SK_Scalar1);
73     rast->addLayer(p);
74 
75     p.setAlpha(0x11);
76     p.setStyle(SkPaint::kFill_Style);
77     p.setXfermodeMode(SkXfermode::kSrc_Mode);
78     rast->addLayer(p);
79 }
80 
r1(SkLayerRasterizer * rast,SkPaint & p)81 static void r1(SkLayerRasterizer* rast, SkPaint& p) {
82     rast->addLayer(p);
83 
84     p.setAlpha(0x40);
85     p.setXfermodeMode(SkXfermode::kSrc_Mode);
86     p.setStyle(SkPaint::kStroke_Style);
87     p.setStrokeWidth(SK_Scalar1*2);
88     rast->addLayer(p);
89 }
90 
r2(SkLayerRasterizer * rast,SkPaint & p)91 static void r2(SkLayerRasterizer* rast, SkPaint& p) {
92     p.setStyle(SkPaint::kStrokeAndFill_Style);
93     p.setStrokeWidth(SK_Scalar1*4);
94     rast->addLayer(p);
95 
96     p.setStyle(SkPaint::kStroke_Style);
97     p.setStrokeWidth(SK_Scalar1*3/2);
98     p.setXfermodeMode(SkXfermode::kClear_Mode);
99     rast->addLayer(p);
100 }
101 
r3(SkLayerRasterizer * rast,SkPaint & p)102 static void r3(SkLayerRasterizer* rast, SkPaint& p) {
103     p.setStyle(SkPaint::kStroke_Style);
104     p.setStrokeWidth(SK_Scalar1*3);
105     rast->addLayer(p);
106 
107     p.setAlpha(0x20);
108     p.setStyle(SkPaint::kFill_Style);
109     p.setXfermodeMode(SkXfermode::kSrc_Mode);
110     rast->addLayer(p);
111 }
112 
r4(SkLayerRasterizer * rast,SkPaint & p)113 static void r4(SkLayerRasterizer* rast, SkPaint& p) {
114     p.setAlpha(0x60);
115     rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
116 
117     p.setAlpha(0xFF);
118     p.setXfermodeMode(SkXfermode::kClear_Mode);
119     rast->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2);
120 
121     p.setXfermode(NULL);
122     rast->addLayer(p);
123 }
124 
125 #include "SkDiscretePathEffect.h"
126 
r5(SkLayerRasterizer * rast,SkPaint & p)127 static void r5(SkLayerRasterizer* rast, SkPaint& p) {
128     rast->addLayer(p);
129 
130     p.setPathEffect(new SkDiscretePathEffect(SK_Scalar1*4, SK_Scalar1*3))->unref();
131     p.setXfermodeMode(SkXfermode::kSrcOut_Mode);
132     rast->addLayer(p);
133 }
134 
r6(SkLayerRasterizer * rast,SkPaint & p)135 static void r6(SkLayerRasterizer* rast, SkPaint& p) {
136     rast->addLayer(p);
137 
138     p.setAntiAlias(false);
139     SkLayerRasterizer* rast2 = new SkLayerRasterizer;
140     r5(rast2, p);
141     p.setRasterizer(rast2)->unref();
142     p.setXfermodeMode(SkXfermode::kClear_Mode);
143     rast->addLayer(p);
144 }
145 
146 #include "Sk2DPathEffect.h"
147 
MakeDotEffect(SkScalar radius,const SkMatrix & matrix)148 static SkPathEffect* MakeDotEffect(SkScalar radius, const SkMatrix& matrix) {
149     SkPath path;
150     path.addCircle(0, 0, radius);
151     return new SkPath2DPathEffect(matrix, path);
152 }
153 
r7(SkLayerRasterizer * rast,SkPaint & p)154 static void r7(SkLayerRasterizer* rast, SkPaint& p) {
155     SkMatrix    lattice;
156     lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
157     lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
158     p.setPathEffect(MakeDotEffect(SK_Scalar1*4, lattice))->unref();
159     rast->addLayer(p);
160 }
161 
r8(SkLayerRasterizer * rast,SkPaint & p)162 static void r8(SkLayerRasterizer* rast, SkPaint& p) {
163     rast->addLayer(p);
164 
165     SkMatrix    lattice;
166     lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
167     lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
168     p.setPathEffect(MakeDotEffect(SK_Scalar1*2, lattice))->unref();
169     p.setXfermodeMode(SkXfermode::kClear_Mode);
170     rast->addLayer(p);
171 
172     p.setPathEffect(NULL);
173     p.setXfermode(NULL);
174     p.setStyle(SkPaint::kStroke_Style);
175     p.setStrokeWidth(SK_Scalar1);
176     rast->addLayer(p);
177 }
178 
179 class Line2DPathEffect : public Sk2DPathEffect {
180 public:
Line2DPathEffect(SkScalar width,const SkMatrix & matrix)181     Line2DPathEffect(SkScalar width, const SkMatrix& matrix)
182         : Sk2DPathEffect(matrix), fWidth(width) {}
183 
filterPath(SkPath * dst,const SkPath & src,SkScalar * width)184 	virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width) {
185         if (this->INHERITED::filterPath(dst, src, width)) {
186             *width = fWidth;
187             return true;
188         }
189         return false;
190     }
191 
getFactory()192     virtual Factory getFactory() { return CreateProc; }
flatten(SkFlattenableWriteBuffer & buffer)193     virtual void flatten(SkFlattenableWriteBuffer& buffer) {
194         this->INHERITED::flatten(buffer);
195         buffer.writeScalar(fWidth);
196     }
197 
198 protected:
nextSpan(int u,int v,int ucount,SkPath * dst)199 	virtual void nextSpan(int u, int v, int ucount, SkPath* dst) {
200         if (ucount > 1) {
201             SkPoint	src[2], dstP[2];
202 
203             src[0].set(SkIntToScalar(u) + SK_ScalarHalf,
204                        SkIntToScalar(v) + SK_ScalarHalf);
205             src[1].set(SkIntToScalar(u+ucount) + SK_ScalarHalf,
206                        SkIntToScalar(v) + SK_ScalarHalf);
207             this->getMatrix().mapPoints(dstP, src, 2);
208 
209             dst->moveTo(dstP[0]);
210             dst->lineTo(dstP[1]);
211         }
212     }
213 
Line2DPathEffect(SkFlattenableReadBuffer & buffer)214     Line2DPathEffect(SkFlattenableReadBuffer& buffer) : Sk2DPathEffect(buffer) {
215         fWidth = buffer.readScalar();
216     }
217 
218 private:
219     SkScalar fWidth;
220 
CreateProc(SkFlattenableReadBuffer & buffer)221     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
222         return new Line2DPathEffect(buffer);
223     }
224 
225     typedef Sk2DPathEffect INHERITED;
226 };
227 
r9(SkLayerRasterizer * rast,SkPaint & p)228 static void r9(SkLayerRasterizer* rast, SkPaint& p) {
229     rast->addLayer(p);
230 
231     SkMatrix    lattice;
232     lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0);
233     lattice.postRotate(SkIntToScalar(30), 0, 0);
234     p.setPathEffect(new Line2DPathEffect(SK_Scalar1*2, lattice))->unref();
235     p.setXfermodeMode(SkXfermode::kClear_Mode);
236     rast->addLayer(p);
237 
238     p.setPathEffect(NULL);
239     p.setXfermode(NULL);
240     p.setStyle(SkPaint::kStroke_Style);
241     p.setStrokeWidth(SK_Scalar1);
242     rast->addLayer(p);
243 }
244 
245 typedef void (*raster_proc)(SkLayerRasterizer*, SkPaint&);
246 
247 static const raster_proc gRastProcs[] = {
248     r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
249 };
250 
251 static const struct {
252     SkColor fMul, fAdd;
253 } gLightingColors[] = {
254     { 0x808080, 0x800000 }, // general case
255     { 0x707070, 0x707070 }, // no-pin case
256     { 0xFFFFFF, 0x800000 }, // just-add case
257     { 0x808080, 0x000000 }, // just-mul case
258     { 0xFFFFFF, 0x000000 }  // identity case
259 };
260 
261 #include "SkXfermode.h"
262 
color_dist16(uint16_t a,uint16_t b)263 static unsigned color_dist16(uint16_t a, uint16_t b) {
264     unsigned dr = SkAbs32(SkPacked16ToR32(a) - SkPacked16ToR32(b));
265     unsigned dg = SkAbs32(SkPacked16ToG32(a) - SkPacked16ToG32(b));
266     unsigned db = SkAbs32(SkPacked16ToB32(a) - SkPacked16ToB32(b));
267 
268     return SkMax32(dr, SkMax32(dg, db));
269 }
270 
scale_dist(unsigned dist,unsigned scale)271 static unsigned scale_dist(unsigned dist, unsigned scale) {
272     dist >>= 6;
273     dist = (dist << 2) | dist;
274     dist = (dist << 4) | dist;
275     return dist;
276 
277 //    return SkAlphaMul(dist, scale);
278 }
279 
apply_shader(SkPaint * paint,int index)280 static void apply_shader(SkPaint* paint, int index) {
281     raster_proc proc = gRastProcs[index];
282     if (proc)
283     {
284         SkPaint p;
285         SkLayerRasterizer*  rast = new SkLayerRasterizer;
286 
287         p.setAntiAlias(true);
288         proc(rast, p);
289         paint->setRasterizer(rast)->unref();
290     }
291 
292 #if 0
293     SkScalar dir[] = { SK_Scalar1, SK_Scalar1, SK_Scalar1 };
294     paint->setMaskFilter(SkBlurMaskFilter::CreateEmboss(dir, SK_Scalar1/4, SkIntToScalar(4), SkIntToScalar(3)))->unref();
295 #endif
296     paint->setColor(SK_ColorBLUE);
297 }
298 
299 static int gRastIndex;
300 
301 class TextEffectView : public SampleView {
302     SkTypeface* fFace;
303 public:
TextEffectView()304 	TextEffectView() {
305         fFace = SkTypeface::CreateFromFile("/Users/reed/Downloads/p052024l.pfb");
306     }
307 
~TextEffectView()308     virtual ~TextEffectView() {
309         SkSafeUnref(fFace);
310     }
311 
312 protected:
313     // overrides from SkEventSink
onQuery(SkEvent * evt)314     virtual bool onQuery(SkEvent* evt) {
315         if (SampleCode::TitleQ(*evt)) {
316             SampleCode::TitleR(evt, "Text Effects");
317             return true;
318         }
319         return this->INHERITED::onQuery(evt);
320     }
321 
onDrawContent(SkCanvas * canvas)322     virtual void onDrawContent(SkCanvas* canvas) {
323         canvas->save();
324 //        canvas->scale(SK_Scalar1*2, SK_Scalar1*2, 0, 0);
325 
326         SkPaint     paint;
327 
328         paint.setAntiAlias(true);
329         paint.setTextSize(SkIntToScalar(56));
330         paint.setTypeface(SkTypeface::CreateFromName("sans-serif",
331                                                      SkTypeface::kBold));
332 
333         SkScalar    x = SkIntToScalar(20);
334         SkScalar    y = paint.getTextSize();
335 
336         SkString str("TextEffects");
337 
338         paint.setTypeface(fFace);
339 
340         for (size_t i = 0; i < SK_ARRAY_COUNT(gRastProcs); i++) {
341             apply_shader(&paint, i);
342 
343           //  paint.setMaskFilter(NULL);
344           //  paint.setColor(SK_ColorBLACK);
345 
346 #if 1
347             int index = i % SK_ARRAY_COUNT(gLightingColors);
348             paint.setColorFilter(SkColorFilter::CreateLightingFilter(
349                                     gLightingColors[index].fMul,
350                                     gLightingColors[index].fAdd))->unref();
351 #endif
352 
353             canvas->drawText(str.c_str(), str.size(), x, y, paint);
354 
355             y += paint.getFontSpacing();
356         }
357 
358         canvas->restore();
359     }
360 
onFindClickHandler(SkScalar x,SkScalar y)361     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
362         gRastIndex = (gRastIndex + 1) % SK_ARRAY_COUNT(gRastProcs);
363         this->inval(NULL);
364 
365         return this->INHERITED::onFindClickHandler(x, y);
366     }
367 
onClick(Click * click)368     virtual bool onClick(Click* click) {
369         return this->INHERITED::onClick(click);
370     }
371 
372 private:
373     typedef SampleView INHERITED;
374 };
375 
376 //////////////////////////////////////////////////////////////////////////////
377 
MyFactory()378 static SkView* MyFactory() { return new TextEffectView; }
379 static SkViewRegister reg(MyFactory);
380 
381