blob: b85064265a329531da87390cca505472e07ea175 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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 */
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#include "SampleCode.h"
9#include "SkCanvas.h"
10#include "SkView.h"
11#include "Sk1DPathEffect.h"
12#include "Sk2DPathEffect.h"
13#include "SkAvoidXfermode.h"
14#include "SkBlurMaskFilter.h"
15#include "SkColorFilter.h"
16#include "SkColorPriv.h"
17#include "SkCornerPathEffect.h"
18#include "SkDashPathEffect.h"
19#include "SkDiscretePathEffect.h"
20#include "SkEmbossMaskFilter.h"
djsollen@google.comc73dd5c2012-08-07 15:54:32 +000021#include "SkFlattenableBuffers.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000022#include "SkGradientShader.h"
23#include "SkImageDecoder.h"
24#include "SkLayerRasterizer.h"
25#include "SkMath.h"
26#include "SkPath.h"
27#include "SkRegion.h"
28#include "SkShader.h"
reed@android.comaa5a7db2009-05-27 01:20:10 +000029#include "SkComposeShader.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000030#include "SkCornerPathEffect.h"
31#include "SkPathMeasure.h"
32#include "SkPicture.h"
33#include "SkRandom.h"
34#include "SkTransparentShader.h"
35#include "SkTypeface.h"
36#include "SkUnitMappers.h"
37#include "SkUtils.h"
38#include "SkXfermode.h"
39
40#include <math.h>
rmistry@google.comae933ce2012-08-23 18:19:56 +000041
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000042static inline SkPMColor rgb2gray(SkPMColor c) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000043 unsigned r = SkGetPackedR32(c);
44 unsigned g = SkGetPackedG32(c);
45 unsigned b = SkGetPackedB32(c);
rmistry@google.comae933ce2012-08-23 18:19:56 +000046
reed@android.comf2b98d62010-12-20 18:26:13 +000047 unsigned x = (r * 5 + g * 7 + b * 4) >> 4;
rmistry@google.comae933ce2012-08-23 18:19:56 +000048
reed@android.com8a1c16f2008-12-17 15:59:43 +000049 return SkPackARGB32(0, x, x, x) | (c & (SK_A32_MASK << SK_A32_SHIFT));
50}
51
52class SkGrayScaleColorFilter : public SkColorFilter {
53public:
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000054 virtual void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000055 for (int i = 0; i < count; i++)
56 result[i] = rgb2gray(src[i]);
57 }
58};
59
60class SkChannelMaskColorFilter : public SkColorFilter {
61public:
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000062 SkChannelMaskColorFilter(U8CPU redMask, U8CPU greenMask, U8CPU blueMask) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000063 fMask = SkPackARGB32(0xFF, redMask, greenMask, blueMask);
64 }
65
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000066 virtual void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000067 SkPMColor mask = fMask;
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000068 for (int i = 0; i < count; i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000069 result[i] = src[i] & mask;
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000070 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000071 }
rmistry@google.comae933ce2012-08-23 18:19:56 +000072
reed@android.com8a1c16f2008-12-17 15:59:43 +000073private:
74 SkPMColor fMask;
75};
76
77///////////////////////////////////////////////////////////
78
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000079static void r0(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000080 p.setMaskFilter(SkBlurMaskFilter::Create(SkIntToScalar(3),
81 SkBlurMaskFilter::kNormal_BlurStyle))->unref();
82 rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
83
84 p.setMaskFilter(NULL);
85 p.setStyle(SkPaint::kStroke_Style);
86 p.setStrokeWidth(SK_Scalar1);
87 rast->addLayer(p);
88
89 p.setAlpha(0x11);
90 p.setStyle(SkPaint::kFill_Style);
reed@android.com0baf1932009-06-24 12:41:42 +000091 p.setXfermodeMode(SkXfermode::kSrc_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +000092 rast->addLayer(p);
93}
94
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000095static void r1(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000096 rast->addLayer(p);
97
98 p.setAlpha(0x40);
reed@android.com0baf1932009-06-24 12:41:42 +000099 p.setXfermodeMode(SkXfermode::kSrc_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000100 p.setStyle(SkPaint::kStroke_Style);
101 p.setStrokeWidth(SK_Scalar1*2);
102 rast->addLayer(p);
103}
rmistry@google.comae933ce2012-08-23 18:19:56 +0000104
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000105static void r2(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000106 p.setStyle(SkPaint::kStrokeAndFill_Style);
107 p.setStrokeWidth(SK_Scalar1*4);
108 rast->addLayer(p);
109
110 p.setStyle(SkPaint::kStroke_Style);
111 p.setStrokeWidth(SK_Scalar1*3/2);
reed@android.com0baf1932009-06-24 12:41:42 +0000112 p.setXfermodeMode(SkXfermode::kClear_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000113 rast->addLayer(p);
114}
115
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000116static void r3(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000117 p.setStyle(SkPaint::kStroke_Style);
118 p.setStrokeWidth(SK_Scalar1*3);
119 rast->addLayer(p);
120
121 p.setAlpha(0x20);
122 p.setStyle(SkPaint::kFill_Style);
reed@android.com0baf1932009-06-24 12:41:42 +0000123 p.setXfermodeMode(SkXfermode::kSrc_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000124 rast->addLayer(p);
125}
126
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000127static void r4(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000128 p.setAlpha(0x60);
129 rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
130
131 p.setAlpha(0xFF);
reed@android.com0baf1932009-06-24 12:41:42 +0000132 p.setXfermodeMode(SkXfermode::kClear_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000133 rast->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2);
134
135 p.setXfermode(NULL);
136 rast->addLayer(p);
137}
138
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000139static void r5(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000140 rast->addLayer(p);
141
142 p.setPathEffect(new SkDiscretePathEffect(SK_Scalar1*4, SK_Scalar1*3))->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000143 p.setXfermodeMode(SkXfermode::kSrcOut_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000144 rast->addLayer(p);
145}
146
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000147static void r6(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000148 rast->addLayer(p);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000149
reed@android.com8a1c16f2008-12-17 15:59:43 +0000150 p.setAntiAlias(false);
151 SkLayerRasterizer* rast2 = new SkLayerRasterizer;
152 r5(rast2, p);
153 p.setRasterizer(rast2)->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000154 p.setXfermodeMode(SkXfermode::kClear_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000155 rast->addLayer(p);
156}
157
158class Dot2DPathEffect : public Sk2DPathEffect {
159public:
160 Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix)
161 : Sk2DPathEffect(matrix), fRadius(radius) {}
162
djsollen@google.comba28d032012-03-26 17:57:35 +0000163 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Dot2DPathEffect)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000164
165protected:
rmistry@google.comae933ce2012-08-23 18:19:56 +0000166 virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000167 dst->addCircle(loc.fX, loc.fY, fRadius);
168 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000169
djsollen@google.com54924242012-03-29 15:18:04 +0000170 Dot2DPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000171 fRadius = buffer.readScalar();
172 }
djsollen@google.com54924242012-03-29 15:18:04 +0000173 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
174 this->INHERITED::flatten(buffer);
175 buffer.writeScalar(fRadius);
176 }
177
reed@android.com8a1c16f2008-12-17 15:59:43 +0000178private:
179 SkScalar fRadius;
180
reed@android.com8a1c16f2008-12-17 15:59:43 +0000181 typedef Sk2DPathEffect INHERITED;
182};
183
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000184static void r7(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000185 SkMatrix lattice;
186 lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
187 lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
188 p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*4, lattice))->unref();
189 rast->addLayer(p);
190}
191
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000192static void r8(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000193 rast->addLayer(p);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000194
reed@android.com8a1c16f2008-12-17 15:59:43 +0000195 SkMatrix lattice;
196 lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
197 lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
198 p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*2, lattice))->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000199 p.setXfermodeMode(SkXfermode::kClear_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000200 rast->addLayer(p);
201
202 p.setPathEffect(NULL);
203 p.setXfermode(NULL);
204 p.setStyle(SkPaint::kStroke_Style);
205 p.setStrokeWidth(SK_Scalar1);
206 rast->addLayer(p);
207}
208
209class Line2DPathEffect : public Sk2DPathEffect {
210public:
211 Line2DPathEffect(SkScalar width, const SkMatrix& matrix)
212 : Sk2DPathEffect(matrix), fWidth(width) {}
213
rmistry@google.comae933ce2012-08-23 18:19:56 +0000214 virtual bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec) SK_OVERRIDE {
reed@google.comfd4be262012-05-25 01:04:12 +0000215 if (this->INHERITED::filterPath(dst, src, rec)) {
216 rec->setStrokeStyle(fWidth);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000217 return true;
218 }
219 return false;
220 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000221
djsollen@google.comba28d032012-03-26 17:57:35 +0000222 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Line2DPathEffect)
223
reed@android.com8a1c16f2008-12-17 15:59:43 +0000224protected:
rmistry@google.comae933ce2012-08-23 18:19:56 +0000225 virtual void nextSpan(int u, int v, int ucount, SkPath* dst) {
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000226 if (ucount > 1) {
rmistry@google.comae933ce2012-08-23 18:19:56 +0000227 SkPoint src[2], dstP[2];
reed@android.com8a1c16f2008-12-17 15:59:43 +0000228
229 src[0].set(SkIntToScalar(u) + SK_ScalarHalf,
230 SkIntToScalar(v) + SK_ScalarHalf);
231 src[1].set(SkIntToScalar(u+ucount) + SK_ScalarHalf,
232 SkIntToScalar(v) + SK_ScalarHalf);
233 this->getMatrix().mapPoints(dstP, src, 2);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000234
reed@android.com8a1c16f2008-12-17 15:59:43 +0000235 dst->moveTo(dstP[0]);
236 dst->lineTo(dstP[1]);
237 }
238 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000239
djsollen@google.com54924242012-03-29 15:18:04 +0000240 Line2DPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000241 fWidth = buffer.readScalar();
242 }
djsollen@google.com54924242012-03-29 15:18:04 +0000243 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
244 this->INHERITED::flatten(buffer);
245 buffer.writeScalar(fWidth);
246 }
247
reed@android.com8a1c16f2008-12-17 15:59:43 +0000248private:
249 SkScalar fWidth;
250
reed@android.com8a1c16f2008-12-17 15:59:43 +0000251 typedef Sk2DPathEffect INHERITED;
252};
253
scroggo@google.com6eb0d622012-06-25 20:32:12 +0000254SK_DEFINE_FLATTENABLE_REGISTRAR(Line2DPathEffect)
255
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000256static void r9(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000257 rast->addLayer(p);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000258
reed@android.com8a1c16f2008-12-17 15:59:43 +0000259 SkMatrix lattice;
260 lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0);
261 lattice.postRotate(SkIntToScalar(30), 0, 0);
262 p.setPathEffect(new Line2DPathEffect(SK_Scalar1*2, lattice))->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000263 p.setXfermodeMode(SkXfermode::kClear_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000264 rast->addLayer(p);
265
266 p.setPathEffect(NULL);
267 p.setXfermode(NULL);
268 p.setStyle(SkPaint::kStroke_Style);
269 p.setStrokeWidth(SK_Scalar1);
270 rast->addLayer(p);
271}
272
273typedef void (*raster_proc)(SkLayerRasterizer*, SkPaint&);
274
275static const raster_proc gRastProcs[] = {
276 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
277};
278
279static const struct {
280 SkColor fMul, fAdd;
281} gLightingColors[] = {
282 { 0x808080, 0x800000 }, // general case
283 { 0x707070, 0x707070 }, // no-pin case
284 { 0xFFFFFF, 0x800000 }, // just-add case
285 { 0x808080, 0x000000 }, // just-mul case
286 { 0xFFFFFF, 0x000000 } // identity case
287};
288
rmistry@google.comae933ce2012-08-23 18:19:56 +0000289static void apply_shader(SkPaint* paint, int index) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000290 raster_proc proc = gRastProcs[index];
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000291 if (proc) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000292 SkPaint p;
293 SkLayerRasterizer* rast = new SkLayerRasterizer;
294
295 p.setAntiAlias(true);
296 proc(rast, p);
297 paint->setRasterizer(rast)->unref();
298 }
299
300#if 1
301 SkScalar dir[] = { SK_Scalar1, SK_Scalar1, SK_Scalar1 };
rmistry@google.comae933ce2012-08-23 18:19:56 +0000302 paint->setMaskFilter(SkBlurMaskFilter::CreateEmboss(dir, SK_Scalar1/4, SkIntToScalar(4), SkIntToScalar(3)))->unref();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000303 paint->setColor(SK_ColorBLUE);
304#endif
305}
306
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000307class DemoView : public SampleView {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000308public:
reed@google.com2f3dc9d2011-05-02 17:33:45 +0000309 DemoView() {}
rmistry@google.comae933ce2012-08-23 18:19:56 +0000310
reed@android.com8a1c16f2008-12-17 15:59:43 +0000311protected:
312 // overrides from SkEventSink
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000313 virtual bool onQuery(SkEvent* evt) {
314 if (SampleCode::TitleQ(*evt)) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000315 SampleCode::TitleR(evt, "Demo");
316 return true;
317 }
318 return this->INHERITED::onQuery(evt);
319 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000320
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000321 virtual bool onClick(Click* click) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000322 return this->INHERITED::onClick(click);
323 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000324
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000325 void makePath(SkPath& path) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000326 path.addCircle(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(20),
327 SkPath::kCCW_Direction);
328 for (int index = 0; index < 10; index++) {
caryclark@google.com02939ce2012-06-06 12:09:51 +0000329 SkScalar x = SkFloatToScalar((float) cos(index / 10.0f * 2 * 3.1415925358f));
330 SkScalar y = SkFloatToScalar((float) sin(index / 10.0f * 2 * 3.1415925358f));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000331 x *= index & 1 ? 7 : 14;
332 y *= index & 1 ? 7 : 14;
333 x += SkIntToScalar(20);
334 y += SkIntToScalar(20);
335 if (index == 0)
336 path.moveTo(x, y);
337 else
338 path.lineTo(x, y);
339 }
340 path.close();
341 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000342
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000343 virtual void onDrawContent(SkCanvas* canvas) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000344 canvas->save();
345 drawPicture(canvas, 0);
346 canvas->restore();
347
348 {
349 SkPicture picture;
350 SkCanvas* record = picture.beginRecording(320, 480);
351 drawPicture(record, 120);
352 canvas->translate(0, SkIntToScalar(120));
353
354 SkRect clip;
355 clip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
356 do {
357 canvas->save();
358 canvas->clipRect(clip);
359 picture.draw(canvas);
360 canvas->restore();
361 if (clip.fRight < SkIntToScalar(320))
362 clip.offset(SkIntToScalar(160), 0);
363 else if (clip.fBottom < SkIntToScalar(480))
364 clip.offset(-SkIntToScalar(320), SkIntToScalar(160));
365 else
366 break;
367 } while (true);
368 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000369 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000370
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000371 void drawPicture(SkCanvas* canvas, int spriteOffset) {
rmistry@google.comae933ce2012-08-23 18:19:56 +0000372 SkMatrix matrix; matrix.reset();
373 SkPaint paint;
374 SkPath path;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000375 SkPoint start = {0, 0};
376 SkPoint stop = { SkIntToScalar(40), SkIntToScalar(40) };
rmistry@google.comae933ce2012-08-23 18:19:56 +0000377 SkRect rect = {0, 0, SkIntToScalar(40), SkIntToScalar(40) };
378 SkRect rect2 = {0, 0, SkIntToScalar(65), SkIntToScalar(20) };
379 SkScalar left = 0, top = 0, x = 0, y = 0;
380 size_t index;
381
382 char ascii[] = "ascii...";
383 size_t asciiLength = sizeof(ascii) - 1;
384 char utf8[] = "utf8" "\xe2\x80\xa6";
385 short utf16[] = {'u', 't', 'f', '1', '6', 0x2026 };
386 short utf16simple[] = {'u', 't', 'f', '1', '6', '!' };
387
reed@android.com8a1c16f2008-12-17 15:59:43 +0000388 makePath(path);
389 SkTDArray<SkPoint>(pos);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000390 pos.setCount(asciiLength);
391 for (index = 0; index < asciiLength; index++)
392 pos[index].set(SkIntToScalar((unsigned int)index * 10),
tomhudson@google.comffe39bd2012-05-17 15:38:00 +0000393 SkIntToScalar((unsigned int)index * 2));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000394 SkTDArray<SkPoint>(pos2);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000395 pos2.setCount(asciiLength);
396 for (index = 0; index < asciiLength; index++)
397 pos2[index].set(SkIntToScalar((unsigned int)index * 10),
tomhudson@google.comffe39bd2012-05-17 15:38:00 +0000398 SkIntToScalar(20));
rmistry@google.comae933ce2012-08-23 18:19:56 +0000399
reed@android.com8a1c16f2008-12-17 15:59:43 +0000400 // shaders
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000401 SkPoint linearPoints[] = { { 0, 0, }, { SkIntToScalar(40), SkIntToScalar(40) } };
reed@android.com8a1c16f2008-12-17 15:59:43 +0000402 SkColor linearColors[] = { SK_ColorRED, SK_ColorBLUE };
403 SkScalar* linearPos = NULL;
404 int linearCount = 2;
405 SkShader::TileMode linearMode = SkShader::kMirror_TileMode;
406 SkUnitMapper* linearMapper = new SkDiscreteMapper(3);
407 SkAutoUnref unmapLinearMapper(linearMapper);
408 SkShader* linear = SkGradientShader::CreateLinear(linearPoints,
409 linearColors, linearPos, linearCount, linearMode, linearMapper);
410
411 SkPoint radialCenter = { SkIntToScalar(25), SkIntToScalar(25) };
412 SkScalar radialRadius = SkIntToScalar(25);
413 SkColor radialColors[] = { SK_ColorGREEN, SK_ColorGRAY, SK_ColorRED };
414 SkScalar radialPos[] = { 0, SkIntToScalar(3) / 5, SkIntToScalar(1)};
415 int radialCount = 3;
416 SkShader::TileMode radialMode = SkShader::kRepeat_TileMode;
417 SkUnitMapper* radialMapper = new SkCosineMapper();
418 SkAutoUnref unmapRadialMapper(radialMapper);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000419 SkShader* radial = SkGradientShader::CreateRadial(radialCenter,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000420 radialRadius, radialColors, radialPos, radialCount,
421 radialMode, radialMapper);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000422
reed@android.com8a1c16f2008-12-17 15:59:43 +0000423 SkTransparentShader* transparentShader = new SkTransparentShader();
424 SkEmbossMaskFilter::Light light;
425 light.fDirection[0] = SK_Scalar1/2;
426 light.fDirection[1] = SK_Scalar1/2;
427 light.fDirection[2] = SK_Scalar1/3;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000428 light.fAmbient = 0x48;
429 light.fSpecular = 0x80;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000430 SkScalar radius = SkIntToScalar(12)/5;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000431 SkEmbossMaskFilter* embossFilter = new SkEmbossMaskFilter(light,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000432 radius);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000433
reed@android.com048522d2009-06-23 12:19:41 +0000434 SkXfermode* xfermode = SkXfermode::Create(SkXfermode::kXor_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000435 SkColorFilter* lightingFilter = SkColorFilter::CreateLightingFilter(
436 0xff89bc45, 0xff112233);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000437
reed@android.com8a1c16f2008-12-17 15:59:43 +0000438 canvas->save();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000439 canvas->translate(SkIntToScalar(0), SkIntToScalar(5));
440 paint.setFlags(SkPaint::kAntiAlias_Flag | SkPaint::kFilterBitmap_Flag);
441 // !!! draw through a clip
442 paint.setColor(SK_ColorLTGRAY);
443 paint.setStyle(SkPaint::kFill_Style);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000444 SkRect clip = {0, 0, SkIntToScalar(320), SkIntToScalar(120)};
445 canvas->clipRect(clip);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000446 paint.setShader(SkShader::CreateBitmapShader(fTx,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000447 SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode))->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000448 canvas->drawPaint(paint);
449 canvas->save();
450
reed@android.com8a1c16f2008-12-17 15:59:43 +0000451 // line (exercises xfermode, colorShader, colorFilter, filterShader)
rmistry@google.comae933ce2012-08-23 18:19:56 +0000452 paint.setColor(SK_ColorGREEN);
453 paint.setStrokeWidth(SkIntToScalar(10));
454 paint.setStyle(SkPaint::kStroke_Style);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000455 paint.setXfermode(xfermode)->unref();
456 paint.setColorFilter(lightingFilter)->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000457 canvas->drawLine(start.fX, start.fY, stop.fX, stop.fY, paint); // should not be green
458 paint.setXfermode(NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000459 paint.setColorFilter(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000460
reed@android.com8a1c16f2008-12-17 15:59:43 +0000461 // rectangle
rmistry@google.comae933ce2012-08-23 18:19:56 +0000462 paint.setStyle(SkPaint::kFill_Style);
463 canvas->translate(SkIntToScalar(50), 0);
464 paint.setColor(SK_ColorYELLOW);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000465 paint.setShader(linear)->unref();
466 paint.setPathEffect(pathEffectTest())->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000467 canvas->drawRect(rect, paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000468 paint.setPathEffect(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000469
reed@android.com8a1c16f2008-12-17 15:59:43 +0000470 // circle w/ emboss & transparent (exercises 3dshader)
rmistry@google.comae933ce2012-08-23 18:19:56 +0000471 canvas->translate(SkIntToScalar(50), 0);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000472 paint.setMaskFilter(embossFilter)->unref();
473 canvas->drawOval(rect, paint);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000474 canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000475 paint.setShader(transparentShader)->unref();
476 canvas->drawOval(rect, paint);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000477 canvas->translate(0, SkIntToScalar(-10));
478
reed@android.com8a1c16f2008-12-17 15:59:43 +0000479 // path
rmistry@google.comae933ce2012-08-23 18:19:56 +0000480 canvas->translate(SkIntToScalar(50), 0);
481 paint.setColor(SK_ColorRED);
482 paint.setStyle(SkPaint::kStroke_Style);
483 paint.setStrokeWidth(SkIntToScalar(5));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000484 paint.setShader(radial)->unref();
485 paint.setMaskFilter(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000486 canvas->drawPath(path, paint);
487
reed@android.com8a1c16f2008-12-17 15:59:43 +0000488 paint.setShader(NULL);
489 // bitmap, sprite
rmistry@google.comae933ce2012-08-23 18:19:56 +0000490 canvas->translate(SkIntToScalar(50), 0);
491 paint.setStyle(SkPaint::kFill_Style);
492 canvas->drawBitmap(fBug, left, top, &paint);
493 canvas->translate(SkIntToScalar(30), 0);
494 canvas->drawSprite(fTb,
495 SkScalarRound(canvas->getTotalMatrix().getTranslateX()),
reed@android.com8a1c16f2008-12-17 15:59:43 +0000496 spriteOffset + 10, &paint);
497
rmistry@google.comae933ce2012-08-23 18:19:56 +0000498 canvas->translate(-SkIntToScalar(30), SkIntToScalar(30));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000499 paint.setShader(shaderTest())->unref(); // test compose shader
rmistry@google.comae933ce2012-08-23 18:19:56 +0000500 canvas->drawRect(rect2, paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000501 paint.setShader(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000502
reed@android.com8a1c16f2008-12-17 15:59:43 +0000503 canvas->restore();
504 // text
reed@android.com8a1c16f2008-12-17 15:59:43 +0000505 canvas->translate(0, SkIntToScalar(60));
rmistry@google.comae933ce2012-08-23 18:19:56 +0000506 canvas->save();
507 paint.setColor(SK_ColorGRAY);
508 canvas->drawPosText(ascii, asciiLength, pos.begin(), paint);
509 canvas->drawPosText(ascii, asciiLength, pos2.begin(), paint);
510
511 canvas->translate(SkIntToScalar(50), 0);
512 paint.setColor(SK_ColorCYAN);
513 canvas->drawText(utf8, sizeof(utf8) - 1, x, y, paint);
514
515 canvas->translate(SkIntToScalar(30), 0);
516 paint.setColor(SK_ColorMAGENTA);
517 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
518 matrix.setTranslate(SkIntToScalar(10), SkIntToScalar(10));
519 canvas->drawTextOnPath((void*) utf16, sizeof(utf16), path, &matrix, paint);
520 canvas->translate(0, SkIntToScalar(20));
521 canvas->drawTextOnPath((void*) utf16simple, sizeof(utf16simple), path, &matrix, paint);
522 canvas->restore();
523
524 canvas->translate(0, SkIntToScalar(60));
525 paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000526 canvas->restore();
527 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000528
reed@android.com8a1c16f2008-12-17 15:59:43 +0000529 /*
530./SkColorFilter.h:25:class SkColorFilter : public SkFlattenable { -- abstract
531 static SkColorFilter* CreatXfermodeFilter() *** untested ***
532 static SkColorFilter* CreatePorterDuffFilter() *** untested ***
533 static SkColorFilter* CreateLightingFilter() -- tested
534./SkDrawLooper.h:9:class SkDrawLooper : public SkFlattenable { -- virtually abstract
535 ./SkBlurDrawLooper.h:9:class SkBlurDrawLooper : public SkDrawLooper { *** untested ***
536./SkMaskFilter.h:41:class SkMaskFilter : public SkFlattenable { -- abstract chmod +w .h
537 ./SkEmbossMaskFilter.h:27:class SkEmbossMaskFilter : public SkMaskFilter { -- tested
538./SkPathEffect.h:33:class SkPathEffect : public SkFlattenable { -- abstract
539 ./Sk1DPathEffect.h:27:class Sk1DPathEffect : public SkPathEffect { -- abstract
540 ./Sk1DPathEffect.h:48:class SkPath1DPathEffect : public Sk1DPathEffect { -- tested
541 ./Sk2DPathEffect.h:25:class Sk2DPathEffect : public SkPathEffect { *** untested ***
542 ./SkCornerPathEffect.h:28:class SkCornerPathEffect : public SkPathEffect { *** untested ***
543 ./SkDashPathEffect.h:27:class SkDashPathEffect : public SkPathEffect {
544 ./SkDiscretePathEffect.h:27:class SkDiscretePathEffect : public SkPathEffect {
545 ./SkPaint.h:760:class SkStrokePathEffect : public SkPathEffect {
546 ./SkPathEffect.h:58:class SkPairPathEffect : public SkPathEffect {
547 ./SkPathEffect.h:78:class SkComposePathEffect : public SkPairPathEffect {
548 ./SkPathEffect.h:114:class SkSumPathEffect : public SkPairPathEffect {
549./SkRasterizer.h:29:class SkRasterizer : public SkFlattenable {
550 ./SkLayerRasterizer.h:27:class SkLayerRasterizer : public SkRasterizer {
551./SkShader.h:36:class SkShader : public SkFlattenable {
552 ./SkColorFilter.h:59:class SkFilterShader : public SkShader {
553 ./SkColorShader.h:26:class SkColorShader : public SkShader {
554 ./SkShaderExtras.h:31:class SkComposeShader : public SkShader {
555 ./SkTransparentShader.h:23:class SkTransparentShader : public SkShader {
556./SkUnitMapper.h:24:class SkUnitMapper : public SkFlattenable {
557 ./SkUnitMapper.h:33:class SkDiscreteMapper : public SkUnitMapper {
558 ./SkUnitMapper.h:51:class SkFlipCosineMapper : public SkUnitMapper {
559./SkXfermode.h:32:class SkXfermode : public SkFlattenable {
560 ./SkAvoidXfermode.h:28:class SkAvoidXfermode : public SkXfermode { *** not done *** chmod +w .h .cpp
561 ./SkXfermode.h:54:class SkProcXfermode : public SkXfermode {
562 */
rmistry@google.comae933ce2012-08-23 18:19:56 +0000563
reed@android.com8a1c16f2008-12-17 15:59:43 +0000564 /*
565./SkBlurMaskFilter.h:25:class SkBlurMaskFilter {
566 chmod +w SkBlurMaskFilter.cpp
567./SkGradientShader.h:30:class SkGradientShader {
568 */
569 // save layer, bounder, looper
570 // matrix
571 // clip /path/region
572 // bitmap proc shader ?
573
574/* untested:
575SkCornerPathEffect.h:28:class SkCornerPathEffect : public SkPathEffect {
576*/
rmistry@google.comae933ce2012-08-23 18:19:56 +0000577
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000578 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000579 fClickPt.set(x, y);
580 this->inval(NULL);
581 return this->INHERITED::onFindClickHandler(x, y);
582 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000583
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000584 SkPathEffect* pathEffectTest() {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000585 static const int gXY[] = { 1, 0, 0, -1, 2, -1, 3, 0, 2, 1, 0, 1 };
586 SkScalar gPhase = 0;
587 SkPath path;
588 path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
589 for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
590 path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
591 path.close();
592 path.offset(SkIntToScalar(-6), 0);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000593 SkPathEffect* outer = new SkPath1DPathEffect(path, SkIntToScalar(12),
reed@android.com8a1c16f2008-12-17 15:59:43 +0000594 gPhase, SkPath1DPathEffect::kRotate_Style);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000595 SkPathEffect* inner = new SkDiscretePathEffect(SkIntToScalar(2),
reed@android.com8a1c16f2008-12-17 15:59:43 +0000596 SkIntToScalar(1)/10); // SkCornerPathEffect(SkIntToScalar(2));
597 SkPathEffect* result = new SkComposePathEffect(outer, inner);
598 outer->unref();
599 inner->unref();
600 return result;
601 }
reed@google.com963a8fa2012-05-10 13:04:59 +0000602
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000603 SkShader* shaderTest() {
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000604 SkPoint pts[] = { { 0, 0, }, { SkIntToScalar(100), 0 } };
reed@android.com8a1c16f2008-12-17 15:59:43 +0000605 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
rmistry@google.comae933ce2012-08-23 18:19:56 +0000606 SkShader* shaderA = SkGradientShader::CreateLinear(pts, colors, NULL,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000607 2, SkShader::kClamp_TileMode);
608 pts[1].set(0, SkIntToScalar(100));
609 SkColor colors2[] = {SK_ColorBLACK, SkColorSetARGB(0x80, 0, 0, 0)};
rmistry@google.comae933ce2012-08-23 18:19:56 +0000610 SkShader* shaderB = SkGradientShader::CreateLinear(pts, colors2, NULL,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000611 2, SkShader::kClamp_TileMode);
reed@android.com048522d2009-06-23 12:19:41 +0000612 SkXfermode* mode = SkXfermode::Create(SkXfermode::kDstIn_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000613 SkShader* result = new SkComposeShader(shaderA, shaderB, mode);
614 shaderA->unref();
615 shaderB->unref();
616 mode->unref();
617 return result;
618 }
619
620 virtual void startTest() {
rmistry@google.comae933ce2012-08-23 18:19:56 +0000621 SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/bugcirc.gif", &fBug);
622 SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/tbcirc.gif", &fTb);
623 SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/05psp04.gif", &fTx);
624 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000625
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000626 void drawRaster(SkCanvas* canvas) {
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000627 for (size_t index = 0; index < SK_ARRAY_COUNT(gRastProcs); index++)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000628 drawOneRaster(canvas);
629 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000630
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000631 void drawOneRaster(SkCanvas* canvas) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000632 canvas->save();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000633
634 SkScalar x = SkIntToScalar(20);
635 SkScalar y = SkIntToScalar(40);
636 SkPaint paint;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000637
reed@android.com8a1c16f2008-12-17 15:59:43 +0000638 paint.setAntiAlias(true);
639 paint.setTextSize(SkIntToScalar(48));
reed@android.comaa5a7db2009-05-27 01:20:10 +0000640 paint.setTypeface(SkTypeface::CreateFromName("sans-serif",
641 SkTypeface::kBold));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000642
643 SkString str("GOOGLE");
644
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000645 for (size_t i = 0; i < SK_ARRAY_COUNT(gRastProcs); i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000646 apply_shader(&paint, i);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000647
reed@android.com8a1c16f2008-12-17 15:59:43 +0000648 // paint.setMaskFilter(NULL);
649 // paint.setColor(SK_ColorBLACK);
650
651#if 01
652 int index = i % SK_ARRAY_COUNT(gLightingColors);
653 paint.setColorFilter(SkColorFilter::CreateLightingFilter(
654 gLightingColors[index].fMul,
655 gLightingColors[index].fAdd))->unref();
656#endif
rmistry@google.comae933ce2012-08-23 18:19:56 +0000657
reed@android.com8a1c16f2008-12-17 15:59:43 +0000658 canvas->drawText(str.c_str(), str.size(), x, y, paint);
659 SkRect oval = { x, y - SkIntToScalar(40), x + SkIntToScalar(40), y };
660 paint.setStyle(SkPaint::kStroke_Style);
661 canvas->drawOval(oval, paint);
662 paint.setStyle(SkPaint::kFill_Style);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000663
664 y += paint.getFontSpacing();
665 }
666
667 canvas->restore();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000668
reed@android.com6b82d1a2009-06-03 02:35:01 +0000669 if (1) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000670 SkAvoidXfermode mode(SK_ColorWHITE, 0xFF,
671 SkAvoidXfermode::kTargetColor_Mode);
672 SkPaint paint;
673 x += SkIntToScalar(20);
674 SkRect r = { x, 0, x + SkIntToScalar(360), SkIntToScalar(700) };
675 paint.setXfermode(&mode);
676 paint.setColor(SK_ColorGREEN);
677 paint.setAntiAlias(true);
678 canvas->drawOval(r, paint);
679 }
680 }
681
682private:
683 SkPoint fClickPt;
684 SkBitmap fBug, fTb, fTx;
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000685 typedef SampleView INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000686};
687
688//////////////////////////////////////////////////////////////////////////////
689
690static SkView* MyFactory() { return new DemoView; }
691static SkViewRegister reg(MyFactory);
692