1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SampleCode.h"
8b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com#include "SkBlurMask.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkView.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "Sk1DPathEffect.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "Sk2DPathEffect.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlurMaskFilter.h"
140daf5dd7fc682c939325e16cac6f8aa2e1295060reed#include "SkColorMatrixFilter.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h"
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCornerPathEffect.h"
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDashPathEffect.h"
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDiscretePathEffect.h"
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkEmbossMaskFilter.h"
208b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h"
218b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h"
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGradientShader.h"
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMath.h"
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPath.h"
25770963f23f4fc313db0fa3bac18b1b8aafb55f17robertphillips@google.com#include "SkPictureRecorder.h"
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRegion.h"
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h"
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCornerPathEffect.h"
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPathMeasure.h"
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h"
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRandom.h"
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypeface.h"
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h"
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include <math.h>
36d15750c0c7766ecab7022ea9b2f9e89a9132cbc2msarett#include "DecodeFile.h"
37ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Dot2DPathEffect : public Sk2DPathEffect {
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix)
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : Sk2DPathEffect(matrix), fRadius(radius) {}
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
43ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Dot2DPathEffect)
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
4636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void next(const SkPoint& loc, int u, int v, SkPath* dst) const override {
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        dst->addCircle(loc.fX, loc.fY, fRadius);
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
49ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
5036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void flatten(SkWriteBuffer& buffer) const override {
5154924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com        this->INHERITED::flatten(buffer);
5254924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com        buffer.writeScalar(fRadius);
5354924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com    }
5454924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar fRadius;
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef Sk2DPathEffect INHERITED;
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
615fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.orgclass DemoView : public SampleView {
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
632f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com    DemoView() {}
64ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // overrides from SkEventSink
675fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org    virtual bool onQuery(SkEvent* evt) {
685fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org        if (SampleCode::TitleQ(*evt)) {
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SampleCode::TitleR(evt, "Demo");
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return this->INHERITED::onQuery(evt);
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
74ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
755fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org    virtual bool onClick(Click* click) {
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return this->INHERITED::onClick(click);
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
78ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
795fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org    void makePath(SkPath& path) {
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        path.addCircle(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(20),
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkPath::kCCW_Direction);
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (int index = 0; index < 10; index++) {
834b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org            SkScalar x = (float) cos(index / 10.0f * 2 * 3.1415925358f);
844b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org            SkScalar y = (float) sin(index / 10.0f * 2 * 3.1415925358f);
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            x *= index & 1 ? 7 : 14;
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            y *= index & 1 ? 7 : 14;
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            x += SkIntToScalar(20);
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            y += SkIntToScalar(20);
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (index == 0)
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                path.moveTo(x, y);
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            else
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                path.lineTo(x, y);
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        path.close();
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
96ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
975fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org    virtual void onDrawContent(SkCanvas* canvas) {
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->save();
9984b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com        this->drawPicture(canvas, 0);
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->restore();
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        {
10384b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com            SkPictureRecorder recorder;
10484b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com            {
10596fcdcc219d2a0d3579719b84b28bede76efba64halcanary                SkCanvas* record = recorder.beginRecording(320, 480, nullptr, 0);
10684b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                this->drawPicture(record, 120);
10784b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com            }
108ca2622ba051829fed5f30facd74c5b41cd4b931creed            sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
10984b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            canvas->translate(0, SkIntToScalar(120));
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkRect clip;
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            clip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            do {
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                canvas->save();
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                canvas->clipRect(clip);
117c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips                picture->playback(canvas);
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                canvas->restore();
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                if (clip.fRight < SkIntToScalar(320))
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    clip.offset(SkIntToScalar(160), 0);
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                else if (clip.fBottom < SkIntToScalar(480))
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    clip.offset(-SkIntToScalar(320), SkIntToScalar(160));
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                else
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    break;
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } while (true);
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
128ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1295fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org    void drawPicture(SkCanvas* canvas, int spriteOffset) {
130ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        SkMatrix matrix; matrix.reset();
131ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        SkPaint paint;
132ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        SkPath path;
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPoint start = {0, 0};
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPoint stop = { SkIntToScalar(40), SkIntToScalar(40) };
135ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        SkRect rect = {0, 0, SkIntToScalar(40), SkIntToScalar(40) };
136ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        SkRect rect2 = {0, 0, SkIntToScalar(65), SkIntToScalar(20) };
137ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        SkScalar left = 0, top = 0, x = 0, y = 0;
1387fa2a65c0cfc714364490cb715171461143024e0reed@google.com        int index;
139ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
140ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        char ascii[] = "ascii...";
1417fa2a65c0cfc714364490cb715171461143024e0reed@google.com        int asciiLength = sizeof(ascii) - 1;
142ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        char utf8[] = "utf8" "\xe2\x80\xa6";
143ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        short utf16[] = {'u', 't', 'f', '1', '6', 0x2026 };
144ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        short utf16simple[] = {'u', 't', 'f', '1', '6', '!' };
145ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        makePath(path);
1471a1d2411e879cffb74994f1978f58d503435c874Ben Wagner        SkTDArray<SkPoint> pos;
148ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        pos.setCount(asciiLength);
149ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        for (index = 0;  index < asciiLength; index++)
150ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com            pos[index].set(SkIntToScalar((unsigned int)index * 10),
151ffe39bd3b66eb5090684959e7f2409346ab72d93tomhudson@google.com                                       SkIntToScalar((unsigned int)index * 2));
1521a1d2411e879cffb74994f1978f58d503435c874Ben Wagner        SkTDArray<SkPoint> pos2;
153ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        pos2.setCount(asciiLength);
154ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        for (index = 0;  index < asciiLength; index++)
155ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com            pos2[index].set(SkIntToScalar((unsigned int)index * 10),
156ffe39bd3b66eb5090684959e7f2409346ab72d93tomhudson@google.com                                        SkIntToScalar(20));
157ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // shaders
15964cc579efa7e416c7298ed159d76b074b283c0f9senorblanco@chromium.org        SkPoint linearPoints[] = { { 0, 0, }, { SkIntToScalar(40), SkIntToScalar(40) } };
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkColor linearColors[] = { SK_ColorRED, SK_ColorBLUE };
16196fcdcc219d2a0d3579719b84b28bede76efba64halcanary        SkScalar* linearPos = nullptr;
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int linearCount = 2;
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkShader::TileMode linearMode = SkShader::kMirror_TileMode;
1648a21c9fe7f5fef9e87115defef27bd7218419f28reed        auto linear = SkGradientShader::MakeLinear(linearPoints,
16583f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org            linearColors, linearPos, linearCount, linearMode);
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPoint radialCenter = { SkIntToScalar(25), SkIntToScalar(25) };
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScalar radialRadius = SkIntToScalar(25);
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkColor radialColors[] = { SK_ColorGREEN, SK_ColorGRAY, SK_ColorRED };
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScalar radialPos[] = { 0, SkIntToScalar(3) / 5, SkIntToScalar(1)};
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int radialCount = 3;
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkShader::TileMode radialMode = SkShader::kRepeat_TileMode;
1738a21c9fe7f5fef9e87115defef27bd7218419f28reed        auto radial = SkGradientShader::MakeRadial(radialCenter,
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            radialRadius, radialColors, radialPos, radialCount,
17583f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org            radialMode);
176ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkEmbossMaskFilter::Light light;
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        light.fDirection[0] = SK_Scalar1/2;
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        light.fDirection[1] = SK_Scalar1/2;
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        light.fDirection[2] = SK_Scalar1/3;
181ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        light.fAmbient        = 0x48;
182ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        light.fSpecular        = 0x80;
183ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
184d053ce9c54d4e5937a142278359e5a4cde18095ereed        auto lightingFilter = SkColorMatrixFilter::MakeLightingFilter(
1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            0xff89bc45, 0xff112233);
186ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->save();
188ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->translate(SkIntToScalar(0), SkIntToScalar(5));
1899cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        paint.setAntiAlias(true);
19093a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        paint.setFilterQuality(kLow_SkFilterQuality);
191ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        // !!! draw through a clip
192ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setColor(SK_ColorLTGRAY);
193ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setStyle(SkPaint::kFill_Style);
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkRect clip = {0, 0, SkIntToScalar(320), SkIntToScalar(120)};
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->clipRect(clip);
1968a21c9fe7f5fef9e87115defef27bd7218419f28reed        paint.setShader(SkShader::MakeBitmapShader(fTx,
1978a21c9fe7f5fef9e87115defef27bd7218419f28reed            SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode));
198ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->drawPaint(paint);
199ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->save();
200ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // line (exercises xfermode, colorShader, colorFilter, filterShader)
202ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setColor(SK_ColorGREEN);
203ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setStrokeWidth(SkIntToScalar(10));
204ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setStyle(SkPaint::kStroke_Style);
205374772bd61951f01bf84fe17bf53d8867681c9aereed        paint.setBlendMode(SkBlendMode::kXor);
206d053ce9c54d4e5937a142278359e5a4cde18095ereed        paint.setColorFilter(lightingFilter);
20723e474cb7331c5d2389d97dce2d9e5c93c58f39fHal Canary        canvas->drawLine(start, stop, paint); // should not be green
208374772bd61951f01bf84fe17bf53d8867681c9aereed        paint.setBlendMode(SkBlendMode::kSrcOver);
20996fcdcc219d2a0d3579719b84b28bede76efba64halcanary        paint.setColorFilter(nullptr);
210ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // rectangle
212ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setStyle(SkPaint::kFill_Style);
213ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->translate(SkIntToScalar(50), 0);
214ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setColor(SK_ColorYELLOW);
2158a21c9fe7f5fef9e87115defef27bd7218419f28reed        paint.setShader(linear);
216a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed        paint.setPathEffect(pathEffectTest());
217ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->drawRect(rect, paint);
21896fcdcc219d2a0d3579719b84b28bede76efba64halcanary        paint.setPathEffect(nullptr);
219ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // circle w/ emboss & transparent (exercises 3dshader)
221ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->translate(SkIntToScalar(50), 0);
222efdfd51b68a300d5c6e28743fe0344ca05d1cec9reed        paint.setMaskFilter(SkEmbossMaskFilter::Make(
223efdfd51b68a300d5c6e28743fe0344ca05d1cec9reed                                     SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(12)/5), light));
2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawOval(rect, paint);
225ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
22656263c78d86cb536d463b8d46f00ac44cad3defbreed//        paint.setShader(transparentShader)->unref();
2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawOval(rect, paint);
228ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->translate(0, SkIntToScalar(-10));
229ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // path
231ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->translate(SkIntToScalar(50), 0);
232ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setColor(SK_ColorRED);
233ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setStyle(SkPaint::kStroke_Style);
234ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setStrokeWidth(SkIntToScalar(5));
2358a21c9fe7f5fef9e87115defef27bd7218419f28reed        paint.setShader(radial);
23696fcdcc219d2a0d3579719b84b28bede76efba64halcanary        paint.setMaskFilter(nullptr);
237ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->drawPath(path, paint);
238ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
23996fcdcc219d2a0d3579719b84b28bede76efba64halcanary        paint.setShader(nullptr);
2406f45c1714786a54adec156f2416a14aa142adf05reed        // bitmap
241ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->translate(SkIntToScalar(50), 0);
242ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setStyle(SkPaint::kFill_Style);
243ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->drawBitmap(fBug, left, top, &paint);
2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
245ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->translate(-SkIntToScalar(30), SkIntToScalar(30));
2468a21c9fe7f5fef9e87115defef27bd7218419f28reed        paint.setShader(shaderTest()); // test compose shader
247ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->drawRect(rect2, paint);
24896fcdcc219d2a0d3579719b84b28bede76efba64halcanary        paint.setShader(nullptr);
249ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->restore();
2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // text
252ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->translate(0, SkIntToScalar(60));
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->save();
254ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setColor(SK_ColorGRAY);
255ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->drawPosText(ascii, asciiLength, pos.begin(), paint);
256ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->drawPosText(ascii, asciiLength, pos2.begin(), paint);
257ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
258ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->translate(SkIntToScalar(50), 0);
259ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setColor(SK_ColorCYAN);
260ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->drawText(utf8, sizeof(utf8) - 1, x, y, paint);
261ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
262ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->translate(SkIntToScalar(30), 0);
263ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setColor(SK_ColorMAGENTA);
264ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        matrix.setTranslate(SkIntToScalar(10), SkIntToScalar(10));
266ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->drawTextOnPath((void*) utf16, sizeof(utf16), path, &matrix, paint);
267ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->translate(0, SkIntToScalar(20));
268ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        canvas->drawTextOnPath((void*) utf16simple, sizeof(utf16simple), path, &matrix, paint);
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->restore();
270ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->translate(0, SkIntToScalar(60));
272ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com        paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->restore();
2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
275ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
2764d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fClickPt.set(x, y);
2784d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        return this->INHERITED::onFindClickHandler(x, y, modi);
2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
280ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
281a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed    sk_sp<SkPathEffect> pathEffectTest() {
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        static const int gXY[] = { 1, 0, 0, -1, 2, -1, 3, 0, 2, 1, 0, 1 };
2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScalar gPhase = 0;
2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPath path;
2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        path.close();
2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        path.offset(SkIntToScalar(-6), 0);
290a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed        auto outer = SkPath1DPathEffect::Make(path, SkIntToScalar(12),
2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            gPhase, SkPath1DPathEffect::kRotate_Style);
292a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed        auto inner = SkDiscretePathEffect::Make(SkIntToScalar(2),
2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkIntToScalar(1)/10); // SkCornerPathEffect(SkIntToScalar(2));
294a07741a75aa694c0e7c00c2301c9de2daf9b5f9eMike Reed        return SkPathEffect::MakeCompose(outer, inner);
2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
296963a8fa542134f3ddbd40165e1b3f9edf9f074ddreed@google.com
2978a21c9fe7f5fef9e87115defef27bd7218419f28reed    sk_sp<SkShader> shaderTest() {
29864cc579efa7e416c7298ed159d76b074b283c0f9senorblanco@chromium.org        SkPoint pts[] = { { 0, 0, }, { SkIntToScalar(100), 0 } };
2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
3008a21c9fe7f5fef9e87115defef27bd7218419f28reed        auto shaderA = SkGradientShader::MakeLinear(pts, colors, nullptr,
3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            2, SkShader::kClamp_TileMode);
3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        pts[1].set(0, SkIntToScalar(100));
3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkColor colors2[] = {SK_ColorBLACK,  SkColorSetARGB(0x80, 0, 0, 0)};
3048a21c9fe7f5fef9e87115defef27bd7218419f28reed        auto shaderB = SkGradientShader::MakeLinear(pts, colors2, nullptr,
3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            2, SkShader::kClamp_TileMode);
306cfb6bdf767796c950f89985445738d2d8e7f12b0reed        return SkShader::MakeComposeShader(std::move(shaderA), std::move(shaderB),
3077d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed                                           SkBlendMode::kDstIn);
3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void startTest() {
311d15750c0c7766ecab7022ea9b2f9e89a9132cbc2msarett        decode_file("/Users/caryclark/Desktop/bugcirc.gif", &fBug);
312d15750c0c7766ecab7022ea9b2f9e89a9132cbc2msarett        decode_file("/Users/caryclark/Desktop/tbcirc.gif", &fTb);
313d15750c0c7766ecab7022ea9b2f9e89a9132cbc2msarett        decode_file("/Users/caryclark/Desktop/05psp04.gif", &fTx);
314ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com    }
3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint fClickPt;
3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap fBug, fTb, fTx;
3195fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org    typedef SampleView INHERITED;
3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////
3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkView* MyFactory() { return new DemoView; }
3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkViewRegister reg(MyFactory);
326