blob: 01fbe0f8ec45fd112f11d6eb5a23da11d10fd1e6 [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.org61490fa2012-12-24 14:38:46 +000054 virtual void filterSpan(const SkPMColor src[], int count,
55 SkPMColor result[]) const SK_OVERRIDE {
reed@android.com8a1c16f2008-12-17 15:59:43 +000056 for (int i = 0; i < count; i++)
57 result[i] = rgb2gray(src[i]);
58 }
59};
60
61class SkChannelMaskColorFilter : public SkColorFilter {
62public:
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000063 SkChannelMaskColorFilter(U8CPU redMask, U8CPU greenMask, U8CPU blueMask) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000064 fMask = SkPackARGB32(0xFF, redMask, greenMask, blueMask);
65 }
66
mike@reedtribe.org61490fa2012-12-24 14:38:46 +000067 virtual void filterSpan(const SkPMColor src[], int count,
68 SkPMColor result[]) const SK_OVERRIDE {
reed@android.com8a1c16f2008-12-17 15:59:43 +000069 SkPMColor mask = fMask;
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000070 for (int i = 0; i < count; i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000071 result[i] = src[i] & mask;
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000072 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000073 }
rmistry@google.comae933ce2012-08-23 18:19:56 +000074
reed@android.com8a1c16f2008-12-17 15:59:43 +000075private:
76 SkPMColor fMask;
77};
78
79///////////////////////////////////////////////////////////
80
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000081static void r0(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000082 p.setMaskFilter(SkBlurMaskFilter::Create(SkIntToScalar(3),
83 SkBlurMaskFilter::kNormal_BlurStyle))->unref();
84 rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
85
86 p.setMaskFilter(NULL);
87 p.setStyle(SkPaint::kStroke_Style);
88 p.setStrokeWidth(SK_Scalar1);
89 rast->addLayer(p);
90
91 p.setAlpha(0x11);
92 p.setStyle(SkPaint::kFill_Style);
reed@android.com0baf1932009-06-24 12:41:42 +000093 p.setXfermodeMode(SkXfermode::kSrc_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +000094 rast->addLayer(p);
95}
96
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000097static void r1(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000098 rast->addLayer(p);
99
100 p.setAlpha(0x40);
reed@android.com0baf1932009-06-24 12:41:42 +0000101 p.setXfermodeMode(SkXfermode::kSrc_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000102 p.setStyle(SkPaint::kStroke_Style);
103 p.setStrokeWidth(SK_Scalar1*2);
104 rast->addLayer(p);
105}
rmistry@google.comae933ce2012-08-23 18:19:56 +0000106
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000107static void r2(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000108 p.setStyle(SkPaint::kStrokeAndFill_Style);
109 p.setStrokeWidth(SK_Scalar1*4);
110 rast->addLayer(p);
111
112 p.setStyle(SkPaint::kStroke_Style);
113 p.setStrokeWidth(SK_Scalar1*3/2);
reed@android.com0baf1932009-06-24 12:41:42 +0000114 p.setXfermodeMode(SkXfermode::kClear_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000115 rast->addLayer(p);
116}
117
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000118static void r3(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000119 p.setStyle(SkPaint::kStroke_Style);
120 p.setStrokeWidth(SK_Scalar1*3);
121 rast->addLayer(p);
122
123 p.setAlpha(0x20);
124 p.setStyle(SkPaint::kFill_Style);
reed@android.com0baf1932009-06-24 12:41:42 +0000125 p.setXfermodeMode(SkXfermode::kSrc_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000126 rast->addLayer(p);
127}
128
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000129static void r4(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000130 p.setAlpha(0x60);
131 rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
132
133 p.setAlpha(0xFF);
reed@android.com0baf1932009-06-24 12:41:42 +0000134 p.setXfermodeMode(SkXfermode::kClear_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000135 rast->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2);
136
137 p.setXfermode(NULL);
138 rast->addLayer(p);
139}
140
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000141static void r5(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000142 rast->addLayer(p);
143
144 p.setPathEffect(new SkDiscretePathEffect(SK_Scalar1*4, SK_Scalar1*3))->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000145 p.setXfermodeMode(SkXfermode::kSrcOut_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000146 rast->addLayer(p);
147}
148
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000149static void r6(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000150 rast->addLayer(p);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000151
reed@android.com8a1c16f2008-12-17 15:59:43 +0000152 p.setAntiAlias(false);
153 SkLayerRasterizer* rast2 = new SkLayerRasterizer;
154 r5(rast2, p);
155 p.setRasterizer(rast2)->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000156 p.setXfermodeMode(SkXfermode::kClear_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000157 rast->addLayer(p);
158}
159
160class Dot2DPathEffect : public Sk2DPathEffect {
161public:
162 Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix)
163 : Sk2DPathEffect(matrix), fRadius(radius) {}
164
djsollen@google.comba28d032012-03-26 17:57:35 +0000165 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Dot2DPathEffect)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000166
167protected:
mike@reedtribe.org61490fa2012-12-24 14:38:46 +0000168 virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) const SK_OVERRIDE {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000169 dst->addCircle(loc.fX, loc.fY, fRadius);
170 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000171
djsollen@google.com54924242012-03-29 15:18:04 +0000172 Dot2DPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000173 fRadius = buffer.readScalar();
174 }
djsollen@google.com54924242012-03-29 15:18:04 +0000175 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
176 this->INHERITED::flatten(buffer);
177 buffer.writeScalar(fRadius);
178 }
179
reed@android.com8a1c16f2008-12-17 15:59:43 +0000180private:
181 SkScalar fRadius;
182
reed@android.com8a1c16f2008-12-17 15:59:43 +0000183 typedef Sk2DPathEffect INHERITED;
184};
185
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000186static void r7(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000187 SkMatrix lattice;
188 lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
189 lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
190 p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*4, lattice))->unref();
191 rast->addLayer(p);
192}
193
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000194static void r8(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000195 rast->addLayer(p);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000196
reed@android.com8a1c16f2008-12-17 15:59:43 +0000197 SkMatrix lattice;
198 lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
199 lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
200 p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*2, lattice))->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000201 p.setXfermodeMode(SkXfermode::kClear_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000202 rast->addLayer(p);
203
204 p.setPathEffect(NULL);
205 p.setXfermode(NULL);
206 p.setStyle(SkPaint::kStroke_Style);
207 p.setStrokeWidth(SK_Scalar1);
208 rast->addLayer(p);
209}
210
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000211static void r9(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000212 rast->addLayer(p);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000213
reed@android.com8a1c16f2008-12-17 15:59:43 +0000214 SkMatrix lattice;
215 lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0);
216 lattice.postRotate(SkIntToScalar(30), 0, 0);
scroggo@google.comd8a6cc82012-09-12 18:53:49 +0000217 p.setPathEffect(new SkLine2DPathEffect(SK_Scalar1*2, lattice))->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000218 p.setXfermodeMode(SkXfermode::kClear_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000219 rast->addLayer(p);
220
221 p.setPathEffect(NULL);
222 p.setXfermode(NULL);
223 p.setStyle(SkPaint::kStroke_Style);
224 p.setStrokeWidth(SK_Scalar1);
225 rast->addLayer(p);
226}
227
228typedef void (*raster_proc)(SkLayerRasterizer*, SkPaint&);
229
230static const raster_proc gRastProcs[] = {
231 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
232};
233
234static const struct {
235 SkColor fMul, fAdd;
236} gLightingColors[] = {
237 { 0x808080, 0x800000 }, // general case
238 { 0x707070, 0x707070 }, // no-pin case
239 { 0xFFFFFF, 0x800000 }, // just-add case
240 { 0x808080, 0x000000 }, // just-mul case
241 { 0xFFFFFF, 0x000000 } // identity case
242};
243
rmistry@google.comae933ce2012-08-23 18:19:56 +0000244static void apply_shader(SkPaint* paint, int index) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000245 raster_proc proc = gRastProcs[index];
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000246 if (proc) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000247 SkPaint p;
248 SkLayerRasterizer* rast = new SkLayerRasterizer;
249
250 p.setAntiAlias(true);
251 proc(rast, p);
252 paint->setRasterizer(rast)->unref();
253 }
254
255#if 1
256 SkScalar dir[] = { SK_Scalar1, SK_Scalar1, SK_Scalar1 };
rmistry@google.comae933ce2012-08-23 18:19:56 +0000257 paint->setMaskFilter(SkBlurMaskFilter::CreateEmboss(dir, SK_Scalar1/4, SkIntToScalar(4), SkIntToScalar(3)))->unref();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000258 paint->setColor(SK_ColorBLUE);
259#endif
260}
261
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000262class DemoView : public SampleView {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000263public:
reed@google.com2f3dc9d2011-05-02 17:33:45 +0000264 DemoView() {}
rmistry@google.comae933ce2012-08-23 18:19:56 +0000265
reed@android.com8a1c16f2008-12-17 15:59:43 +0000266protected:
267 // overrides from SkEventSink
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000268 virtual bool onQuery(SkEvent* evt) {
269 if (SampleCode::TitleQ(*evt)) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000270 SampleCode::TitleR(evt, "Demo");
271 return true;
272 }
273 return this->INHERITED::onQuery(evt);
274 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000275
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000276 virtual bool onClick(Click* click) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000277 return this->INHERITED::onClick(click);
278 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000279
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000280 void makePath(SkPath& path) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000281 path.addCircle(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(20),
282 SkPath::kCCW_Direction);
283 for (int index = 0; index < 10; index++) {
caryclark@google.com02939ce2012-06-06 12:09:51 +0000284 SkScalar x = SkFloatToScalar((float) cos(index / 10.0f * 2 * 3.1415925358f));
285 SkScalar y = SkFloatToScalar((float) sin(index / 10.0f * 2 * 3.1415925358f));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000286 x *= index & 1 ? 7 : 14;
287 y *= index & 1 ? 7 : 14;
288 x += SkIntToScalar(20);
289 y += SkIntToScalar(20);
290 if (index == 0)
291 path.moveTo(x, y);
292 else
293 path.lineTo(x, y);
294 }
295 path.close();
296 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000297
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000298 virtual void onDrawContent(SkCanvas* canvas) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000299 canvas->save();
300 drawPicture(canvas, 0);
301 canvas->restore();
302
303 {
304 SkPicture picture;
305 SkCanvas* record = picture.beginRecording(320, 480);
306 drawPicture(record, 120);
307 canvas->translate(0, SkIntToScalar(120));
308
309 SkRect clip;
310 clip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
311 do {
312 canvas->save();
313 canvas->clipRect(clip);
314 picture.draw(canvas);
315 canvas->restore();
316 if (clip.fRight < SkIntToScalar(320))
317 clip.offset(SkIntToScalar(160), 0);
318 else if (clip.fBottom < SkIntToScalar(480))
319 clip.offset(-SkIntToScalar(320), SkIntToScalar(160));
320 else
321 break;
322 } while (true);
323 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000324 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000325
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000326 void drawPicture(SkCanvas* canvas, int spriteOffset) {
rmistry@google.comae933ce2012-08-23 18:19:56 +0000327 SkMatrix matrix; matrix.reset();
328 SkPaint paint;
329 SkPath path;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000330 SkPoint start = {0, 0};
331 SkPoint stop = { SkIntToScalar(40), SkIntToScalar(40) };
rmistry@google.comae933ce2012-08-23 18:19:56 +0000332 SkRect rect = {0, 0, SkIntToScalar(40), SkIntToScalar(40) };
333 SkRect rect2 = {0, 0, SkIntToScalar(65), SkIntToScalar(20) };
334 SkScalar left = 0, top = 0, x = 0, y = 0;
335 size_t index;
336
337 char ascii[] = "ascii...";
338 size_t asciiLength = sizeof(ascii) - 1;
339 char utf8[] = "utf8" "\xe2\x80\xa6";
340 short utf16[] = {'u', 't', 'f', '1', '6', 0x2026 };
341 short utf16simple[] = {'u', 't', 'f', '1', '6', '!' };
342
reed@android.com8a1c16f2008-12-17 15:59:43 +0000343 makePath(path);
344 SkTDArray<SkPoint>(pos);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000345 pos.setCount(asciiLength);
346 for (index = 0; index < asciiLength; index++)
347 pos[index].set(SkIntToScalar((unsigned int)index * 10),
tomhudson@google.comffe39bd2012-05-17 15:38:00 +0000348 SkIntToScalar((unsigned int)index * 2));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000349 SkTDArray<SkPoint>(pos2);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000350 pos2.setCount(asciiLength);
351 for (index = 0; index < asciiLength; index++)
352 pos2[index].set(SkIntToScalar((unsigned int)index * 10),
tomhudson@google.comffe39bd2012-05-17 15:38:00 +0000353 SkIntToScalar(20));
rmistry@google.comae933ce2012-08-23 18:19:56 +0000354
reed@android.com8a1c16f2008-12-17 15:59:43 +0000355 // shaders
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000356 SkPoint linearPoints[] = { { 0, 0, }, { SkIntToScalar(40), SkIntToScalar(40) } };
reed@android.com8a1c16f2008-12-17 15:59:43 +0000357 SkColor linearColors[] = { SK_ColorRED, SK_ColorBLUE };
358 SkScalar* linearPos = NULL;
359 int linearCount = 2;
360 SkShader::TileMode linearMode = SkShader::kMirror_TileMode;
361 SkUnitMapper* linearMapper = new SkDiscreteMapper(3);
362 SkAutoUnref unmapLinearMapper(linearMapper);
363 SkShader* linear = SkGradientShader::CreateLinear(linearPoints,
364 linearColors, linearPos, linearCount, linearMode, linearMapper);
365
366 SkPoint radialCenter = { SkIntToScalar(25), SkIntToScalar(25) };
367 SkScalar radialRadius = SkIntToScalar(25);
368 SkColor radialColors[] = { SK_ColorGREEN, SK_ColorGRAY, SK_ColorRED };
369 SkScalar radialPos[] = { 0, SkIntToScalar(3) / 5, SkIntToScalar(1)};
370 int radialCount = 3;
371 SkShader::TileMode radialMode = SkShader::kRepeat_TileMode;
372 SkUnitMapper* radialMapper = new SkCosineMapper();
373 SkAutoUnref unmapRadialMapper(radialMapper);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000374 SkShader* radial = SkGradientShader::CreateRadial(radialCenter,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000375 radialRadius, radialColors, radialPos, radialCount,
376 radialMode, radialMapper);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000377
reed@android.com8a1c16f2008-12-17 15:59:43 +0000378 SkTransparentShader* transparentShader = new SkTransparentShader();
379 SkEmbossMaskFilter::Light light;
380 light.fDirection[0] = SK_Scalar1/2;
381 light.fDirection[1] = SK_Scalar1/2;
382 light.fDirection[2] = SK_Scalar1/3;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000383 light.fAmbient = 0x48;
384 light.fSpecular = 0x80;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000385 SkScalar radius = SkIntToScalar(12)/5;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000386 SkEmbossMaskFilter* embossFilter = new SkEmbossMaskFilter(light,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000387 radius);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000388
reed@android.com048522d2009-06-23 12:19:41 +0000389 SkXfermode* xfermode = SkXfermode::Create(SkXfermode::kXor_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000390 SkColorFilter* lightingFilter = SkColorFilter::CreateLightingFilter(
391 0xff89bc45, 0xff112233);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000392
reed@android.com8a1c16f2008-12-17 15:59:43 +0000393 canvas->save();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000394 canvas->translate(SkIntToScalar(0), SkIntToScalar(5));
reed@google.com9cfc83c2013-07-22 17:18:18 +0000395 paint.setAntiAlias(true);
396 paint.setFilterLevel(SkPaint::kLow_FilterLevel);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000397 // !!! draw through a clip
398 paint.setColor(SK_ColorLTGRAY);
399 paint.setStyle(SkPaint::kFill_Style);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000400 SkRect clip = {0, 0, SkIntToScalar(320), SkIntToScalar(120)};
401 canvas->clipRect(clip);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000402 paint.setShader(SkShader::CreateBitmapShader(fTx,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000403 SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode))->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000404 canvas->drawPaint(paint);
405 canvas->save();
406
reed@android.com8a1c16f2008-12-17 15:59:43 +0000407 // line (exercises xfermode, colorShader, colorFilter, filterShader)
rmistry@google.comae933ce2012-08-23 18:19:56 +0000408 paint.setColor(SK_ColorGREEN);
409 paint.setStrokeWidth(SkIntToScalar(10));
410 paint.setStyle(SkPaint::kStroke_Style);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000411 paint.setXfermode(xfermode)->unref();
412 paint.setColorFilter(lightingFilter)->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000413 canvas->drawLine(start.fX, start.fY, stop.fX, stop.fY, paint); // should not be green
414 paint.setXfermode(NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000415 paint.setColorFilter(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000416
reed@android.com8a1c16f2008-12-17 15:59:43 +0000417 // rectangle
rmistry@google.comae933ce2012-08-23 18:19:56 +0000418 paint.setStyle(SkPaint::kFill_Style);
419 canvas->translate(SkIntToScalar(50), 0);
420 paint.setColor(SK_ColorYELLOW);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000421 paint.setShader(linear)->unref();
422 paint.setPathEffect(pathEffectTest())->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000423 canvas->drawRect(rect, paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000424 paint.setPathEffect(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000425
reed@android.com8a1c16f2008-12-17 15:59:43 +0000426 // circle w/ emboss & transparent (exercises 3dshader)
rmistry@google.comae933ce2012-08-23 18:19:56 +0000427 canvas->translate(SkIntToScalar(50), 0);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000428 paint.setMaskFilter(embossFilter)->unref();
429 canvas->drawOval(rect, paint);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000430 canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000431 paint.setShader(transparentShader)->unref();
432 canvas->drawOval(rect, paint);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000433 canvas->translate(0, SkIntToScalar(-10));
434
reed@android.com8a1c16f2008-12-17 15:59:43 +0000435 // path
rmistry@google.comae933ce2012-08-23 18:19:56 +0000436 canvas->translate(SkIntToScalar(50), 0);
437 paint.setColor(SK_ColorRED);
438 paint.setStyle(SkPaint::kStroke_Style);
439 paint.setStrokeWidth(SkIntToScalar(5));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000440 paint.setShader(radial)->unref();
441 paint.setMaskFilter(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000442 canvas->drawPath(path, paint);
443
reed@android.com8a1c16f2008-12-17 15:59:43 +0000444 paint.setShader(NULL);
445 // bitmap, sprite
rmistry@google.comae933ce2012-08-23 18:19:56 +0000446 canvas->translate(SkIntToScalar(50), 0);
447 paint.setStyle(SkPaint::kFill_Style);
448 canvas->drawBitmap(fBug, left, top, &paint);
449 canvas->translate(SkIntToScalar(30), 0);
450 canvas->drawSprite(fTb,
451 SkScalarRound(canvas->getTotalMatrix().getTranslateX()),
reed@android.com8a1c16f2008-12-17 15:59:43 +0000452 spriteOffset + 10, &paint);
453
rmistry@google.comae933ce2012-08-23 18:19:56 +0000454 canvas->translate(-SkIntToScalar(30), SkIntToScalar(30));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000455 paint.setShader(shaderTest())->unref(); // test compose shader
rmistry@google.comae933ce2012-08-23 18:19:56 +0000456 canvas->drawRect(rect2, paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000457 paint.setShader(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000458
reed@android.com8a1c16f2008-12-17 15:59:43 +0000459 canvas->restore();
460 // text
reed@android.com8a1c16f2008-12-17 15:59:43 +0000461 canvas->translate(0, SkIntToScalar(60));
rmistry@google.comae933ce2012-08-23 18:19:56 +0000462 canvas->save();
463 paint.setColor(SK_ColorGRAY);
464 canvas->drawPosText(ascii, asciiLength, pos.begin(), paint);
465 canvas->drawPosText(ascii, asciiLength, pos2.begin(), paint);
466
467 canvas->translate(SkIntToScalar(50), 0);
468 paint.setColor(SK_ColorCYAN);
469 canvas->drawText(utf8, sizeof(utf8) - 1, x, y, paint);
470
471 canvas->translate(SkIntToScalar(30), 0);
472 paint.setColor(SK_ColorMAGENTA);
473 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
474 matrix.setTranslate(SkIntToScalar(10), SkIntToScalar(10));
475 canvas->drawTextOnPath((void*) utf16, sizeof(utf16), path, &matrix, paint);
476 canvas->translate(0, SkIntToScalar(20));
477 canvas->drawTextOnPath((void*) utf16simple, sizeof(utf16simple), path, &matrix, paint);
478 canvas->restore();
479
480 canvas->translate(0, SkIntToScalar(60));
481 paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000482 canvas->restore();
483 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000484
reed@android.com8a1c16f2008-12-17 15:59:43 +0000485 /*
486./SkColorFilter.h:25:class SkColorFilter : public SkFlattenable { -- abstract
487 static SkColorFilter* CreatXfermodeFilter() *** untested ***
488 static SkColorFilter* CreatePorterDuffFilter() *** untested ***
489 static SkColorFilter* CreateLightingFilter() -- tested
490./SkDrawLooper.h:9:class SkDrawLooper : public SkFlattenable { -- virtually abstract
491 ./SkBlurDrawLooper.h:9:class SkBlurDrawLooper : public SkDrawLooper { *** untested ***
492./SkMaskFilter.h:41:class SkMaskFilter : public SkFlattenable { -- abstract chmod +w .h
493 ./SkEmbossMaskFilter.h:27:class SkEmbossMaskFilter : public SkMaskFilter { -- tested
494./SkPathEffect.h:33:class SkPathEffect : public SkFlattenable { -- abstract
495 ./Sk1DPathEffect.h:27:class Sk1DPathEffect : public SkPathEffect { -- abstract
496 ./Sk1DPathEffect.h:48:class SkPath1DPathEffect : public Sk1DPathEffect { -- tested
497 ./Sk2DPathEffect.h:25:class Sk2DPathEffect : public SkPathEffect { *** untested ***
498 ./SkCornerPathEffect.h:28:class SkCornerPathEffect : public SkPathEffect { *** untested ***
499 ./SkDashPathEffect.h:27:class SkDashPathEffect : public SkPathEffect {
500 ./SkDiscretePathEffect.h:27:class SkDiscretePathEffect : public SkPathEffect {
501 ./SkPaint.h:760:class SkStrokePathEffect : public SkPathEffect {
502 ./SkPathEffect.h:58:class SkPairPathEffect : public SkPathEffect {
503 ./SkPathEffect.h:78:class SkComposePathEffect : public SkPairPathEffect {
504 ./SkPathEffect.h:114:class SkSumPathEffect : public SkPairPathEffect {
505./SkRasterizer.h:29:class SkRasterizer : public SkFlattenable {
506 ./SkLayerRasterizer.h:27:class SkLayerRasterizer : public SkRasterizer {
507./SkShader.h:36:class SkShader : public SkFlattenable {
508 ./SkColorFilter.h:59:class SkFilterShader : public SkShader {
509 ./SkColorShader.h:26:class SkColorShader : public SkShader {
510 ./SkShaderExtras.h:31:class SkComposeShader : public SkShader {
511 ./SkTransparentShader.h:23:class SkTransparentShader : public SkShader {
512./SkUnitMapper.h:24:class SkUnitMapper : public SkFlattenable {
513 ./SkUnitMapper.h:33:class SkDiscreteMapper : public SkUnitMapper {
514 ./SkUnitMapper.h:51:class SkFlipCosineMapper : public SkUnitMapper {
515./SkXfermode.h:32:class SkXfermode : public SkFlattenable {
516 ./SkAvoidXfermode.h:28:class SkAvoidXfermode : public SkXfermode { *** not done *** chmod +w .h .cpp
517 ./SkXfermode.h:54:class SkProcXfermode : public SkXfermode {
518 */
rmistry@google.comae933ce2012-08-23 18:19:56 +0000519
reed@android.com8a1c16f2008-12-17 15:59:43 +0000520 /*
521./SkBlurMaskFilter.h:25:class SkBlurMaskFilter {
522 chmod +w SkBlurMaskFilter.cpp
523./SkGradientShader.h:30:class SkGradientShader {
524 */
525 // save layer, bounder, looper
526 // matrix
527 // clip /path/region
528 // bitmap proc shader ?
529
530/* untested:
531SkCornerPathEffect.h:28:class SkCornerPathEffect : public SkPathEffect {
532*/
rmistry@google.comae933ce2012-08-23 18:19:56 +0000533
reed@google.com4d5c26d2013-01-08 16:17:50 +0000534 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000535 fClickPt.set(x, y);
536 this->inval(NULL);
reed@google.com4d5c26d2013-01-08 16:17:50 +0000537 return this->INHERITED::onFindClickHandler(x, y, modi);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000538 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000539
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000540 SkPathEffect* pathEffectTest() {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000541 static const int gXY[] = { 1, 0, 0, -1, 2, -1, 3, 0, 2, 1, 0, 1 };
542 SkScalar gPhase = 0;
543 SkPath path;
544 path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
545 for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
546 path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
547 path.close();
548 path.offset(SkIntToScalar(-6), 0);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000549 SkPathEffect* outer = new SkPath1DPathEffect(path, SkIntToScalar(12),
reed@android.com8a1c16f2008-12-17 15:59:43 +0000550 gPhase, SkPath1DPathEffect::kRotate_Style);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000551 SkPathEffect* inner = new SkDiscretePathEffect(SkIntToScalar(2),
reed@android.com8a1c16f2008-12-17 15:59:43 +0000552 SkIntToScalar(1)/10); // SkCornerPathEffect(SkIntToScalar(2));
553 SkPathEffect* result = new SkComposePathEffect(outer, inner);
554 outer->unref();
555 inner->unref();
556 return result;
557 }
reed@google.com963a8fa2012-05-10 13:04:59 +0000558
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000559 SkShader* shaderTest() {
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000560 SkPoint pts[] = { { 0, 0, }, { SkIntToScalar(100), 0 } };
reed@android.com8a1c16f2008-12-17 15:59:43 +0000561 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
rmistry@google.comae933ce2012-08-23 18:19:56 +0000562 SkShader* shaderA = SkGradientShader::CreateLinear(pts, colors, NULL,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000563 2, SkShader::kClamp_TileMode);
564 pts[1].set(0, SkIntToScalar(100));
565 SkColor colors2[] = {SK_ColorBLACK, SkColorSetARGB(0x80, 0, 0, 0)};
rmistry@google.comae933ce2012-08-23 18:19:56 +0000566 SkShader* shaderB = SkGradientShader::CreateLinear(pts, colors2, NULL,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000567 2, SkShader::kClamp_TileMode);
reed@android.com048522d2009-06-23 12:19:41 +0000568 SkXfermode* mode = SkXfermode::Create(SkXfermode::kDstIn_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000569 SkShader* result = new SkComposeShader(shaderA, shaderB, mode);
570 shaderA->unref();
571 shaderB->unref();
572 mode->unref();
573 return result;
574 }
575
576 virtual void startTest() {
rmistry@google.comae933ce2012-08-23 18:19:56 +0000577 SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/bugcirc.gif", &fBug);
578 SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/tbcirc.gif", &fTb);
579 SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/05psp04.gif", &fTx);
580 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000581
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000582 void drawRaster(SkCanvas* canvas) {
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000583 for (size_t index = 0; index < SK_ARRAY_COUNT(gRastProcs); index++)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000584 drawOneRaster(canvas);
585 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000586
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000587 void drawOneRaster(SkCanvas* canvas) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000588 canvas->save();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000589
590 SkScalar x = SkIntToScalar(20);
591 SkScalar y = SkIntToScalar(40);
592 SkPaint paint;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000593
reed@android.com8a1c16f2008-12-17 15:59:43 +0000594 paint.setAntiAlias(true);
595 paint.setTextSize(SkIntToScalar(48));
reed@android.comaa5a7db2009-05-27 01:20:10 +0000596 paint.setTypeface(SkTypeface::CreateFromName("sans-serif",
597 SkTypeface::kBold));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000598
599 SkString str("GOOGLE");
600
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000601 for (size_t i = 0; i < SK_ARRAY_COUNT(gRastProcs); i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000602 apply_shader(&paint, i);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000603
reed@android.com8a1c16f2008-12-17 15:59:43 +0000604 // paint.setMaskFilter(NULL);
605 // paint.setColor(SK_ColorBLACK);
606
607#if 01
608 int index = i % SK_ARRAY_COUNT(gLightingColors);
609 paint.setColorFilter(SkColorFilter::CreateLightingFilter(
610 gLightingColors[index].fMul,
611 gLightingColors[index].fAdd))->unref();
612#endif
rmistry@google.comae933ce2012-08-23 18:19:56 +0000613
reed@android.com8a1c16f2008-12-17 15:59:43 +0000614 canvas->drawText(str.c_str(), str.size(), x, y, paint);
615 SkRect oval = { x, y - SkIntToScalar(40), x + SkIntToScalar(40), y };
616 paint.setStyle(SkPaint::kStroke_Style);
617 canvas->drawOval(oval, paint);
618 paint.setStyle(SkPaint::kFill_Style);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000619
620 y += paint.getFontSpacing();
621 }
622
623 canvas->restore();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000624
reed@android.com6b82d1a2009-06-03 02:35:01 +0000625 if (1) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000626 SkAvoidXfermode mode(SK_ColorWHITE, 0xFF,
627 SkAvoidXfermode::kTargetColor_Mode);
628 SkPaint paint;
629 x += SkIntToScalar(20);
630 SkRect r = { x, 0, x + SkIntToScalar(360), SkIntToScalar(700) };
631 paint.setXfermode(&mode);
632 paint.setColor(SK_ColorGREEN);
633 paint.setAntiAlias(true);
634 canvas->drawOval(r, paint);
635 }
636 }
637
638private:
639 SkPoint fClickPt;
640 SkBitmap fBug, fTb, fTx;
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000641 typedef SampleView INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000642};
643
644//////////////////////////////////////////////////////////////////////////////
645
646static SkView* MyFactory() { return new DemoView; }
647static SkViewRegister reg(MyFactory);