grab from latest android



git-svn-id: http://skia.googlecode.com/svn/trunk@27 2bbb7eff-a529-9590-31e7-b0007b416f81
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);
+