aboutsummaryrefslogtreecommitdiffhomepage
path: root/samplecode/SampleCull.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'samplecode/SampleCull.cpp')
-rw-r--r--samplecode/SampleCull.cpp230
1 files changed, 230 insertions, 0 deletions
diff --git a/samplecode/SampleCull.cpp b/samplecode/SampleCull.cpp
new file mode 100644
index 0000000000..ea1bb779ec
--- /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);
+