diff options
Diffstat (limited to 'samplecode/SampleCull.cpp')
-rw-r--r-- | samplecode/SampleCull.cpp | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/samplecode/SampleCull.cpp b/samplecode/SampleCull.cpp new file mode 100644 index 0000000..ea1bb77 --- /dev/null +++ b/samplecode/SampleCull.cpp @@ -0,0 +1,230 @@ +#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(SkScalarRound(pts[0].fX), SkScalarRound(pts[0].fY)); + break; + case SkPath::kLine_Verb: + array[n++].set(SkScalarRound(pts[1].fX), SkScalarRound(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 SkView { +public: + CullView() + { + fClip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160)); + + SkRandom rand; + + for (int i = 0; i < 50; i++) { + int x = nextScalarRange(rand, -fClip.width()*1, fClip.width()*2); + int 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); + } + + 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); + } + + void drawBG(SkCanvas* canvas) + { + canvas->drawColor(0xFFDDDDDD); + + #if 0 + SkPaint paint; + + paint.setAntiAliasOn(true); + paint.setTextSize(SkIntToScalar(20)); + paint.setTypeface(SkTypeface::Create("serif", SkTypeface::kBoldItalic))->unref(); + + uint16_t text[20]; + + text[0] = 'H'; + text[1] = 'i'; + text[2] = ' '; + for (int i = 3; i < 20; i++) + text[i] = 0x3040 + i; + canvas->drawText16(text, 20, SkIntToScalar(20), SkIntToScalar(20), paint); + #endif + } + + virtual void onDraw(SkCanvas* canvas) + { + this->drawBG(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(NULL); +#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(NULL); + } + + virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) + { + return this->INHERITED::onFindClickHandler(x, y); + } + + virtual bool onClick(Click* click) + { + return this->INHERITED::onClick(click); + } + +private: + SkRect fClip; + SkIPoint* fPoints; + SkPath fPath; + int fPtCount; + + typedef SkView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new CullView; } +static SkViewRegister reg(MyFactory); + |