1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SampleCode.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkView.h"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCornerPathEffect.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCullPoints.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGradientShader.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPath.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRegion.h"
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h"
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h"
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRandom.h"
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
20961ddb04a0a7aba843032d829ab867518e52559ereed@google.comstatic void addbump(SkPath* path, const SkPoint pts[2], SkScalar bump) {
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkVector    tang;
22ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    tang.setLength(pts[1].fX - pts[0].fX, pts[1].fY - pts[0].fY, bump);
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    path->lineTo(SkScalarHalf(pts[0].fX + pts[1].fX) - tang.fY,
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                 SkScalarHalf(pts[0].fY + pts[1].fY) + tang.fX);
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    path->lineTo(pts[1]);
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
30961ddb04a0a7aba843032d829ab867518e52559ereed@google.comstatic void subdivide(SkPath* path, SkScalar bump) {
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath::Iter    iter(*path, false);
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint         pts[4];
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath          tmp;
34ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (;;)
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        switch (iter.next(pts)) {
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case SkPath::kMove_Verb:
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            tmp.moveTo(pts[0]);
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case SkPath::kLine_Verb:
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            addbump(&tmp, pts, bump);
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            bump = -bump;
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case SkPath::kDone_Verb:
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            goto FINISH;
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        default:
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comFINISH:
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    path->swap(tmp);
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
54961ddb04a0a7aba843032d829ab867518e52559ereed@google.comstatic SkIPoint* getpts(const SkPath& path, int* count) {
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint     pts[4];
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int         n = 1;
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkIPoint*   array;
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPath::Iter    iter(path, false);
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (;;)
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            switch (iter.next(pts)) {
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case SkPath::kLine_Verb:
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                n += 1;
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case SkPath::kDone_Verb:
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                goto FINISHED;
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            default:
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comFINISHED:
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    array = new SkIPoint[n];
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    n = 0;
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPath::Iter    iter(path, false);
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (;;)
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            switch (iter.next(pts)) {
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case SkPath::kMove_Verb:
82e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com                array[n++].set(SkScalarRoundToInt(pts[0].fX),
83e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com                               SkScalarRoundToInt(pts[0].fY));
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case SkPath::kLine_Verb:
86e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com                array[n++].set(SkScalarRoundToInt(pts[1].fX),
87e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com                               SkScalarRoundToInt(pts[1].fY));
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case SkPath::kDone_Verb:
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                goto FINISHED2;
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            default:
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
95ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comFINISHED2:
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *count = n;
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return array;
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
101e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgstatic SkScalar nextScalarRange(SkRandom& rand, SkScalar min, SkScalar max) {
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return min + SkScalarMul(rand.nextUScalar1(), max - min);
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
105961ddb04a0a7aba843032d829ab867518e52559ereed@google.comclass CullView : public SampleView {
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
107ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com    CullView() {
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fClip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
109ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
110e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom    rand;
111ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (int i = 0; i < 50; i++) {
113261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com            SkScalar x = nextScalarRange(rand, -fClip.width()*1, fClip.width()*2);
114261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com            SkScalar y = nextScalarRange(rand, -fClip.height()*1, fClip.height()*2);
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (i == 0)
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                fPath.moveTo(x, y);
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            else
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                fPath.lineTo(x, y);
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
120ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScalar bump = fClip.width()/8;
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        subdivide(&fPath, bump);
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        subdivide(&fPath, bump);
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        subdivide(&fPath, bump);
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPoints = getpts(fPath, &fPtCount);
126ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
127961ddb04a0a7aba843032d829ab867518e52559ereed@google.com        this->setBGColor(0xFFDDDDDD);
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
129ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
130961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    virtual ~CullView() {
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        delete[] fPoints;
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // overrides from SkEventSink
136961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    virtual bool onQuery(SkEvent* evt) {
137961ddb04a0a7aba843032d829ab867518e52559ereed@google.com        if (SampleCode::TitleQ(*evt)) {
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SampleCode::TitleR(evt, "Culling");
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return this->INHERITED::onQuery(evt);
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
143ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
144961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    virtual void onDrawContent(SkCanvas* canvas) {
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkAutoCanvasRestore ar(canvas, true);
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->translate(  SkScalarHalf(this->width() - fClip.width()),
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                            SkScalarHalf(this->height() - fClip.height()));
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com   //     canvas->scale(SK_Scalar1*3, SK_Scalar1*3, 0, 0);
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPaint paint;
153ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    //    paint.setAntiAliasOn(true);
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setStyle(SkPaint::kStroke_Style);
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawRect(fClip, paint);
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 1
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setColor(0xFF555555);
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setStrokeWidth(SkIntToScalar(2));
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//        paint.setPathEffect(new SkCornerPathEffect(SkIntToScalar(30)))->unref();
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawPath(fPath, paint);
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//        paint.setPathEffect(NULL);
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPath  tmp;
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkIRect iclip;
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fClip.round(&iclip);
170ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkCullPointsPath    cpp(iclip, &tmp);
172ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        cpp.moveTo(fPoints[0].fX, fPoints[0].fY);
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (int i = 0; i < fPtCount; i++)
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            cpp.lineTo(fPoints[i].fX, fPoints[i].fY);
176ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setColor(SK_ColorRED);
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setStrokeWidth(SkIntToScalar(3));
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setStrokeJoin(SkPaint::kRound_Join);
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawPath(tmp, paint);
181ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->inval(NULL);
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
184ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkRect      fClip;
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkIPoint*   fPoints;
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath      fPath;
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int         fPtCount;
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
191961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    typedef SampleView INHERITED;
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkView* MyFactory() { return new CullView; }
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkViewRegister reg(MyFactory);
198