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 */
776113a9b7716748c70ea0ecf7aacbabe4cce5009reed
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SampleCode.h"
976113a9b7716748c70ea0ecf7aacbabe4cce5009reed#include "SkAnimTimer.h"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkView.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGradientShader.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPath.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRegion.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h"
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h"
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "Sk1DPathEffect.h"
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCornerPathEffect.h"
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPathMeasure.h"
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRandom.h"
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h"
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define CORNER_RADIUS   12
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const int gXY[] = {
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    4, 0, 0, -4, 8, -4, 12, 0, 8, 4, 0, 4
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
29a439334b6e758d38501e225e2e5d0ab73e2fb6ebreedstatic sk_sp<SkPathEffect> make_pe(int flags, SkScalar phase) {
30a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed    if (flags == 1) {
31a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed        return SkCornerPathEffect::Make(SkIntToScalar(CORNER_RADIUS));
32a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed    }
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath  path;
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    path.close();
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    path.offset(SkIntToScalar(-6), 0);
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
41a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed    auto outer = SkPath1DPathEffect::Make(path, 12, phase, SkPath1DPathEffect::kRotate_Style);
42ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (flags == 2)
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return outer;
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
46a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed    auto inner = SkCornerPathEffect::Make(SkIntToScalar(CORNER_RADIUS));
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
48a07741a75aa694c0e7c00c2301c9de2daf9b5f9eMike Reed    return SkPathEffect::MakeCompose(outer, inner);
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
51a439334b6e758d38501e225e2e5d0ab73e2fb6ebreedstatic sk_sp<SkPathEffect> make_warp_pe(SkScalar phase) {
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath  path;
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
54a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed    for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2) {
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
56a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed    }
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    path.close();
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    path.offset(SkIntToScalar(-6), 0);
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
60a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed    auto outer = SkPath1DPathEffect::Make(
61d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed        path, 12, phase, SkPath1DPathEffect::kMorph_Style);
62a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed    auto inner = SkCornerPathEffect::Make(SkIntToScalar(CORNER_RADIUS));
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
64a07741a75aa694c0e7c00c2301c9de2daf9b5f9eMike Reed    return SkPathEffect::MakeCompose(outer, inner);
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorFilter.h"
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
71e5ff43906603dff33e14086cf1e5d73c157d2e8ereed@google.comclass PathEffectView : public SampleView {
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath  fPath;
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint fClickPt;
74d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed    SkScalar fPhase;
75d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
77d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed    PathEffectView() : fPhase(0) {
7863c684a8a609d39da11b4a656223cebf52ca85dccaryclark        }
7963c684a8a609d39da11b4a656223cebf52ca85dccaryclark
8063c684a8a609d39da11b4a656223cebf52ca85dccaryclarkprotected:
8136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onOnceBeforeDraw() override {
82e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom    rand;
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int         steps = 20;
8492a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com        SkScalar    dist = SkIntToScalar(400);
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScalar    x = SkIntToScalar(20);
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScalar    y = SkIntToScalar(50);
87ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPath.moveTo(x, y);
89f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        for (int i = 0; i < steps; i++) {
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            x += dist/steps;
9192a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            SkScalar tmpY = y + SkIntToScalar(rand.nextS() % 25);
9292a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            if (i == steps/2) {
9392a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com                fPath.moveTo(x, tmpY);
9492a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            } else {
9592a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com                fPath.lineTo(x, tmpY);
9692a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            }
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
9992a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com        {
10092a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            SkRect  oval;
10192a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            oval.set(SkIntToScalar(20), SkIntToScalar(30),
10292a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com                     SkIntToScalar(100), SkIntToScalar(60));
10392a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            oval.offset(x, 0);
10492a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            fPath.addRoundRect(oval, SkIntToScalar(8), SkIntToScalar(8));
10592a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com        }
106ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fClickPt.set(SkIntToScalar(200), SkIntToScalar(200));
108ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
109e5ff43906603dff33e14086cf1e5d73c157d2e8ereed@google.com        this->setBGColor(0xFFDDDDDD);
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
111ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
11236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onQuery(SkEvent* evt) override {
113f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (SampleCode::TitleQ(*evt)) {
114f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            SampleCode::TitleR(evt, "PathEffects");
115f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            return true;
116f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
117f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return this->INHERITED::onQuery(evt);
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
119ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
12036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onDrawContent(SkCanvas* canvas) override {
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPaint paint;
122ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
123d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed        canvas->translate(0, 50);
124ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setColor(SK_ColorBLUE);
126a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed        paint.setPathEffect(make_pe(2, fPhase));
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawPath(fPath, paint);
128ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
129d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed        canvas->translate(0, 50);
130ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setARGB(0xFF, 0, 0xBB, 0);
132a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed        paint.setPathEffect(make_pe(3, fPhase));
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawPath(fPath, paint);
134ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
135d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed        canvas->translate(0, 50);
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setARGB(0xFF, 0, 0, 0);
138a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed        paint.setPathEffect(make_warp_pe(fPhase));
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawPath(fPath, paint);
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
141ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
14236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onAnimate(const SkAnimTimer& timer) override {
14376113a9b7716748c70ea0ecf7aacbabe4cce5009reed        fPhase = timer.scaled(40);
144d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed        return true;
145d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed    }
146d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
148e5ff43906603dff33e14086cf1e5d73c157d2e8ereed@google.com    typedef SampleView INHERITED;
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkView* MyFactory() { return new PathEffectView; }
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkViewRegister reg(MyFactory);
155