| |
| /* |
| * Copyright 2011 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| #include "SampleCode.h" |
| #include "SkView.h" |
| #include "SkCanvas.h" |
| #include "SkCornerPathEffect.h" |
| #include "SkCullPoints.h" |
| #include "SkGradientShader.h" |
| #include "SkPath.h" |
| #include "SkRegion.h" |
| #include "SkShader.h" |
| #include "SkUtils.h" |
| #include "SkRandom.h" |
| |
| static void addbump(SkPath* path, const SkPoint pts[2], SkScalar bump) { |
| SkVector tang; |
| |
| tang.setLength(pts[1].fX - pts[0].fX, pts[1].fY - pts[0].fY, bump); |
| |
| path->lineTo(SkScalarHalf(pts[0].fX + pts[1].fX) - tang.fY, |
| SkScalarHalf(pts[0].fY + pts[1].fY) + tang.fX); |
| path->lineTo(pts[1]); |
| } |
| |
| static void subdivide(SkPath* path, SkScalar bump) { |
| SkPath::Iter iter(*path, false); |
| SkPoint pts[4]; |
| SkPath tmp; |
| |
| for (;;) |
| switch (iter.next(pts)) { |
| case SkPath::kMove_Verb: |
| tmp.moveTo(pts[0]); |
| break; |
| case SkPath::kLine_Verb: |
| addbump(&tmp, pts, bump); |
| bump = -bump; |
| break; |
| case SkPath::kDone_Verb: |
| goto FINISH; |
| default: |
| break; |
| } |
| |
| FINISH: |
| path->swap(tmp); |
| } |
| |
| static SkIPoint* getpts(const SkPath& path, int* count) { |
| SkPoint pts[4]; |
| int n = 1; |
| SkIPoint* array; |
| |
| { |
| SkPath::Iter iter(path, false); |
| for (;;) |
| switch (iter.next(pts)) { |
| case SkPath::kLine_Verb: |
| n += 1; |
| break; |
| case SkPath::kDone_Verb: |
| goto FINISHED; |
| default: |
| break; |
| } |
| } |
| |
| FINISHED: |
| array = new SkIPoint[n]; |
| n = 0; |
| |
| { |
| SkPath::Iter iter(path, false); |
| for (;;) |
| switch (iter.next(pts)) { |
| case SkPath::kMove_Verb: |
| array[n++].set(SkScalarRoundToInt(pts[0].fX), |
| SkScalarRoundToInt(pts[0].fY)); |
| break; |
| case SkPath::kLine_Verb: |
| array[n++].set(SkScalarRoundToInt(pts[1].fX), |
| SkScalarRoundToInt(pts[1].fY)); |
| break; |
| case SkPath::kDone_Verb: |
| goto FINISHED2; |
| default: |
| break; |
| } |
| } |
| |
| FINISHED2: |
| *count = n; |
| return array; |
| } |
| |
| static SkScalar nextScalarRange(SkRandom& rand, SkScalar min, SkScalar max) { |
| return min + SkScalarMul(rand.nextUScalar1(), max - min); |
| } |
| |
| class CullView : public SampleView { |
| public: |
| CullView() { |
| fClip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160)); |
| |
| SkRandom rand; |
| |
| for (int i = 0; i < 50; i++) { |
| SkScalar x = nextScalarRange(rand, -fClip.width()*1, fClip.width()*2); |
| SkScalar y = nextScalarRange(rand, -fClip.height()*1, fClip.height()*2); |
| if (i == 0) |
| fPath.moveTo(x, y); |
| else |
| fPath.lineTo(x, y); |
| } |
| |
| SkScalar bump = fClip.width()/8; |
| subdivide(&fPath, bump); |
| subdivide(&fPath, bump); |
| subdivide(&fPath, bump); |
| fPoints = getpts(fPath, &fPtCount); |
| |
| this->setBGColor(0xFFDDDDDD); |
| } |
| |
| virtual ~CullView() { |
| delete[] fPoints; |
| } |
| |
| protected: |
| // overrides from SkEventSink |
| virtual bool onQuery(SkEvent* evt) { |
| if (SampleCode::TitleQ(*evt)) { |
| SampleCode::TitleR(evt, "Culling"); |
| return true; |
| } |
| return this->INHERITED::onQuery(evt); |
| } |
| |
| virtual void onDrawContent(SkCanvas* canvas) { |
| SkAutoCanvasRestore ar(canvas, true); |
| |
| canvas->translate( SkScalarHalf(this->width() - fClip.width()), |
| SkScalarHalf(this->height() - fClip.height())); |
| |
| // canvas->scale(SK_Scalar1*3, SK_Scalar1*3, 0, 0); |
| |
| SkPaint paint; |
| |
| // paint.setAntiAliasOn(true); |
| paint.setStyle(SkPaint::kStroke_Style); |
| |
| canvas->drawRect(fClip, paint); |
| |
| #if 1 |
| paint.setColor(0xFF555555); |
| paint.setStrokeWidth(SkIntToScalar(2)); |
| // paint.setPathEffect(new SkCornerPathEffect(SkIntToScalar(30)))->unref(); |
| canvas->drawPath(fPath, paint); |
| // paint.setPathEffect(nullptr); |
| #endif |
| |
| SkPath tmp; |
| SkIRect iclip; |
| fClip.round(&iclip); |
| |
| SkCullPointsPath cpp(iclip, &tmp); |
| |
| cpp.moveTo(fPoints[0].fX, fPoints[0].fY); |
| for (int i = 0; i < fPtCount; i++) |
| cpp.lineTo(fPoints[i].fX, fPoints[i].fY); |
| |
| paint.setColor(SK_ColorRED); |
| paint.setStrokeWidth(SkIntToScalar(3)); |
| paint.setStrokeJoin(SkPaint::kRound_Join); |
| canvas->drawPath(tmp, paint); |
| |
| this->inval(nullptr); |
| } |
| |
| private: |
| SkRect fClip; |
| SkIPoint* fPoints; |
| SkPath fPath; |
| int fPtCount; |
| |
| typedef SampleView INHERITED; |
| }; |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| static SkView* MyFactory() { return new CullView; } |
| static SkViewRegister reg(MyFactory); |