SamplePathEffects.cpp revision e5ff43906603dff33e14086cf1e5d73c157d2e8e
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SampleCode.h"
28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkView.h"
38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGradientShader.h"
58a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPath.h"
68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRegion.h"
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h"
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "Sk1DPathEffect.h"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCornerPathEffect.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPathMeasure.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRandom.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPixelXorXfermode.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define CORNER_RADIUS   12
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkScalar gPhase;
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const int gXY[] = {
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    4, 0, 0, -4, 8, -4, 12, 0, 8, 4, 0, 4
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
23f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic SkPathEffect* make_pe(int flags) {
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (flags == 1)
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return new SkCornerPathEffect(SkIntToScalar(CORNER_RADIUS));
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath  path;
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    path.close();
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    path.offset(SkIntToScalar(-6), 0);
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPathEffect* outer = new SkPath1DPathEffect(path, SkIntToScalar(12), gPhase, SkPath1DPathEffect::kRotate_Style);
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (flags == 2)
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return outer;
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPathEffect* inner = new SkCornerPathEffect(SkIntToScalar(CORNER_RADIUS));
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPathEffect* pe = new SkComposePathEffect(outer, inner);
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    outer->unref();
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    inner->unref();
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return pe;
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
47f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic SkPathEffect* make_warp_pe() {
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath  path;
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    path.close();
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    path.offset(SkIntToScalar(-6), 0);
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPathEffect* outer = new SkPath1DPathEffect(path, SkIntToScalar(12), gPhase, SkPath1DPathEffect::kMorph_Style);
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPathEffect* inner = new SkCornerPathEffect(SkIntToScalar(CORNER_RADIUS));
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPathEffect* pe = new SkComposePathEffect(outer, inner);
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    outer->unref();
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    inner->unref();
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return pe;
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorFilter.h"
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkLayerRasterizer.h"
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass testrast : public SkLayerRasterizer {
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
71f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    testrast() {
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPaint paint;
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setAntiAlias(true);
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setStyle(SkPaint::kStroke_Style);
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setStrokeWidth(SK_Scalar1*4);
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->addLayer(paint);
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setStrokeWidth(SK_Scalar1*1);
81048522dd2aa45d1b4bf52944527f877b30ea45fdreed@android.com        paint.setXfermode(SkXfermode::kClear_Mode);
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->addLayer(paint);
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setAlpha(0x66);
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->addLayer(paint, SkIntToScalar(4), SkIntToScalar(4));
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setAlpha(0xFF);
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->addLayer(paint);
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
93e5ff43906603dff33e14086cf1e5d73c157d2e8ereed@google.comclass PathEffectView : public SampleView {
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath  fPath;
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint fClickPt;
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
97f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com	PathEffectView() {
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkRandom    rand;
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int         steps = 20;
10092a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com        SkScalar    dist = SkIntToScalar(400);
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScalar    x = SkIntToScalar(20);
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScalar    y = SkIntToScalar(50);
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPath.moveTo(x, y);
105f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        for (int i = 0; i < steps; i++) {
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            x += dist/steps;
10792a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            SkScalar tmpY = y + SkIntToScalar(rand.nextS() % 25);
10892a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            if (i == steps/2) {
10992a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com                fPath.moveTo(x, tmpY);
11092a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            } else {
11192a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com                fPath.lineTo(x, tmpY);
11292a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            }
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
11592a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com        {
11692a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            SkRect  oval;
11792a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            oval.set(SkIntToScalar(20), SkIntToScalar(30),
11892a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com                     SkIntToScalar(100), SkIntToScalar(60));
11992a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            oval.offset(x, 0);
12092a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com            fPath.addRoundRect(oval, SkIntToScalar(8), SkIntToScalar(8));
12192a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com        }
12292a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fClickPt.set(SkIntToScalar(200), SkIntToScalar(200));
124e5ff43906603dff33e14086cf1e5d73c157d2e8ereed@google.com
125e5ff43906603dff33e14086cf1e5d73c157d2e8ereed@google.com        this->setBGColor(0xFFDDDDDD);
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // overrides from SkEventSink
130f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    virtual bool onQuery(SkEvent* evt) {
131f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (SampleCode::TitleQ(*evt)) {
132f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            SampleCode::TitleR(evt, "PathEffects");
133f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            return true;
134f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
135f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return this->INHERITED::onQuery(evt);
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
138e5ff43906603dff33e14086cf1e5d73c157d2e8ereed@google.com    virtual void onDrawContent(SkCanvas* canvas) {
139f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        gPhase -= SampleCode::GetAnimSecondsDelta() * 40;
140671cd656785de5e84564b6ffe4831625d7016dedreed@android.com        this->inval(NULL);
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPaint paint;
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
144f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#if 0
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setAntiAlias(true);
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setStyle(SkPaint::kStroke_Style);
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setStrokeWidth(SkIntToScalar(5));
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawPath(fPath, paint);
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setStrokeWidth(0);
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
15192a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com        paint.setColor(SK_ColorWHITE);
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setPathEffect(make_pe(1))->unref();
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawPath(fPath, paint);
154f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#endif
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->translate(0, SkIntToScalar(50));
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setColor(SK_ColorBLUE);
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setPathEffect(make_pe(2))->unref();
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawPath(fPath, paint);
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->translate(0, SkIntToScalar(50));
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setARGB(0xFF, 0, 0xBB, 0);
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setPathEffect(make_pe(3))->unref();
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawPath(fPath, paint);
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->translate(0, SkIntToScalar(50));
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setARGB(0xFF, 0, 0, 0);
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setPathEffect(make_warp_pe())->unref();
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setRasterizer(new testrast)->unref();
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawPath(fPath, paint);
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
177e5ff43906603dff33e14086cf1e5d73c157d2e8ereed@google.com    typedef SampleView INHERITED;
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkView* MyFactory() { return new PathEffectView; }
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkViewRegister reg(MyFactory);
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
185