SamplePath.cpp revision d0d0e65a6313f01dfd952e8cc214a7c193bec57a
1#include "SampleCode.h"
2#include "SkView.h"
3#include "SkCanvas.h"
4#include "SkGradientShader.h"
5#include "SkGraphics.h"
6#include "SkImageDecoder.h"
7#include "SkPath.h"
8#include "SkRegion.h"
9#include "SkShader.h"
10#include "SkUtils.h"
11#include "SkXfermode.h"
12#include "SkColorPriv.h"
13#include "SkColorFilter.h"
14#include "SkParsePath.h"
15#include "SkTime.h"
16#include "SkTypeface.h"
17
18#include "SkGeometry.h"
19
20// http://code.google.com/p/skia/issues/detail?id=32
21static void test_cubic() {
22    SkPoint src[4] = {
23        { 556.25000, 523.03003 },
24        { 556.23999, 522.96002 },
25        { 556.21997, 522.89001 },
26        { 556.21997, 522.82001 }
27    };
28    SkPoint dst[11];
29    dst[10].set(42, -42);   // one past the end, that we don't clobber these
30    SkScalar tval[] = { 0.33333334f, 0.99999994f };
31
32    SkChopCubicAt(src, dst, tval, 2);
33
34#if 0
35    for (int i = 0; i < 11; i++) {
36        SkDebugf("--- %d [%g %g]\n", i, dst[i].fX, dst[i].fY);
37    }
38#endif
39}
40
41static void test_cubic2() {
42    const char* str = "M2242 -590088L-377758 9.94099e+07L-377758 9.94099e+07L2242 -590088Z";
43    SkPath path;
44    SkParsePath::FromSVGString(str, &path);
45
46    {
47        float x = strtof("9.94099e+07", NULL);
48        int ix = (int)x;
49        int fx = (int)(x * 65536);
50        int ffx = SkScalarToFixed(x);
51        printf("%g %x %x %x\n", x, ix, fx, ffx);
52
53        SkRect r = path.getBounds();
54        SkIRect ir;
55        r.round(&ir);
56        printf("[%g %g %g %g] [%x %x %x %x]\n",
57               r.fLeft, r.fTop, r.fRight, r.fBottom,
58               ir.fLeft, ir.fTop, ir.fRight, ir.fBottom);
59    }
60
61    SkBitmap bitmap;
62    bitmap.setConfig(SkBitmap::kARGB_8888_Config, 300, 200);
63    bitmap.allocPixels();
64
65    SkCanvas canvas(bitmap);
66    SkPaint paint;
67    paint.setAntiAlias(true);
68    canvas.drawPath(path, paint);
69}
70
71class PathView : public SkView {
72public:
73    int fDStroke, fStroke, fMinStroke, fMaxStroke;
74    SkPath fPath[6];
75    bool fShowHairline;
76
77	PathView() {
78        test_cubic();
79        test_cubic2();
80
81        fShowHairline = false;
82
83        fDStroke = 1;
84        fStroke = 10;
85        fMinStroke = 10;
86        fMaxStroke = 180;
87
88        const int V = 85;
89
90        fPath[0].moveTo(SkIntToScalar(40), SkIntToScalar(70));
91        fPath[0].lineTo(SkIntToScalar(70), SkIntToScalar(70) + SK_Scalar1/1);
92        fPath[0].lineTo(SkIntToScalar(110), SkIntToScalar(70));
93
94        fPath[1].moveTo(SkIntToScalar(40), SkIntToScalar(70));
95        fPath[1].lineTo(SkIntToScalar(70), SkIntToScalar(70) - SK_Scalar1/1);
96        fPath[1].lineTo(SkIntToScalar(110), SkIntToScalar(70));
97
98        fPath[2].moveTo(SkIntToScalar(V), SkIntToScalar(V));
99        fPath[2].lineTo(SkIntToScalar(50), SkIntToScalar(V));
100        fPath[2].lineTo(SkIntToScalar(50), SkIntToScalar(50));
101
102        fPath[3].moveTo(SkIntToScalar(50), SkIntToScalar(50));
103        fPath[3].lineTo(SkIntToScalar(50), SkIntToScalar(V));
104        fPath[3].lineTo(SkIntToScalar(V), SkIntToScalar(V));
105
106        fPath[4].moveTo(SkIntToScalar(50), SkIntToScalar(50));
107        fPath[4].lineTo(SkIntToScalar(50), SkIntToScalar(V));
108        fPath[4].lineTo(SkIntToScalar(52), SkIntToScalar(50));
109
110        fPath[5].moveTo(SkIntToScalar(52), SkIntToScalar(50));
111        fPath[5].lineTo(SkIntToScalar(50), SkIntToScalar(V));
112        fPath[5].lineTo(SkIntToScalar(50), SkIntToScalar(50));
113    }
114
115    virtual ~PathView()
116    {
117    }
118
119    void nextStroke()
120    {
121        fStroke += fDStroke;
122        if (fStroke > fMaxStroke || fStroke < fMinStroke)
123            fDStroke = -fDStroke;
124    }
125
126protected:
127    // overrides from SkEventSink
128    virtual bool onQuery(SkEvent* evt)
129    {
130        if (SampleCode::TitleQ(*evt))
131        {
132            SampleCode::TitleR(evt, "Paths");
133            return true;
134        }
135        return this->INHERITED::onQuery(evt);
136    }
137
138    void drawBG(SkCanvas* canvas)
139    {
140        canvas->drawColor(0xFFDDDDDD);
141//        canvas->drawColor(SK_ColorWHITE);
142    }
143
144    void drawPath(SkCanvas* canvas, const SkPath& path, SkPaint::Join j)
145    {
146        SkPaint paint;
147
148        paint.setAntiAlias(true);
149        paint.setStyle(SkPaint::kStroke_Style);
150        paint.setStrokeJoin(j);
151        paint.setStrokeWidth(SkIntToScalar(fStroke));
152
153        if (fShowHairline)
154        {
155            SkPath  fill;
156
157            paint.getFillPath(path, &fill);
158            paint.setStrokeWidth(0);
159            canvas->drawPath(fill, paint);
160        }
161        else
162            canvas->drawPath(path, paint);
163
164        paint.setColor(SK_ColorRED);
165        paint.setStrokeWidth(0);
166        canvas->drawPath(path, paint);
167    }
168
169    virtual void onDraw(SkCanvas* canvas)
170    {
171        this->drawBG(canvas);
172
173        canvas->translate(SkIntToScalar(50), SkIntToScalar(50));
174
175        static const SkPaint::Join gJoins[] = {
176            SkPaint::kBevel_Join,
177            SkPaint::kMiter_Join,
178            SkPaint::kRound_Join
179        };
180
181        for (int i = 0; i < SK_ARRAY_COUNT(gJoins); i++)
182        {
183            canvas->save();
184            for (int j = 0; j < SK_ARRAY_COUNT(fPath); j++)
185            {
186                this->drawPath(canvas, fPath[j], gJoins[i]);
187                canvas->translate(SkIntToScalar(200), 0);
188            }
189            canvas->restore();
190
191            canvas->translate(0, SkIntToScalar(200));
192        }
193
194        this->nextStroke();
195        this->inval(NULL);
196    }
197
198    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y)
199    {
200        fShowHairline = !fShowHairline;
201        this->inval(NULL);
202        return this->INHERITED::onFindClickHandler(x, y);
203    }
204
205    virtual bool onClick(Click* click)
206    {
207        return this->INHERITED::onClick(click);
208    }
209
210private:
211    typedef SkView INHERITED;
212};
213
214//////////////////////////////////////////////////////////////////////////////
215
216static SkView* MyFactory() { return new PathView; }
217static SkViewRegister reg(MyFactory);
218
219