• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "gm.h"
9 
10 class SkJSCanvas {
11 public:
12     SkJSCanvas(SkCanvas* target);
13     ~SkJSCanvas();
14 
15     void save();
16     void restore();
17 
18     double lineWidth;
19     void setLineWidth(double);
20 
21     void beginPath();
22     void moveTo(double x, double y);
23     void lineTo(double x, double y);
24     void closePath();
25 
26     void fill();
27     void stroke();
28 
29     void fillText(const char text[], double x, double y);
30 
31 private:
32     SkCanvas*   fTarget;
33     SkPaint     fFillPaint;
34     SkPaint     fStrokePaint;
35     SkPath      fPath;
36 };
37 
SkJSCanvas(SkCanvas * target)38 SkJSCanvas::SkJSCanvas(SkCanvas* target) : fTarget(target) {
39     fFillPaint.setAntiAlias(true);
40     fStrokePaint.setAntiAlias(true);
41     fStrokePaint.setStyle(SkPaint::kStroke_Style);
42     fStrokePaint.setStrokeWidth(SK_Scalar1);
43 }
44 
~SkJSCanvas()45 SkJSCanvas::~SkJSCanvas() {}
46 
save()47 void SkJSCanvas::save() { fTarget->save(); }
restore()48 void SkJSCanvas::restore() { fTarget->restore(); }
49 
beginPath()50 void SkJSCanvas::beginPath() { fPath.reset(); }
moveTo(double x,double y)51 void SkJSCanvas::moveTo(double x, double y) {
52     fPath.moveTo(SkDoubleToScalar(x), SkDoubleToScalar(y));
53 }
54 
lineTo(double x,double y)55 void SkJSCanvas::lineTo(double x, double y) {
56     fPath.lineTo(SkDoubleToScalar(x), SkDoubleToScalar(y));
57 }
58 
closePath()59 void SkJSCanvas::closePath() { fPath.close(); }
60 
fill()61 void SkJSCanvas::fill() {
62     fTarget->drawPath(fPath, fFillPaint);
63 }
64 
stroke()65 void SkJSCanvas::stroke() {
66     fStrokePaint.setStrokeWidth(SkDoubleToScalar(lineWidth));
67     fTarget->drawPath(fPath, fStrokePaint);
68 }
69 
fillText(const char text[],double x,double y)70 void SkJSCanvas::fillText(const char text[], double x, double y) {
71     fTarget->drawText(text, strlen(text),
72                       SkDoubleToScalar(x), SkDoubleToScalar(y), fFillPaint);
73 }
74 
75 ///////////////////////////////////////////////////////////////////////////////
76 
dump(const SkPath & path)77 static void dump(const SkPath& path) {
78     const SkRect& r = path.getBounds();
79     SkDebugf("isEmpty %d, bounds [%g %g %g %g]\n", path.isEmpty(),
80              r.fLeft, r.fTop, r.fRight, r.fBottom);
81 }
82 
test_stroke(SkCanvas * canvas)83 static void test_stroke(SkCanvas* canvas) {
84     if (true) {
85         SkPath path;
86         dump(path);
87         path.reset(); path.moveTo(0, 0);
88         dump(path);
89         path.reset(); path.moveTo(100, 100);
90         dump(path);
91         path.reset(); path.moveTo(0, 0); path.moveTo(100, 100);
92         dump(path);
93         path.reset(); path.moveTo(0, 0); path.lineTo(100, 100);
94         dump(path);
95         path.reset(); path.moveTo(0, 0); path.lineTo(100, 100); path.moveTo(200, 200);
96         dump(path);
97     }
98 
99 #if 0
100     // TEST 1 - The rectangle as it's expected to look
101     var canvas = document.createElement('canvas');
102     document.body.appendChild(canvas);
103     var ctx = canvas.getContext("2d");
104 #else
105     SkJSCanvas ctx(canvas);
106 #endif
107 
108     ctx.save();
109     ctx.lineWidth = 2;
110     ctx.beginPath();
111     ctx.moveTo(10, 100);
112     ctx.lineTo(150, 100);
113     ctx.lineTo(150, 15);
114     ctx.lineTo(10, 15);
115     ctx.closePath();
116 
117     // no extra moveTo here
118     // ctx.moveTo(175, 125);
119 
120     ctx.stroke();
121     ctx.restore();
122 
123     ctx.fillText("As Expected", 10, 10);
124 
125 #if 0
126     // TEST 2 - Includes an extra moveTo call before stroke; the rectangle appears larger
127     canvas = document.createElement('canvas');
128     document.body.appendChild(canvas);
129     ctx = canvas.getContext("2d");
130 #else
131     canvas->translate(200, 0);
132 #endif
133 
134     ctx.save();
135     ctx.lineWidth = 2;
136     ctx.beginPath();
137     ctx.moveTo(10, 100);
138     ctx.lineTo(150, 100);
139     ctx.lineTo(150, 15);
140     ctx.lineTo(10, 15);
141     ctx.closePath();
142 
143     ctx.moveTo(175, 125);
144 
145     ctx.stroke();
146     ctx.restore();
147 
148     ctx.fillText("Larger Rectangle", 10, 10);
149 
150 #if 0
151     // TEST 3 - Identical to test 2 except the line width is 1
152     canvas = document.createElement('canvas');
153     document.body.appendChild(canvas);
154     ctx = canvas.getContext("2d");
155 #else
156     canvas->translate(200, 0);
157 #endif
158 
159     ctx.save();
160     ctx.lineWidth = 1;
161     ctx.beginPath();
162     ctx.moveTo(10, 100);
163     ctx.lineTo(150, 100);
164     ctx.lineTo(150, 15);
165     ctx.lineTo(10, 15);
166     ctx.closePath();
167 
168     ctx.moveTo(175, 125);
169 
170     ctx.stroke();
171     ctx.restore();
172 
173     ctx.fillText("As Expected - line width 1", 10, 10);
174 }
175 
176 class Poly2PolyGM : public skiagm::GM {
177 public:
Poly2PolyGM()178     Poly2PolyGM() {}
179 
180 protected:
onShortName()181     virtual SkString onShortName() SK_OVERRIDE {
182         return SkString("poly2poly");
183     }
184 
onISize()185     virtual SkISize onISize() SK_OVERRIDE {
186         return SkISize::Make(835, 840);
187     }
188 
doDraw(SkCanvas * canvas,SkPaint * paint,const int isrc[],const int idst[],int count)189     static void doDraw(SkCanvas* canvas, SkPaint* paint, const int isrc[],
190                        const int idst[], int count) {
191         SkMatrix matrix;
192         SkPoint src[4], dst[4];
193 
194         for (int i = 0; i < count; i++) {
195             src[i].set(SkIntToScalar(isrc[2*i+0]), SkIntToScalar(isrc[2*i+1]));
196             dst[i].set(SkIntToScalar(idst[2*i+0]), SkIntToScalar(idst[2*i+1]));
197         }
198 
199         canvas->save();
200         matrix.setPolyToPoly(src, dst, count);
201         canvas->concat(matrix);
202 
203         paint->setColor(SK_ColorGRAY);
204         paint->setStyle(SkPaint::kStroke_Style);
205         const SkScalar D = SkIntToScalar(64);
206         canvas->drawRectCoords(0, 0, D, D, *paint);
207         canvas->drawLine(0, 0, D, D, *paint);
208         canvas->drawLine(0, D, D, 0, *paint);
209 
210         SkPaint::FontMetrics fm;
211         paint->getFontMetrics(&fm);
212         paint->setColor(SK_ColorRED);
213         paint->setStyle(SkPaint::kFill_Style);
214         SkScalar x = D/2;
215         SkScalar y = D/2 - (fm.fAscent + fm.fDescent)/2;
216         SkString str;
217         str.appendS32(count);
218         canvas->drawText(str.c_str(), str.size(), x, y, *paint);
219 
220         canvas->restore();
221     }
222 
onDraw(SkCanvas * canvas)223     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
224         if (false) { test_stroke(canvas); return; }
225 
226         SkPaint paint;
227         paint.setAntiAlias(true);
228         paint.setStrokeWidth(SkIntToScalar(4));
229         paint.setTextSize(SkIntToScalar(40));
230         paint.setTextAlign(SkPaint::kCenter_Align);
231 
232         canvas->save();
233         canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
234         // translate (1 point)
235         const int src1[] = { 0, 0 };
236         const int dst1[] = { 5, 5 };
237         doDraw(canvas, &paint, src1, dst1, 1);
238         canvas->restore();
239 
240         canvas->save();
241         canvas->translate(SkIntToScalar(160), SkIntToScalar(10));
242         // rotate/uniform-scale (2 points)
243         const int src2[] = { 32, 32, 64, 32 };
244         const int dst2[] = { 32, 32, 64, 48 };
245         doDraw(canvas, &paint, src2, dst2, 2);
246         canvas->restore();
247 
248         canvas->save();
249         canvas->translate(SkIntToScalar(10), SkIntToScalar(110));
250         // rotate/skew (3 points)
251         const int src3[] = { 0, 0, 64, 0, 0, 64 };
252         const int dst3[] = { 0, 0, 96, 0, 24, 64 };
253         doDraw(canvas, &paint, src3, dst3, 3);
254         canvas->restore();
255 
256         canvas->save();
257         canvas->translate(SkIntToScalar(160), SkIntToScalar(110));
258         // perspective (4 points)
259         const int src4[] = { 0, 0, 64, 0, 64, 64, 0, 64 };
260         const int dst4[] = { 0, 0, 96, 0, 64, 96, 0, 64 };
261         doDraw(canvas, &paint, src4, dst4, 4);
262         canvas->restore();
263     }
264 
265 private:
266     typedef skiagm::GM INHERITED;
267 };
268 
269 //////////////////////////////////////////////////////////////////////////////
270 
271 DEF_GM( return new Poly2PolyGM; )
272