SampleStrokePath.cpp revision ed881c2704bc81fe46a68c0cf9e292287313baa6
1#include "SampleCode.h"
2#include "SkCanvas.h"
3#include "SkParsePath.h"
4#include "SkPath.h"
5#include "SkRandom.h"
6#include "SkView.h"
7
8static void scale_to_width(SkPath* path, SkScalar dstWidth) {
9    const SkRect& bounds = path->getBounds();
10    SkScalar scale = dstWidth / bounds.width();
11    SkMatrix matrix;
12
13    matrix.setScale(scale, scale);
14    path->transform(matrix);
15}
16
17static const struct {
18    SkPaint::Style  fStyle;
19    SkPaint::Join   fJoin;
20    int             fStrokeWidth;
21} gRec[] = {
22    { SkPaint::kFill_Style,             SkPaint::kMiter_Join,   0 },
23    { SkPaint::kStroke_Style,           SkPaint::kMiter_Join,   0 },
24    { SkPaint::kStroke_Style,           SkPaint::kMiter_Join,   10 },
25    { SkPaint::kStrokeAndFill_Style,    SkPaint::kMiter_Join,   10 },
26};
27
28class StrokePathView : public SkView {
29    SkScalar    fWidth;
30    SkPath      fPath;
31public:
32	StrokePathView() {
33        fWidth = SkIntToScalar(120);
34
35#if 0
36        const char str[] =
37            "M 0, 3"
38            "C 10, -10, 30, -10, 0, 28"
39            "C -30, -10, -10, -10, 0, 3"
40            "Z";
41        SkParsePath::FromSVGString(str, &fPath);
42#else
43        fPath.addCircle(0, 0, SkIntToScalar(50), SkPath::kCW_Direction);
44        fPath.addCircle(0, SkIntToScalar(-50), SkIntToScalar(30), SkPath::kCW_Direction);
45#endif
46
47        scale_to_width(&fPath, fWidth);
48        const SkRect& bounds = fPath.getBounds();
49        fPath.offset(-bounds.fLeft, -bounds.fTop);
50    }
51
52protected:
53    // overrides from SkEventSink
54    virtual bool onQuery(SkEvent* evt) {
55        if (SampleCode::TitleQ(*evt)) {
56            SampleCode::TitleR(evt, "StrokePath");
57            return true;
58        }
59        return this->INHERITED::onQuery(evt);
60    }
61
62    void drawBG(SkCanvas* canvas) {
63        canvas->drawColor(0xFFDDDDDD);
64    }
65
66    SkRandom rand;
67
68    void drawSet(SkCanvas* canvas, SkPaint* paint) {
69        SkAutoCanvasRestore acr(canvas, true);
70
71        for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) {
72            paint->setStyle(gRec[i].fStyle);
73            paint->setStrokeJoin(gRec[i].fJoin);
74            paint->setStrokeWidth(SkIntToScalar(gRec[i].fStrokeWidth));
75            canvas->drawPath(fPath, *paint);
76            canvas->translate(fWidth * 5 / 4, 0);
77        }
78    }
79
80    virtual void onDraw(SkCanvas* canvas) {
81        drawBG(canvas);
82        canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
83
84        SkPaint paint;
85        paint.setAntiAlias(true);
86        paint.setColor(SK_ColorBLUE);
87
88#if 1
89        SkPath p;
90        float r = rand.nextUScalar1() + 0.5f;
91        SkScalar x = 0, y = 0;
92        p.moveTo(x, y);
93#if 0
94        p.cubicTo(x-75*r, y+75*r, x-40*r, y+125*r, x, y+85*r);
95        p.cubicTo(x+40*r, y+125*r, x+75*r, y+75*r, x, y);
96#else
97        p.cubicTo(x+75*r, y+75*r, x+40*r, y+125*r, x, y+85*r);
98        p.cubicTo(x-40*r, y+125*r, x-75*r, y+75*r, x, y);
99#endif
100        p.close();
101        fPath = p;
102        fPath.offset(100, 0);
103#endif
104
105        fPath.setFillType(SkPath::kWinding_FillType);
106        drawSet(canvas, &paint);
107
108        canvas->translate(0, fPath.getBounds().height() * 5 / 4);
109        fPath.setFillType(SkPath::kEvenOdd_FillType);
110        drawSet(canvas, &paint);
111    }
112
113    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
114        this->inval(NULL);
115        return this->INHERITED::onFindClickHandler(x, y);
116    }
117private:
118    typedef SkView INHERITED;
119};
120
121//////////////////////////////////////////////////////////////////////////////
122
123static SkView* MyFactory() { return new StrokePathView; }
124static SkViewRegister reg(MyFactory);
125
126