blob: 7c0557fc40e4a61a2a0a97fb1c72dde7736771c5 [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"
reed@android.com8a1c16f2008-12-17 15:59:43 +000014#include "SkBlurMaskFilter.h"
reed0daf5dd2016-01-11 12:34:04 -080015#include "SkColorMatrixFilter.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000016#include "SkColorPriv.h"
17#include "SkCornerPathEffect.h"
18#include "SkDashPathEffect.h"
19#include "SkDiscretePathEffect.h"
20#include "SkEmbossMaskFilter.h"
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000021#include "SkReadBuffer.h"
22#include "SkWriteBuffer.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"
robertphillips@google.com770963f2014-04-18 18:04:41 +000028#include "SkPictureRecorder.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000029#include "SkRegion.h"
30#include "SkShader.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"
reed@android.com8a1c16f2008-12-17 15:59:43 +000035#include "SkTypeface.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000036#include "SkUtils.h"
37#include "SkXfermode.h"
38
39#include <math.h>
rmistry@google.comae933ce2012-08-23 18:19:56 +000040
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000041static inline SkPMColor rgb2gray(SkPMColor c) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000042 unsigned r = SkGetPackedR32(c);
43 unsigned g = SkGetPackedG32(c);
44 unsigned b = SkGetPackedB32(c);
rmistry@google.comae933ce2012-08-23 18:19:56 +000045
reed@android.comf2b98d62010-12-20 18:26:13 +000046 unsigned x = (r * 5 + g * 7 + b * 4) >> 4;
rmistry@google.comae933ce2012-08-23 18:19:56 +000047
reed@android.com8a1c16f2008-12-17 15:59:43 +000048 return SkPackARGB32(0, x, x, x) | (c & (SK_A32_MASK << SK_A32_SHIFT));
49}
50
51class SkGrayScaleColorFilter : public SkColorFilter {
52public:
mike@reedtribe.org61490fa2012-12-24 14:38:46 +000053 virtual void filterSpan(const SkPMColor src[], int count,
mtklein36352bf2015-03-25 18:17:31 -070054 SkPMColor result[]) const override {
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.org61490fa2012-12-24 14:38:46 +000066 virtual void filterSpan(const SkPMColor src[], int count,
mtklein36352bf2015-03-25 18:17:31 -070067 SkPMColor result[]) const override {
reed@android.com8a1c16f2008-12-17 15:59:43 +000068 SkPMColor mask = fMask;
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000069 for (int i = 0; i < count; i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000070 result[i] = src[i] & mask;
mike@reedtribe.org5fd92432011-05-05 01:59:48 +000071 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000072 }
rmistry@google.comae933ce2012-08-23 18:19:56 +000073
reed@android.com8a1c16f2008-12-17 15:59:43 +000074private:
75 SkPMColor fMask;
76};
77
78///////////////////////////////////////////////////////////
79
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +000080static void r0(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
commit-bot@chromium.orge3964552014-04-28 16:25:35 +000081 p.setMaskFilter(SkBlurMaskFilter::Create(kNormal_SkBlurStyle,
robertphillips@google.comb7061172013-09-06 14:16:12 +000082 SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)),
robertphillips@google.com7ce661d2013-08-27 16:14:03 +000083 SkBlurMaskFilter::kNone_BlurFlag))->unref();
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +000084 rastBuilder->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
reed@android.com8a1c16f2008-12-17 15:59:43 +000085
halcanary96fcdcc2015-08-27 07:41:13 -070086 p.setMaskFilter(nullptr);
reed@android.com8a1c16f2008-12-17 15:59:43 +000087 p.setStyle(SkPaint::kStroke_Style);
88 p.setStrokeWidth(SK_Scalar1);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +000089 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +000090
91 p.setAlpha(0x11);
92 p.setStyle(SkPaint::kFill_Style);
reed@android.com0baf1932009-06-24 12:41:42 +000093 p.setXfermodeMode(SkXfermode::kSrc_Mode);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +000094 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +000095}
96
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +000097static void r1(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
98 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +000099
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);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000104 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000105}
rmistry@google.comae933ce2012-08-23 18:19:56 +0000106
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000107static void r2(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000108 p.setStyle(SkPaint::kStrokeAndFill_Style);
109 p.setStrokeWidth(SK_Scalar1*4);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000110 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000111
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);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000115 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000116}
117
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000118static void r3(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000119 p.setStyle(SkPaint::kStroke_Style);
120 p.setStrokeWidth(SK_Scalar1*3);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000121 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000122
123 p.setAlpha(0x20);
124 p.setStyle(SkPaint::kFill_Style);
reed@android.com0baf1932009-06-24 12:41:42 +0000125 p.setXfermodeMode(SkXfermode::kSrc_Mode);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000126 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000127}
128
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000129static void r4(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000130 p.setAlpha(0x60);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000131 rastBuilder->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000132
133 p.setAlpha(0xFF);
reed@android.com0baf1932009-06-24 12:41:42 +0000134 p.setXfermodeMode(SkXfermode::kClear_Mode);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000135 rastBuilder->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000136
halcanary96fcdcc2015-08-27 07:41:13 -0700137 p.setXfermode(nullptr);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000138 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000139}
140
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000141static void r5(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
142 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000143
reeda4393342016-03-18 11:22:57 -0700144 p.setPathEffect(SkDiscretePathEffect::Make(SK_Scalar1*4, SK_Scalar1*3));
reed@android.com0baf1932009-06-24 12:41:42 +0000145 p.setXfermodeMode(SkXfermode::kSrcOut_Mode);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000146 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000147}
148
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000149static void r6(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
150 rastBuilder->addLayer(p);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000151
reed@android.com8a1c16f2008-12-17 15:59:43 +0000152 p.setAntiAlias(false);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000153 SkLayerRasterizer::Builder rastBuilder2;
154 r5(&rastBuilder2, p);
155 p.setRasterizer(rastBuilder2.detachRasterizer())->unref();
reed@android.com0baf1932009-06-24 12:41:42 +0000156 p.setXfermodeMode(SkXfermode::kClear_Mode);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000157 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000158}
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:
mtklein36352bf2015-03-25 18:17:31 -0700168 void next(const SkPoint& loc, int u, int v, SkPath* dst) const 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
mtklein36352bf2015-03-25 18:17:31 -0700172 void flatten(SkWriteBuffer& buffer) const override {
djsollen@google.com54924242012-03-29 15:18:04 +0000173 this->INHERITED::flatten(buffer);
174 buffer.writeScalar(fRadius);
175 }
176
reed@android.com8a1c16f2008-12-17 15:59:43 +0000177private:
178 SkScalar fRadius;
179
reed@android.com8a1c16f2008-12-17 15:59:43 +0000180 typedef Sk2DPathEffect INHERITED;
181};
182
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000183static void r7(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000184 SkMatrix lattice;
185 lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
186 lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
reeda4393342016-03-18 11:22:57 -0700187 p.setPathEffect(sk_make_sp<Dot2DPathEffect>(SK_Scalar1*4, lattice));
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000188 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000189}
190
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000191static void r8(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
192 rastBuilder->addLayer(p);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000193
reed@android.com8a1c16f2008-12-17 15:59:43 +0000194 SkMatrix lattice;
195 lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
196 lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
reeda4393342016-03-18 11:22:57 -0700197 p.setPathEffect(sk_make_sp<Dot2DPathEffect>(SK_Scalar1*2, lattice));
reed@android.com0baf1932009-06-24 12:41:42 +0000198 p.setXfermodeMode(SkXfermode::kClear_Mode);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000199 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000200
halcanary96fcdcc2015-08-27 07:41:13 -0700201 p.setPathEffect(nullptr);
202 p.setXfermode(nullptr);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000203 p.setStyle(SkPaint::kStroke_Style);
204 p.setStrokeWidth(SK_Scalar1);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000205 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000206}
207
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000208static void r9(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
209 rastBuilder->addLayer(p);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000210
reed@android.com8a1c16f2008-12-17 15:59:43 +0000211 SkMatrix lattice;
212 lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0);
213 lattice.postRotate(SkIntToScalar(30), 0, 0);
reeda4393342016-03-18 11:22:57 -0700214 p.setPathEffect(SkLine2DPathEffect::Make(SK_Scalar1*2, lattice));
reed@android.com0baf1932009-06-24 12:41:42 +0000215 p.setXfermodeMode(SkXfermode::kClear_Mode);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000216 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000217
halcanary96fcdcc2015-08-27 07:41:13 -0700218 p.setPathEffect(nullptr);
219 p.setXfermode(nullptr);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000220 p.setStyle(SkPaint::kStroke_Style);
221 p.setStrokeWidth(SK_Scalar1);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000222 rastBuilder->addLayer(p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000223}
224
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000225typedef void (*raster_proc)(SkLayerRasterizer::Builder*, SkPaint&);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000226
227static const raster_proc gRastProcs[] = {
228 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
229};
230
231static const struct {
232 SkColor fMul, fAdd;
233} gLightingColors[] = {
234 { 0x808080, 0x800000 }, // general case
235 { 0x707070, 0x707070 }, // no-pin case
236 { 0xFFFFFF, 0x800000 }, // just-add case
237 { 0x808080, 0x000000 }, // just-mul case
238 { 0xFFFFFF, 0x000000 } // identity case
239};
240
rmistry@google.comae933ce2012-08-23 18:19:56 +0000241static void apply_shader(SkPaint* paint, int index) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000242 raster_proc proc = gRastProcs[index];
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000243 if (proc) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000244 SkPaint p;
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000245 SkLayerRasterizer::Builder rastBuilder;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000246
247 p.setAntiAlias(true);
commit-bot@chromium.orgf792a1b2014-02-26 13:27:37 +0000248 proc(&rastBuilder, p);
249 paint->setRasterizer(rastBuilder.detachRasterizer())->unref();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000250 }
251
252#if 1
253 SkScalar dir[] = { SK_Scalar1, SK_Scalar1, SK_Scalar1 };
robertphillips@google.comb7061172013-09-06 14:16:12 +0000254 paint->setMaskFilter(SkBlurMaskFilter::CreateEmboss(
255 SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)), dir,
256 SK_Scalar1/4, SkIntToScalar(4)))->unref();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000257 paint->setColor(SK_ColorBLUE);
258#endif
259}
260
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000261class DemoView : public SampleView {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000262public:
reed@google.com2f3dc9d2011-05-02 17:33:45 +0000263 DemoView() {}
rmistry@google.comae933ce2012-08-23 18:19:56 +0000264
reed@android.com8a1c16f2008-12-17 15:59:43 +0000265protected:
266 // overrides from SkEventSink
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000267 virtual bool onQuery(SkEvent* evt) {
268 if (SampleCode::TitleQ(*evt)) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000269 SampleCode::TitleR(evt, "Demo");
270 return true;
271 }
272 return this->INHERITED::onQuery(evt);
273 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000274
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000275 virtual bool onClick(Click* click) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000276 return this->INHERITED::onClick(click);
277 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000278
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000279 void makePath(SkPath& path) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000280 path.addCircle(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(20),
281 SkPath::kCCW_Direction);
282 for (int index = 0; index < 10; index++) {
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000283 SkScalar x = (float) cos(index / 10.0f * 2 * 3.1415925358f);
284 SkScalar y = (float) sin(index / 10.0f * 2 * 3.1415925358f);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000285 x *= index & 1 ? 7 : 14;
286 y *= index & 1 ? 7 : 14;
287 x += SkIntToScalar(20);
288 y += SkIntToScalar(20);
289 if (index == 0)
290 path.moveTo(x, y);
291 else
292 path.lineTo(x, y);
293 }
294 path.close();
295 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000296
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000297 virtual void onDrawContent(SkCanvas* canvas) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000298 canvas->save();
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000299 this->drawPicture(canvas, 0);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000300 canvas->restore();
301
302 {
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000303 SkPictureRecorder recorder;
304 {
halcanary96fcdcc2015-08-27 07:41:13 -0700305 SkCanvas* record = recorder.beginRecording(320, 480, nullptr, 0);
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000306 this->drawPicture(record, 120);
307 }
reedca2622b2016-03-18 07:25:55 -0700308 sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000309
reed@android.com8a1c16f2008-12-17 15:59:43 +0000310 canvas->translate(0, SkIntToScalar(120));
311
312 SkRect clip;
313 clip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
314 do {
315 canvas->save();
316 canvas->clipRect(clip);
robertphillipsc5ba71d2014-09-04 08:42:50 -0700317 picture->playback(canvas);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000318 canvas->restore();
319 if (clip.fRight < SkIntToScalar(320))
320 clip.offset(SkIntToScalar(160), 0);
321 else if (clip.fBottom < SkIntToScalar(480))
322 clip.offset(-SkIntToScalar(320), SkIntToScalar(160));
323 else
324 break;
325 } while (true);
326 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000327 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000328
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000329 void drawPicture(SkCanvas* canvas, int spriteOffset) {
rmistry@google.comae933ce2012-08-23 18:19:56 +0000330 SkMatrix matrix; matrix.reset();
331 SkPaint paint;
332 SkPath path;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000333 SkPoint start = {0, 0};
334 SkPoint stop = { SkIntToScalar(40), SkIntToScalar(40) };
rmistry@google.comae933ce2012-08-23 18:19:56 +0000335 SkRect rect = {0, 0, SkIntToScalar(40), SkIntToScalar(40) };
336 SkRect rect2 = {0, 0, SkIntToScalar(65), SkIntToScalar(20) };
337 SkScalar left = 0, top = 0, x = 0, y = 0;
reed@google.com7fa2a652014-01-27 13:42:58 +0000338 int index;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000339
340 char ascii[] = "ascii...";
reed@google.com7fa2a652014-01-27 13:42:58 +0000341 int asciiLength = sizeof(ascii) - 1;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000342 char utf8[] = "utf8" "\xe2\x80\xa6";
343 short utf16[] = {'u', 't', 'f', '1', '6', 0x2026 };
344 short utf16simple[] = {'u', 't', 'f', '1', '6', '!' };
345
reed@android.com8a1c16f2008-12-17 15:59:43 +0000346 makePath(path);
347 SkTDArray<SkPoint>(pos);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000348 pos.setCount(asciiLength);
349 for (index = 0; index < asciiLength; index++)
350 pos[index].set(SkIntToScalar((unsigned int)index * 10),
tomhudson@google.comffe39bd2012-05-17 15:38:00 +0000351 SkIntToScalar((unsigned int)index * 2));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000352 SkTDArray<SkPoint>(pos2);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000353 pos2.setCount(asciiLength);
354 for (index = 0; index < asciiLength; index++)
355 pos2[index].set(SkIntToScalar((unsigned int)index * 10),
tomhudson@google.comffe39bd2012-05-17 15:38:00 +0000356 SkIntToScalar(20));
rmistry@google.comae933ce2012-08-23 18:19:56 +0000357
reed@android.com8a1c16f2008-12-17 15:59:43 +0000358 // shaders
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000359 SkPoint linearPoints[] = { { 0, 0, }, { SkIntToScalar(40), SkIntToScalar(40) } };
reed@android.com8a1c16f2008-12-17 15:59:43 +0000360 SkColor linearColors[] = { SK_ColorRED, SK_ColorBLUE };
halcanary96fcdcc2015-08-27 07:41:13 -0700361 SkScalar* linearPos = nullptr;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000362 int linearCount = 2;
363 SkShader::TileMode linearMode = SkShader::kMirror_TileMode;
reed8a21c9f2016-03-08 18:50:00 -0800364 auto linear = SkGradientShader::MakeLinear(linearPoints,
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +0000365 linearColors, linearPos, linearCount, linearMode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000366
367 SkPoint radialCenter = { SkIntToScalar(25), SkIntToScalar(25) };
368 SkScalar radialRadius = SkIntToScalar(25);
369 SkColor radialColors[] = { SK_ColorGREEN, SK_ColorGRAY, SK_ColorRED };
370 SkScalar radialPos[] = { 0, SkIntToScalar(3) / 5, SkIntToScalar(1)};
371 int radialCount = 3;
372 SkShader::TileMode radialMode = SkShader::kRepeat_TileMode;
reed8a21c9f2016-03-08 18:50:00 -0800373 auto radial = SkGradientShader::MakeRadial(radialCenter,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000374 radialRadius, radialColors, radialPos, radialCount,
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +0000375 radialMode);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000376
reed@android.com8a1c16f2008-12-17 15:59:43 +0000377 SkEmbossMaskFilter::Light light;
378 light.fDirection[0] = SK_Scalar1/2;
379 light.fDirection[1] = SK_Scalar1/2;
380 light.fDirection[2] = SK_Scalar1/3;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000381 light.fAmbient = 0x48;
382 light.fSpecular = 0x80;
robertphillips@google.comb7061172013-09-06 14:16:12 +0000383 SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(12)/5);
reed5e1ddb12015-12-21 08:52:45 -0800384 SkMaskFilter* embossFilter = SkEmbossMaskFilter::Create(sigma, light);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000385
reed@android.com048522d2009-06-23 12:19:41 +0000386 SkXfermode* xfermode = SkXfermode::Create(SkXfermode::kXor_Mode);
reed0daf5dd2016-01-11 12:34:04 -0800387 SkColorFilter* lightingFilter = SkColorMatrixFilter::CreateLightingFilter(
reed@android.com8a1c16f2008-12-17 15:59:43 +0000388 0xff89bc45, 0xff112233);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000389
reed@android.com8a1c16f2008-12-17 15:59:43 +0000390 canvas->save();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000391 canvas->translate(SkIntToScalar(0), SkIntToScalar(5));
reed@google.com9cfc83c2013-07-22 17:18:18 +0000392 paint.setAntiAlias(true);
reed93a12152015-03-16 10:08:34 -0700393 paint.setFilterQuality(kLow_SkFilterQuality);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000394 // !!! draw through a clip
395 paint.setColor(SK_ColorLTGRAY);
396 paint.setStyle(SkPaint::kFill_Style);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000397 SkRect clip = {0, 0, SkIntToScalar(320), SkIntToScalar(120)};
398 canvas->clipRect(clip);
reed8a21c9f2016-03-08 18:50:00 -0800399 paint.setShader(SkShader::MakeBitmapShader(fTx,
400 SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode));
rmistry@google.comae933ce2012-08-23 18:19:56 +0000401 canvas->drawPaint(paint);
402 canvas->save();
403
reed@android.com8a1c16f2008-12-17 15:59:43 +0000404 // line (exercises xfermode, colorShader, colorFilter, filterShader)
rmistry@google.comae933ce2012-08-23 18:19:56 +0000405 paint.setColor(SK_ColorGREEN);
406 paint.setStrokeWidth(SkIntToScalar(10));
407 paint.setStyle(SkPaint::kStroke_Style);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000408 paint.setXfermode(xfermode)->unref();
409 paint.setColorFilter(lightingFilter)->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000410 canvas->drawLine(start.fX, start.fY, stop.fX, stop.fY, paint); // should not be green
halcanary96fcdcc2015-08-27 07:41:13 -0700411 paint.setXfermode(nullptr);
412 paint.setColorFilter(nullptr);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000413
reed@android.com8a1c16f2008-12-17 15:59:43 +0000414 // rectangle
rmistry@google.comae933ce2012-08-23 18:19:56 +0000415 paint.setStyle(SkPaint::kFill_Style);
416 canvas->translate(SkIntToScalar(50), 0);
417 paint.setColor(SK_ColorYELLOW);
reed8a21c9f2016-03-08 18:50:00 -0800418 paint.setShader(linear);
reeda4393342016-03-18 11:22:57 -0700419 paint.setPathEffect(pathEffectTest());
rmistry@google.comae933ce2012-08-23 18:19:56 +0000420 canvas->drawRect(rect, paint);
halcanary96fcdcc2015-08-27 07:41:13 -0700421 paint.setPathEffect(nullptr);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000422
reed@android.com8a1c16f2008-12-17 15:59:43 +0000423 // circle w/ emboss & transparent (exercises 3dshader)
rmistry@google.comae933ce2012-08-23 18:19:56 +0000424 canvas->translate(SkIntToScalar(50), 0);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000425 paint.setMaskFilter(embossFilter)->unref();
426 canvas->drawOval(rect, paint);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000427 canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
reed56263c72015-06-05 11:31:26 -0700428// paint.setShader(transparentShader)->unref();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000429 canvas->drawOval(rect, paint);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000430 canvas->translate(0, SkIntToScalar(-10));
431
reed@android.com8a1c16f2008-12-17 15:59:43 +0000432 // path
rmistry@google.comae933ce2012-08-23 18:19:56 +0000433 canvas->translate(SkIntToScalar(50), 0);
434 paint.setColor(SK_ColorRED);
435 paint.setStyle(SkPaint::kStroke_Style);
436 paint.setStrokeWidth(SkIntToScalar(5));
reed8a21c9f2016-03-08 18:50:00 -0800437 paint.setShader(radial);
halcanary96fcdcc2015-08-27 07:41:13 -0700438 paint.setMaskFilter(nullptr);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000439 canvas->drawPath(path, paint);
440
halcanary96fcdcc2015-08-27 07:41:13 -0700441 paint.setShader(nullptr);
reed6f45c172015-11-04 08:34:07 -0800442 // bitmap
rmistry@google.comae933ce2012-08-23 18:19:56 +0000443 canvas->translate(SkIntToScalar(50), 0);
444 paint.setStyle(SkPaint::kFill_Style);
445 canvas->drawBitmap(fBug, left, top, &paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000446
rmistry@google.comae933ce2012-08-23 18:19:56 +0000447 canvas->translate(-SkIntToScalar(30), SkIntToScalar(30));
reed8a21c9f2016-03-08 18:50:00 -0800448 paint.setShader(shaderTest()); // test compose shader
rmistry@google.comae933ce2012-08-23 18:19:56 +0000449 canvas->drawRect(rect2, paint);
halcanary96fcdcc2015-08-27 07:41:13 -0700450 paint.setShader(nullptr);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000451
reed@android.com8a1c16f2008-12-17 15:59:43 +0000452 canvas->restore();
453 // text
reed@android.com8a1c16f2008-12-17 15:59:43 +0000454 canvas->translate(0, SkIntToScalar(60));
rmistry@google.comae933ce2012-08-23 18:19:56 +0000455 canvas->save();
456 paint.setColor(SK_ColorGRAY);
457 canvas->drawPosText(ascii, asciiLength, pos.begin(), paint);
458 canvas->drawPosText(ascii, asciiLength, pos2.begin(), paint);
459
460 canvas->translate(SkIntToScalar(50), 0);
461 paint.setColor(SK_ColorCYAN);
462 canvas->drawText(utf8, sizeof(utf8) - 1, x, y, paint);
463
464 canvas->translate(SkIntToScalar(30), 0);
465 paint.setColor(SK_ColorMAGENTA);
466 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
467 matrix.setTranslate(SkIntToScalar(10), SkIntToScalar(10));
468 canvas->drawTextOnPath((void*) utf16, sizeof(utf16), path, &matrix, paint);
469 canvas->translate(0, SkIntToScalar(20));
470 canvas->drawTextOnPath((void*) utf16simple, sizeof(utf16simple), path, &matrix, paint);
471 canvas->restore();
472
473 canvas->translate(0, SkIntToScalar(60));
474 paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000475 canvas->restore();
476 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000477
reed@google.com4d5c26d2013-01-08 16:17:50 +0000478 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000479 fClickPt.set(x, y);
halcanary96fcdcc2015-08-27 07:41:13 -0700480 this->inval(nullptr);
reed@google.com4d5c26d2013-01-08 16:17:50 +0000481 return this->INHERITED::onFindClickHandler(x, y, modi);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000482 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000483
reeda4393342016-03-18 11:22:57 -0700484 sk_sp<SkPathEffect> pathEffectTest() {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000485 static const int gXY[] = { 1, 0, 0, -1, 2, -1, 3, 0, 2, 1, 0, 1 };
486 SkScalar gPhase = 0;
487 SkPath path;
488 path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
489 for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
490 path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
491 path.close();
492 path.offset(SkIntToScalar(-6), 0);
reeda4393342016-03-18 11:22:57 -0700493 auto outer = SkPath1DPathEffect::Make(path, SkIntToScalar(12),
reed@android.com8a1c16f2008-12-17 15:59:43 +0000494 gPhase, SkPath1DPathEffect::kRotate_Style);
reeda4393342016-03-18 11:22:57 -0700495 auto inner = SkDiscretePathEffect::Make(SkIntToScalar(2),
reed@android.com8a1c16f2008-12-17 15:59:43 +0000496 SkIntToScalar(1)/10); // SkCornerPathEffect(SkIntToScalar(2));
reeda4393342016-03-18 11:22:57 -0700497 return SkComposePathEffect::Make(outer, inner);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000498 }
reed@google.com963a8fa2012-05-10 13:04:59 +0000499
reed8a21c9f2016-03-08 18:50:00 -0800500 sk_sp<SkShader> shaderTest() {
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000501 SkPoint pts[] = { { 0, 0, }, { SkIntToScalar(100), 0 } };
reed@android.com8a1c16f2008-12-17 15:59:43 +0000502 SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
reed8a21c9f2016-03-08 18:50:00 -0800503 auto shaderA = SkGradientShader::MakeLinear(pts, colors, nullptr,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000504 2, SkShader::kClamp_TileMode);
505 pts[1].set(0, SkIntToScalar(100));
506 SkColor colors2[] = {SK_ColorBLACK, SkColorSetARGB(0x80, 0, 0, 0)};
reed8a21c9f2016-03-08 18:50:00 -0800507 auto shaderB = SkGradientShader::MakeLinear(pts, colors2, nullptr,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000508 2, SkShader::kClamp_TileMode);
reed8a21c9f2016-03-08 18:50:00 -0800509 SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(SkXfermode::kDstIn_Mode));
510 return SkShader::MakeComposeShader(shaderA, shaderB, mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000511 }
512
513 virtual void startTest() {
rmistry@google.comae933ce2012-08-23 18:19:56 +0000514 SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/bugcirc.gif", &fBug);
515 SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/tbcirc.gif", &fTb);
516 SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/05psp04.gif", &fTx);
517 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000518
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000519 void drawRaster(SkCanvas* canvas) {
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000520 for (size_t index = 0; index < SK_ARRAY_COUNT(gRastProcs); index++)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000521 drawOneRaster(canvas);
522 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000523
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000524 void drawOneRaster(SkCanvas* canvas) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000525 canvas->save();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000526
527 SkScalar x = SkIntToScalar(20);
528 SkScalar y = SkIntToScalar(40);
529 SkPaint paint;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000530
reed@android.com8a1c16f2008-12-17 15:59:43 +0000531 paint.setAntiAlias(true);
532 paint.setTextSize(SkIntToScalar(48));
reed@android.comaa5a7db2009-05-27 01:20:10 +0000533 paint.setTypeface(SkTypeface::CreateFromName("sans-serif",
534 SkTypeface::kBold));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000535
536 SkString str("GOOGLE");
537
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000538 for (size_t i = 0; i < SK_ARRAY_COUNT(gRastProcs); i++) {
reed@google.com7fa2a652014-01-27 13:42:58 +0000539 apply_shader(&paint, (int)i);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000540
halcanary96fcdcc2015-08-27 07:41:13 -0700541 // paint.setMaskFilter(nullptr);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000542 // paint.setColor(SK_ColorBLACK);
543
544#if 01
545 int index = i % SK_ARRAY_COUNT(gLightingColors);
reed0daf5dd2016-01-11 12:34:04 -0800546 paint.setColorFilter(SkColorMatrixFilter::CreateLightingFilter(
reed@android.com8a1c16f2008-12-17 15:59:43 +0000547 gLightingColors[index].fMul,
548 gLightingColors[index].fAdd))->unref();
549#endif
rmistry@google.comae933ce2012-08-23 18:19:56 +0000550
reed@android.com8a1c16f2008-12-17 15:59:43 +0000551 canvas->drawText(str.c_str(), str.size(), x, y, paint);
552 SkRect oval = { x, y - SkIntToScalar(40), x + SkIntToScalar(40), y };
553 paint.setStyle(SkPaint::kStroke_Style);
554 canvas->drawOval(oval, paint);
555 paint.setStyle(SkPaint::kFill_Style);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000556
557 y += paint.getFontSpacing();
558 }
559
560 canvas->restore();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000561 }
562
563private:
564 SkPoint fClickPt;
565 SkBitmap fBug, fTb, fTx;
mike@reedtribe.org5fd92432011-05-05 01:59:48 +0000566 typedef SampleView INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000567};
568
569//////////////////////////////////////////////////////////////////////////////
570
571static SkView* MyFactory() { return new DemoView; }
572static SkViewRegister reg(MyFactory);