blob: 8907a349e83a5a9ed49b70f0c014c51a9ab999c1 [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"
robertphillips@google.comb7061172013-09-06 14:16:12 +00009#include "SkBlurMask.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#include "SkCanvas.h"
11#include "SkView.h"
12#include "Sk1DPathEffect.h"
13#include "Sk2DPathEffect.h"
14#include "SkAvoidXfermode.h"
15#include "SkBlurMaskFilter.h"
16#include "SkColorFilter.h"
17#include "SkColorPriv.h"
18#include "SkCornerPathEffect.h"
19#include "SkDashPathEffect.h"
20#include "SkDiscretePathEffect.h"
21#include "SkEmbossMaskFilter.h"
djsollen@google.comc73dd5c2012-08-07 15:54:32 +000022#include "SkFlattenableBuffers.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000023#include "SkGradientShader.h"
24#include "SkImageDecoder.h"
25#include "SkLayerRasterizer.h"
26#include "SkMath.h"
27#include "SkPath.h"
28#include "SkRegion.h"
29#include "SkShader.h"
reed@android.comaa5a7db2009-05-27 01:20:10 +000030#include "SkComposeShader.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000031#include "SkCornerPathEffect.h"
32#include "SkPathMeasure.h"
33#include "SkPicture.h"
34#include "SkRandom.h"
35#include "SkTransparentShader.h"
36#include "SkTypeface.h"
37#include "SkUnitMappers.h"
38#include "SkUtils.h"
39#include "SkXfermode.h"
40
41#include <math.h>
rmistry@google.comae933ce2012-08-23 18:19:56 +000042
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000043static inline SkPMColor rgb2gray(SkPMColor c) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000044 unsigned r = SkGetPackedR32(c);
45 unsigned g = SkGetPackedG32(c);
46 unsigned b = SkGetPackedB32(c);
rmistry@google.comae933ce2012-08-23 18:19:56 +000047
reed@android.comf2b98d62010-12-20 18:26:13 +000048 unsigned x = (r * 5 + g * 7 + b * 4) >> 4;
rmistry@google.comae933ce2012-08-23 18:19:56 +000049
reed@android.com8a1c16f2008-12-17 15:59:43 +000050 return SkPackARGB32(0, x, x, x) | (c & (SK_A32_MASK << SK_A32_SHIFT));
51}
52
53class SkGrayScaleColorFilter : public SkColorFilter {
54public:
mike@reedtribe.org61490fa2012-12-24 14:38:46 +000055 virtual void filterSpan(const SkPMColor src[], int count,
56 SkPMColor result[]) const SK_OVERRIDE {
reed@android.com8a1c16f2008-12-17 15:59:43 +000057 for (int i = 0; i < count; i++)
58 result[i] = rgb2gray(src[i]);
59 }
60};
61
62class SkChannelMaskColorFilter : public SkColorFilter {
63public:
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000064 SkChannelMaskColorFilter(U8CPU redMask, U8CPU greenMask, U8CPU blueMask) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000065 fMask = SkPackARGB32(0xFF, redMask, greenMask, blueMask);
66 }
67
mike@reedtribe.org61490fa2012-12-24 14:38:46 +000068 virtual void filterSpan(const SkPMColor src[], int count,
69 SkPMColor result[]) const SK_OVERRIDE {
reed@android.com8a1c16f2008-12-17 15:59:43 +000070 SkPMColor mask = fMask;
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000071 for (int i = 0; i < count; i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000072 result[i] = src[i] & mask;
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000073 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000074 }
rmistry@google.comae933ce2012-08-23 18:19:56 +000075
reed@android.com8a1c16f2008-12-17 15:59:43 +000076private:
77 SkPMColor fMask;
78};
79
80///////////////////////////////////////////////////////////
81
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000082static void r0(SkLayerRasterizer* rast, SkPaint& p) {
robertphillips@google.comb7061172013-09-06 14:16:12 +000083 p.setMaskFilter(SkBlurMaskFilter::Create(SkBlurMaskFilter::kNormal_BlurStyle,
84 SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)),
robertphillips@google.com7ce661d2013-08-27 16:14:03 +000085 SkBlurMaskFilter::kNone_BlurFlag))->unref();
reed@android.com8a1c16f2008-12-17 15:59:43 +000086 rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
87
88 p.setMaskFilter(NULL);
89 p.setStyle(SkPaint::kStroke_Style);
90 p.setStrokeWidth(SK_Scalar1);
91 rast->addLayer(p);
92
93 p.setAlpha(0x11);
94 p.setStyle(SkPaint::kFill_Style);
reed@android.com0baf1932009-06-24 12:41:42 +000095 p.setXfermodeMode(SkXfermode::kSrc_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +000096 rast->addLayer(p);
97}
98
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000099static void r1(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000100 rast->addLayer(p);
101
102 p.setAlpha(0x40);
reed@android.com0baf1932009-06-24 12:41:42 +0000103 p.setXfermodeMode(SkXfermode::kSrc_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000104 p.setStyle(SkPaint::kStroke_Style);
105 p.setStrokeWidth(SK_Scalar1*2);
106 rast->addLayer(p);
107}
rmistry@google.comae933ce2012-08-23 18:19:56 +0000108
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000109static void r2(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000110 p.setStyle(SkPaint::kStrokeAndFill_Style);
111 p.setStrokeWidth(SK_Scalar1*4);
112 rast->addLayer(p);
113
114 p.setStyle(SkPaint::kStroke_Style);
115 p.setStrokeWidth(SK_Scalar1*3/2);
reed@android.com0baf1932009-06-24 12:41:42 +0000116 p.setXfermodeMode(SkXfermode::kClear_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000117 rast->addLayer(p);
118}
119
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000120static void r3(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000121 p.setStyle(SkPaint::kStroke_Style);
122 p.setStrokeWidth(SK_Scalar1*3);
123 rast->addLayer(p);
124
125 p.setAlpha(0x20);
126 p.setStyle(SkPaint::kFill_Style);
reed@android.com0baf1932009-06-24 12:41:42 +0000127 p.setXfermodeMode(SkXfermode::kSrc_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000128 rast->addLayer(p);
129}
130
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000131static void r4(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000132 p.setAlpha(0x60);
133 rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
134
135 p.setAlpha(0xFF);
reed@android.com0baf1932009-06-24 12:41:42 +0000136 p.setXfermodeMode(SkXfermode::kClear_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000137 rast->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2);
138
139 p.setXfermode(NULL);
140 rast->addLayer(p);
141}
142
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000143static void r5(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000144 rast->addLayer(p);
145
146 p.setPathEffect(new SkDiscretePathEffect(SK_Scalar1*4, SK_Scalar1*3))->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000147 p.setXfermodeMode(SkXfermode::kSrcOut_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000148 rast->addLayer(p);
149}
150
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000151static void r6(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000152 rast->addLayer(p);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000153
reed@android.com8a1c16f2008-12-17 15:59:43 +0000154 p.setAntiAlias(false);
155 SkLayerRasterizer* rast2 = new SkLayerRasterizer;
156 r5(rast2, p);
157 p.setRasterizer(rast2)->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000158 p.setXfermodeMode(SkXfermode::kClear_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000159 rast->addLayer(p);
160}
161
162class Dot2DPathEffect : public Sk2DPathEffect {
163public:
164 Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix)
165 : Sk2DPathEffect(matrix), fRadius(radius) {}
166
djsollen@google.comba28d032012-03-26 17:57:35 +0000167 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Dot2DPathEffect)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000168
169protected:
mike@reedtribe.org61490fa2012-12-24 14:38:46 +0000170 virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) const SK_OVERRIDE {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000171 dst->addCircle(loc.fX, loc.fY, fRadius);
172 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000173
djsollen@google.com54924242012-03-29 15:18:04 +0000174 Dot2DPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000175 fRadius = buffer.readScalar();
176 }
djsollen@google.com54924242012-03-29 15:18:04 +0000177 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
178 this->INHERITED::flatten(buffer);
179 buffer.writeScalar(fRadius);
180 }
181
reed@android.com8a1c16f2008-12-17 15:59:43 +0000182private:
183 SkScalar fRadius;
184
reed@android.com8a1c16f2008-12-17 15:59:43 +0000185 typedef Sk2DPathEffect INHERITED;
186};
187
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000188static void r7(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000189 SkMatrix lattice;
190 lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
191 lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
192 p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*4, lattice))->unref();
193 rast->addLayer(p);
194}
195
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000196static void r8(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000197 rast->addLayer(p);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000198
reed@android.com8a1c16f2008-12-17 15:59:43 +0000199 SkMatrix lattice;
200 lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
201 lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
202 p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*2, lattice))->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000203 p.setXfermodeMode(SkXfermode::kClear_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000204 rast->addLayer(p);
205
206 p.setPathEffect(NULL);
207 p.setXfermode(NULL);
208 p.setStyle(SkPaint::kStroke_Style);
209 p.setStrokeWidth(SK_Scalar1);
210 rast->addLayer(p);
211}
212
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000213static void r9(SkLayerRasterizer* rast, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000214 rast->addLayer(p);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000215
reed@android.com8a1c16f2008-12-17 15:59:43 +0000216 SkMatrix lattice;
217 lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0);
218 lattice.postRotate(SkIntToScalar(30), 0, 0);
scroggo@google.comd8a6cc82012-09-12 18:53:49 +0000219 p.setPathEffect(new SkLine2DPathEffect(SK_Scalar1*2, lattice))->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000220 p.setXfermodeMode(SkXfermode::kClear_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000221 rast->addLayer(p);
222
223 p.setPathEffect(NULL);
224 p.setXfermode(NULL);
225 p.setStyle(SkPaint::kStroke_Style);
226 p.setStrokeWidth(SK_Scalar1);
227 rast->addLayer(p);
228}
229
230typedef void (*raster_proc)(SkLayerRasterizer*, SkPaint&);
231
232static const raster_proc gRastProcs[] = {
233 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
234};
235
236static const struct {
237 SkColor fMul, fAdd;
238} gLightingColors[] = {
239 { 0x808080, 0x800000 }, // general case
240 { 0x707070, 0x707070 }, // no-pin case
241 { 0xFFFFFF, 0x800000 }, // just-add case
242 { 0x808080, 0x000000 }, // just-mul case
243 { 0xFFFFFF, 0x000000 } // identity case
244};
245
rmistry@google.comae933ce2012-08-23 18:19:56 +0000246static void apply_shader(SkPaint* paint, int index) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000247 raster_proc proc = gRastProcs[index];
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000248 if (proc) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000249 SkPaint p;
250 SkLayerRasterizer* rast = new SkLayerRasterizer;
251
252 p.setAntiAlias(true);
253 proc(rast, p);
254 paint->setRasterizer(rast)->unref();
255 }
256
257#if 1
258 SkScalar dir[] = { SK_Scalar1, SK_Scalar1, SK_Scalar1 };
robertphillips@google.comb7061172013-09-06 14:16:12 +0000259 paint->setMaskFilter(SkBlurMaskFilter::CreateEmboss(
260 SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)), dir,
261 SK_Scalar1/4, SkIntToScalar(4)))->unref();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000262 paint->setColor(SK_ColorBLUE);
263#endif
264}
265
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000266class DemoView : public SampleView {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000267public:
reed@google.com2f3dc9d2011-05-02 17:33:45 +0000268 DemoView() {}
rmistry@google.comae933ce2012-08-23 18:19:56 +0000269
reed@android.com8a1c16f2008-12-17 15:59:43 +0000270protected:
271 // overrides from SkEventSink
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000272 virtual bool onQuery(SkEvent* evt) {
273 if (SampleCode::TitleQ(*evt)) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000274 SampleCode::TitleR(evt, "Demo");
275 return true;
276 }
277 return this->INHERITED::onQuery(evt);
278 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000279
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000280 virtual bool onClick(Click* click) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000281 return this->INHERITED::onClick(click);
282 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000283
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000284 void makePath(SkPath& path) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000285 path.addCircle(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(20),
286 SkPath::kCCW_Direction);
287 for (int index = 0; index < 10; index++) {
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000288 SkScalar x = (float) cos(index / 10.0f * 2 * 3.1415925358f);
289 SkScalar y = (float) sin(index / 10.0f * 2 * 3.1415925358f);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000290 x *= index & 1 ? 7 : 14;
291 y *= index & 1 ? 7 : 14;
292 x += SkIntToScalar(20);
293 y += SkIntToScalar(20);
294 if (index == 0)
295 path.moveTo(x, y);
296 else
297 path.lineTo(x, y);
298 }
299 path.close();
300 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000301
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000302 virtual void onDrawContent(SkCanvas* canvas) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000303 canvas->save();
304 drawPicture(canvas, 0);
305 canvas->restore();
306
307 {
308 SkPicture picture;
309 SkCanvas* record = picture.beginRecording(320, 480);
310 drawPicture(record, 120);
311 canvas->translate(0, SkIntToScalar(120));
312
313 SkRect clip;
314 clip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
315 do {
316 canvas->save();
317 canvas->clipRect(clip);
318 picture.draw(canvas);
319 canvas->restore();
320 if (clip.fRight < SkIntToScalar(320))
321 clip.offset(SkIntToScalar(160), 0);
322 else if (clip.fBottom < SkIntToScalar(480))
323 clip.offset(-SkIntToScalar(320), SkIntToScalar(160));
324 else
325 break;
326 } while (true);
327 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000328 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000329
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000330 void drawPicture(SkCanvas* canvas, int spriteOffset) {
rmistry@google.comae933ce2012-08-23 18:19:56 +0000331 SkMatrix matrix; matrix.reset();
332 SkPaint paint;
333 SkPath path;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000334 SkPoint start = {0, 0};
335 SkPoint stop = { SkIntToScalar(40), SkIntToScalar(40) };
rmistry@google.comae933ce2012-08-23 18:19:56 +0000336 SkRect rect = {0, 0, SkIntToScalar(40), SkIntToScalar(40) };
337 SkRect rect2 = {0, 0, SkIntToScalar(65), SkIntToScalar(20) };
338 SkScalar left = 0, top = 0, x = 0, y = 0;
339 size_t index;
340
341 char ascii[] = "ascii...";
342 size_t asciiLength = sizeof(ascii) - 1;
343 char utf8[] = "utf8" "\xe2\x80\xa6";
344 short utf16[] = {'u', 't', 'f', '1', '6', 0x2026 };
345 short utf16simple[] = {'u', 't', 'f', '1', '6', '!' };
346
reed@android.com8a1c16f2008-12-17 15:59:43 +0000347 makePath(path);
348 SkTDArray<SkPoint>(pos);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000349 pos.setCount(asciiLength);
350 for (index = 0; index < asciiLength; index++)
351 pos[index].set(SkIntToScalar((unsigned int)index * 10),
tomhudson@google.comffe39bd2012-05-17 15:38:00 +0000352 SkIntToScalar((unsigned int)index * 2));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000353 SkTDArray<SkPoint>(pos2);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000354 pos2.setCount(asciiLength);
355 for (index = 0; index < asciiLength; index++)
356 pos2[index].set(SkIntToScalar((unsigned int)index * 10),
tomhudson@google.comffe39bd2012-05-17 15:38:00 +0000357 SkIntToScalar(20));
rmistry@google.comae933ce2012-08-23 18:19:56 +0000358
reed@android.com8a1c16f2008-12-17 15:59:43 +0000359 // shaders
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000360 SkPoint linearPoints[] = { { 0, 0, }, { SkIntToScalar(40), SkIntToScalar(40) } };
reed@android.com8a1c16f2008-12-17 15:59:43 +0000361 SkColor linearColors[] = { SK_ColorRED, SK_ColorBLUE };
362 SkScalar* linearPos = NULL;
363 int linearCount = 2;
364 SkShader::TileMode linearMode = SkShader::kMirror_TileMode;
365 SkUnitMapper* linearMapper = new SkDiscreteMapper(3);
366 SkAutoUnref unmapLinearMapper(linearMapper);
367 SkShader* linear = SkGradientShader::CreateLinear(linearPoints,
368 linearColors, linearPos, linearCount, linearMode, linearMapper);
369
370 SkPoint radialCenter = { SkIntToScalar(25), SkIntToScalar(25) };
371 SkScalar radialRadius = SkIntToScalar(25);
372 SkColor radialColors[] = { SK_ColorGREEN, SK_ColorGRAY, SK_ColorRED };
373 SkScalar radialPos[] = { 0, SkIntToScalar(3) / 5, SkIntToScalar(1)};
374 int radialCount = 3;
375 SkShader::TileMode radialMode = SkShader::kRepeat_TileMode;
376 SkUnitMapper* radialMapper = new SkCosineMapper();
377 SkAutoUnref unmapRadialMapper(radialMapper);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000378 SkShader* radial = SkGradientShader::CreateRadial(radialCenter,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000379 radialRadius, radialColors, radialPos, radialCount,
380 radialMode, radialMapper);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000381
reed@android.com8a1c16f2008-12-17 15:59:43 +0000382 SkTransparentShader* transparentShader = new SkTransparentShader();
383 SkEmbossMaskFilter::Light light;
384 light.fDirection[0] = SK_Scalar1/2;
385 light.fDirection[1] = SK_Scalar1/2;
386 light.fDirection[2] = SK_Scalar1/3;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000387 light.fAmbient = 0x48;
388 light.fSpecular = 0x80;
robertphillips@google.comb7061172013-09-06 14:16:12 +0000389 SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(12)/5);
390 SkEmbossMaskFilter* embossFilter = new SkEmbossMaskFilter(sigma, light);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000391
reed@android.com048522d2009-06-23 12:19:41 +0000392 SkXfermode* xfermode = SkXfermode::Create(SkXfermode::kXor_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000393 SkColorFilter* lightingFilter = SkColorFilter::CreateLightingFilter(
394 0xff89bc45, 0xff112233);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000395
reed@android.com8a1c16f2008-12-17 15:59:43 +0000396 canvas->save();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000397 canvas->translate(SkIntToScalar(0), SkIntToScalar(5));
reed@google.com9cfc83c2013-07-22 17:18:18 +0000398 paint.setAntiAlias(true);
399 paint.setFilterLevel(SkPaint::kLow_FilterLevel);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000400 // !!! draw through a clip
401 paint.setColor(SK_ColorLTGRAY);
402 paint.setStyle(SkPaint::kFill_Style);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000403 SkRect clip = {0, 0, SkIntToScalar(320), SkIntToScalar(120)};
404 canvas->clipRect(clip);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000405 paint.setShader(SkShader::CreateBitmapShader(fTx,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000406 SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode))->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000407 canvas->drawPaint(paint);
408 canvas->save();
409
reed@android.com8a1c16f2008-12-17 15:59:43 +0000410 // line (exercises xfermode, colorShader, colorFilter, filterShader)
rmistry@google.comae933ce2012-08-23 18:19:56 +0000411 paint.setColor(SK_ColorGREEN);
412 paint.setStrokeWidth(SkIntToScalar(10));
413 paint.setStyle(SkPaint::kStroke_Style);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000414 paint.setXfermode(xfermode)->unref();
415 paint.setColorFilter(lightingFilter)->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000416 canvas->drawLine(start.fX, start.fY, stop.fX, stop.fY, paint); // should not be green
417 paint.setXfermode(NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000418 paint.setColorFilter(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000419
reed@android.com8a1c16f2008-12-17 15:59:43 +0000420 // rectangle
rmistry@google.comae933ce2012-08-23 18:19:56 +0000421 paint.setStyle(SkPaint::kFill_Style);
422 canvas->translate(SkIntToScalar(50), 0);
423 paint.setColor(SK_ColorYELLOW);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000424 paint.setShader(linear)->unref();
425 paint.setPathEffect(pathEffectTest())->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000426 canvas->drawRect(rect, paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000427 paint.setPathEffect(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000428
reed@android.com8a1c16f2008-12-17 15:59:43 +0000429 // circle w/ emboss & transparent (exercises 3dshader)
rmistry@google.comae933ce2012-08-23 18:19:56 +0000430 canvas->translate(SkIntToScalar(50), 0);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000431 paint.setMaskFilter(embossFilter)->unref();
432 canvas->drawOval(rect, paint);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000433 canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000434 paint.setShader(transparentShader)->unref();
435 canvas->drawOval(rect, paint);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000436 canvas->translate(0, SkIntToScalar(-10));
437
reed@android.com8a1c16f2008-12-17 15:59:43 +0000438 // path
rmistry@google.comae933ce2012-08-23 18:19:56 +0000439 canvas->translate(SkIntToScalar(50), 0);
440 paint.setColor(SK_ColorRED);
441 paint.setStyle(SkPaint::kStroke_Style);
442 paint.setStrokeWidth(SkIntToScalar(5));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000443 paint.setShader(radial)->unref();
444 paint.setMaskFilter(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000445 canvas->drawPath(path, paint);
446
reed@android.com8a1c16f2008-12-17 15:59:43 +0000447 paint.setShader(NULL);
448 // bitmap, sprite
rmistry@google.comae933ce2012-08-23 18:19:56 +0000449 canvas->translate(SkIntToScalar(50), 0);
450 paint.setStyle(SkPaint::kFill_Style);
451 canvas->drawBitmap(fBug, left, top, &paint);
452 canvas->translate(SkIntToScalar(30), 0);
453 canvas->drawSprite(fTb,
454 SkScalarRound(canvas->getTotalMatrix().getTranslateX()),
reed@android.com8a1c16f2008-12-17 15:59:43 +0000455 spriteOffset + 10, &paint);
456
rmistry@google.comae933ce2012-08-23 18:19:56 +0000457 canvas->translate(-SkIntToScalar(30), SkIntToScalar(30));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000458 paint.setShader(shaderTest())->unref(); // test compose shader
rmistry@google.comae933ce2012-08-23 18:19:56 +0000459 canvas->drawRect(rect2, paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000460 paint.setShader(NULL);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000461
reed@android.com8a1c16f2008-12-17 15:59:43 +0000462 canvas->restore();
463 // text
reed@android.com8a1c16f2008-12-17 15:59:43 +0000464 canvas->translate(0, SkIntToScalar(60));
rmistry@google.comae933ce2012-08-23 18:19:56 +0000465 canvas->save();
466 paint.setColor(SK_ColorGRAY);
467 canvas->drawPosText(ascii, asciiLength, pos.begin(), paint);
468 canvas->drawPosText(ascii, asciiLength, pos2.begin(), paint);
469
470 canvas->translate(SkIntToScalar(50), 0);
471 paint.setColor(SK_ColorCYAN);
472 canvas->drawText(utf8, sizeof(utf8) - 1, x, y, paint);
473
474 canvas->translate(SkIntToScalar(30), 0);
475 paint.setColor(SK_ColorMAGENTA);
476 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
477 matrix.setTranslate(SkIntToScalar(10), SkIntToScalar(10));
478 canvas->drawTextOnPath((void*) utf16, sizeof(utf16), path, &matrix, paint);
479 canvas->translate(0, SkIntToScalar(20));
480 canvas->drawTextOnPath((void*) utf16simple, sizeof(utf16simple), path, &matrix, paint);
481 canvas->restore();
482
483 canvas->translate(0, SkIntToScalar(60));
484 paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000485 canvas->restore();
486 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000487
reed@android.com8a1c16f2008-12-17 15:59:43 +0000488 /*
489./SkColorFilter.h:25:class SkColorFilter : public SkFlattenable { -- abstract
490 static SkColorFilter* CreatXfermodeFilter() *** untested ***
491 static SkColorFilter* CreatePorterDuffFilter() *** untested ***
492 static SkColorFilter* CreateLightingFilter() -- tested
493./SkDrawLooper.h:9:class SkDrawLooper : public SkFlattenable { -- virtually abstract
494 ./SkBlurDrawLooper.h:9:class SkBlurDrawLooper : public SkDrawLooper { *** untested ***
495./SkMaskFilter.h:41:class SkMaskFilter : public SkFlattenable { -- abstract chmod +w .h
496 ./SkEmbossMaskFilter.h:27:class SkEmbossMaskFilter : public SkMaskFilter { -- tested
497./SkPathEffect.h:33:class SkPathEffect : public SkFlattenable { -- abstract
498 ./Sk1DPathEffect.h:27:class Sk1DPathEffect : public SkPathEffect { -- abstract
499 ./Sk1DPathEffect.h:48:class SkPath1DPathEffect : public Sk1DPathEffect { -- tested
500 ./Sk2DPathEffect.h:25:class Sk2DPathEffect : public SkPathEffect { *** untested ***
501 ./SkCornerPathEffect.h:28:class SkCornerPathEffect : public SkPathEffect { *** untested ***
502 ./SkDashPathEffect.h:27:class SkDashPathEffect : public SkPathEffect {
503 ./SkDiscretePathEffect.h:27:class SkDiscretePathEffect : public SkPathEffect {
504 ./SkPaint.h:760:class SkStrokePathEffect : public SkPathEffect {
505 ./SkPathEffect.h:58:class SkPairPathEffect : public SkPathEffect {
506 ./SkPathEffect.h:78:class SkComposePathEffect : public SkPairPathEffect {
507 ./SkPathEffect.h:114:class SkSumPathEffect : public SkPairPathEffect {
508./SkRasterizer.h:29:class SkRasterizer : public SkFlattenable {
509 ./SkLayerRasterizer.h:27:class SkLayerRasterizer : public SkRasterizer {
510./SkShader.h:36:class SkShader : public SkFlattenable {
511 ./SkColorFilter.h:59:class SkFilterShader : public SkShader {
512 ./SkColorShader.h:26:class SkColorShader : public SkShader {
513 ./SkShaderExtras.h:31:class SkComposeShader : public SkShader {
514 ./SkTransparentShader.h:23:class SkTransparentShader : public SkShader {
515./SkUnitMapper.h:24:class SkUnitMapper : public SkFlattenable {
516 ./SkUnitMapper.h:33:class SkDiscreteMapper : public SkUnitMapper {
517 ./SkUnitMapper.h:51:class SkFlipCosineMapper : public SkUnitMapper {
518./SkXfermode.h:32:class SkXfermode : public SkFlattenable {
519 ./SkAvoidXfermode.h:28:class SkAvoidXfermode : public SkXfermode { *** not done *** chmod +w .h .cpp
520 ./SkXfermode.h:54:class SkProcXfermode : public SkXfermode {
521 */
rmistry@google.comae933ce2012-08-23 18:19:56 +0000522
reed@android.com8a1c16f2008-12-17 15:59:43 +0000523 /*
524./SkBlurMaskFilter.h:25:class SkBlurMaskFilter {
525 chmod +w SkBlurMaskFilter.cpp
526./SkGradientShader.h:30:class SkGradientShader {
527 */
528 // save layer, bounder, looper
529 // matrix
530 // clip /path/region
531 // bitmap proc shader ?
532
533/* untested:
534SkCornerPathEffect.h:28:class SkCornerPathEffect : public SkPathEffect {
535*/
rmistry@google.comae933ce2012-08-23 18:19:56 +0000536
reed@google.com4d5c26d2013-01-08 16:17:50 +0000537 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000538 fClickPt.set(x, y);
539 this->inval(NULL);
reed@google.com4d5c26d2013-01-08 16:17:50 +0000540 return this->INHERITED::onFindClickHandler(x, y, modi);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000541 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000542
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000543 SkPathEffect* pathEffectTest() {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000544 static const int gXY[] = { 1, 0, 0, -1, 2, -1, 3, 0, 2, 1, 0, 1 };
545 SkScalar gPhase = 0;
546 SkPath path;
547 path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
548 for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
549 path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
550 path.close();
551 path.offset(SkIntToScalar(-6), 0);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000552 SkPathEffect* outer = new SkPath1DPathEffect(path, SkIntToScalar(12),
reed@android.com8a1c16f2008-12-17 15:59:43 +0000553 gPhase, SkPath1DPathEffect::kRotate_Style);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000554 SkPathEffect* inner = new SkDiscretePathEffect(SkIntToScalar(2),
reed@android.com8a1c16f2008-12-17 15:59:43 +0000555 SkIntToScalar(1)/10); // SkCornerPathEffect(SkIntToScalar(2));
556 SkPathEffect* result = new SkComposePathEffect(outer, inner);
557 outer->unref();
558 inner->unref();
559 return result;
560 }
reed@google.com963a8fa2012-05-10 13:04:59 +0000561
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000562 SkShader* shaderTest() {
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000563 SkPoint pts[] = { { 0, 0, }, { SkIntToScalar(100), 0 } };
reed@android.com8a1c16f2008-12-17 15:59:43 +0000564 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
rmistry@google.comae933ce2012-08-23 18:19:56 +0000565 SkShader* shaderA = SkGradientShader::CreateLinear(pts, colors, NULL,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000566 2, SkShader::kClamp_TileMode);
567 pts[1].set(0, SkIntToScalar(100));
568 SkColor colors2[] = {SK_ColorBLACK, SkColorSetARGB(0x80, 0, 0, 0)};
rmistry@google.comae933ce2012-08-23 18:19:56 +0000569 SkShader* shaderB = SkGradientShader::CreateLinear(pts, colors2, NULL,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000570 2, SkShader::kClamp_TileMode);
reed@android.com048522d2009-06-23 12:19:41 +0000571 SkXfermode* mode = SkXfermode::Create(SkXfermode::kDstIn_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000572 SkShader* result = new SkComposeShader(shaderA, shaderB, mode);
573 shaderA->unref();
574 shaderB->unref();
575 mode->unref();
576 return result;
577 }
578
579 virtual void startTest() {
rmistry@google.comae933ce2012-08-23 18:19:56 +0000580 SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/bugcirc.gif", &fBug);
581 SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/tbcirc.gif", &fTb);
582 SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/05psp04.gif", &fTx);
583 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000584
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000585 void drawRaster(SkCanvas* canvas) {
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000586 for (size_t index = 0; index < SK_ARRAY_COUNT(gRastProcs); index++)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000587 drawOneRaster(canvas);
588 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000589
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000590 void drawOneRaster(SkCanvas* canvas) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000591 canvas->save();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000592
593 SkScalar x = SkIntToScalar(20);
594 SkScalar y = SkIntToScalar(40);
595 SkPaint paint;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000596
reed@android.com8a1c16f2008-12-17 15:59:43 +0000597 paint.setAntiAlias(true);
598 paint.setTextSize(SkIntToScalar(48));
reed@android.comaa5a7db2009-05-27 01:20:10 +0000599 paint.setTypeface(SkTypeface::CreateFromName("sans-serif",
600 SkTypeface::kBold));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000601
602 SkString str("GOOGLE");
603
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000604 for (size_t i = 0; i < SK_ARRAY_COUNT(gRastProcs); i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000605 apply_shader(&paint, i);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000606
reed@android.com8a1c16f2008-12-17 15:59:43 +0000607 // paint.setMaskFilter(NULL);
608 // paint.setColor(SK_ColorBLACK);
609
610#if 01
611 int index = i % SK_ARRAY_COUNT(gLightingColors);
612 paint.setColorFilter(SkColorFilter::CreateLightingFilter(
613 gLightingColors[index].fMul,
614 gLightingColors[index].fAdd))->unref();
615#endif
rmistry@google.comae933ce2012-08-23 18:19:56 +0000616
reed@android.com8a1c16f2008-12-17 15:59:43 +0000617 canvas->drawText(str.c_str(), str.size(), x, y, paint);
618 SkRect oval = { x, y - SkIntToScalar(40), x + SkIntToScalar(40), y };
619 paint.setStyle(SkPaint::kStroke_Style);
620 canvas->drawOval(oval, paint);
621 paint.setStyle(SkPaint::kFill_Style);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000622
623 y += paint.getFontSpacing();
624 }
625
626 canvas->restore();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000627
reed@android.com6b82d1a2009-06-03 02:35:01 +0000628 if (1) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000629 SkAvoidXfermode mode(SK_ColorWHITE, 0xFF,
630 SkAvoidXfermode::kTargetColor_Mode);
631 SkPaint paint;
632 x += SkIntToScalar(20);
633 SkRect r = { x, 0, x + SkIntToScalar(360), SkIntToScalar(700) };
634 paint.setXfermode(&mode);
635 paint.setColor(SK_ColorGREEN);
636 paint.setAntiAlias(true);
637 canvas->drawOval(r, paint);
638 }
639 }
640
641private:
642 SkPoint fClickPt;
643 SkBitmap fBug, fTb, fTx;
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000644 typedef SampleView INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000645};
646
647//////////////////////////////////////////////////////////////////////////////
648
649static SkView* MyFactory() { return new DemoView; }
650static SkViewRegister reg(MyFactory);