blob: 7dac2a4fffac34b1b6dec5418f9ef388257d80cf [file] [log] [blame]
caryclark@google.comaa358312013-01-29 20:28:49 +00001#include "SkCanvas.h"
yangsu@google.com69f2e052011-08-30 17:08:08 +00002#include "SkCGUtils.h"
caryclark@google.comaa358312013-01-29 20:28:49 +00003#include "SkGraphics.h"
4#include "SkImageDecoder.h"
5#include "SkOSFile.h"
6#include "SkPaint.h"
7#include "SkPicture.h"
8#include "SkStream.h"
9#include "SkWindow.h"
10
11static void make_filepath(SkString* path, const char* dir, const SkString& name) {
12 size_t len = strlen(dir);
13 path->set(dir);
14 if (len > 0 && dir[len - 1] != '/') {
15 path->append("/");
16 }
17 path->append(name);
18}
19
20static SkPicture* LoadPicture(const char path[]) {
21 SkPicture* pic = NULL;
22
23 SkBitmap bm;
24 if (SkImageDecoder::DecodeFile(path, &bm)) {
25 bm.setImmutable();
26 pic = SkNEW(SkPicture);
27 SkCanvas* can = pic->beginRecording(bm.width(), bm.height());
28 can->drawBitmap(bm, 0, 0, NULL);
29 pic->endRecording();
30 } else {
31 SkFILEStream stream(path);
32 if (stream.isValid()) {
33 pic = SkNEW_ARGS(SkPicture,
34 (&stream, NULL, &SkImageDecoder::DecodeStream));
35 }
36
37 if (false) { // re-record
38 SkPicture p2;
39 pic->draw(p2.beginRecording(pic->width(), pic->height()));
40 p2.endRecording();
41
42 SkString path2(path);
43 path2.append(".new.skp");
44 SkFILEWStream writer(path2.c_str());
45 p2.serialize(&writer);
46 }
47 }
48 return pic;
49}
50
yangsu@google.com69f2e052011-08-30 17:08:08 +000051class SkSampleView : public SkView {
52public:
53 SkSampleView() {
54 this->setVisibleP(true);
55 this->setClipToBounds(false);
56 };
57protected:
58 virtual void onDraw(SkCanvas* canvas) {
59 canvas->drawColor(0xFFFFFFFF);
60 SkPaint p;
61 p.setTextSize(20);
62 p.setAntiAlias(true);
63 canvas->drawText("Hello World!", 13, 50, 30, p);
caryclark@google.comaa358312013-01-29 20:28:49 +000064 // SkRect r = {50, 50, 80, 80};
yangsu@google.com69f2e052011-08-30 17:08:08 +000065 p.setColor(0xAA11EEAA);
caryclark@google.comaa358312013-01-29 20:28:49 +000066 // canvas->drawRect(r, p);
67
68 SkRect result;
69 SkPath path;
70 path.moveTo(0, 0);
71 path.lineTo(1, 1);
72 path.lineTo(1, 8);
73 path.lineTo(0, 9);
74 SkASSERT(path.hasRectangularInterior(&result));
75
76 path.reset();
77 path.addRect(10, 10, 100, 100, SkPath::kCW_Direction);
78 path.addRect(20, 20, 50, 50, SkPath::kCW_Direction);
79 path.addRect(50, 50, 90, 90, SkPath::kCCW_Direction);
80 p.setColor(0xAA335577);
81 canvas->drawPath(path, p);
82 SkASSERT(!path.hasRectangularInterior(NULL));
83 path.reset();
84 path.addRect(10, 10, 100, 100, SkPath::kCW_Direction);
85 path.addRect(20, 20, 80, 80, SkPath::kCW_Direction);
86 SkRect expected = {20, 20, 80, 80};
87 SkASSERT(path.hasRectangularInterior(&result));
88 SkASSERT(result == expected);
89
yangsu@google.com69f2e052011-08-30 17:08:08 +000090 }
91private:
92 typedef SkView INHERITED;
93};
94
caryclark@google.comaa358312013-01-29 20:28:49 +000095void application_init();
96void application_term();
97
98static int showPathContour(SkPath::Iter& iter) {
99 uint8_t verb;
100 SkPoint pts[4];
101 int moves = 0;
102 bool waitForClose = false;
103 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
104 switch (verb) {
105 case SkPath::kMove_Verb:
106 if (!waitForClose) {
107 ++moves;
108 waitForClose = true;
109 }
110 SkDebugf("path.moveTo(%1.9g, %1.9g);\n", pts[0].fX, pts[0].fY);
111 break;
112 case SkPath::kLine_Verb:
113 SkDebugf("path.lineTo(%1.9g, %1.9g);\n", pts[1].fX, pts[1].fY);
114 break;
115 case SkPath::kQuad_Verb:
116 SkDebugf("path.quadTo(%1.9g, %1.9g, %1.9g, %1.9g);\n",
117 pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
118 break;
119 case SkPath::kCubic_Verb:
120 SkDebugf("path.cubicTo(%1.9g, %1.9g, %1.9g, %1.9g, %1.9g, %1.9g);\n",
121 pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY,
122 pts[3].fX, pts[3].fY);
123 break;
124 case SkPath::kClose_Verb:
125 waitForClose = false;
126 SkDebugf("path.close();\n");
127 break;
128 default:
129 SkDEBUGFAIL("bad verb");
130 SkASSERT(0);
131 return 0;
132 }
133 }
134 return moves;
135}
136
137class PathCanvas : public SkCanvas {
138 virtual void drawPath(const SkPath& path, const SkPaint& paint) {
139 if (nameonly) {
140 SkDebugf(" %s%d,\n", filename.c_str(), ++count);
141 return;
142 }
143 SkPath::Iter iter(path, true);
144 SkDebugf("<div id=\"%s%d\">\n", filename.c_str(), ++count);
145 SkASSERT(path.getFillType() < SkPath::kInverseWinding_FillType);
146 SkDebugf("path.setFillType(SkPath::k%s_FillType);\n",
147 path.getFillType() == SkPath::kWinding_FillType ? "Winding" : "EvenOdd");
148 int contours = showPathContour(iter);
149 SkRect r;
150 SkRect copy = r;
151 bool hasOne = path.hasRectangularInterior(&r);
152 bool expected = (path.getFillType() == SkPath::kWinding_FillType && contours == 1)
153 || (path.getFillType() == SkPath::kEvenOdd_FillType && contours == 2);
154 if (!expected) {
155 SkDebugf("suspect contours=%d\n", contours);
156 }
157 int verbs = path.countVerbs();
158 int points = path.countPoints();
159 if (hasOne) {
160 if (rectVerbsMin > verbs) {
161 rectVerbsMin = verbs;
162 }
163 if (rectVerbsMax < verbs) {
164 rectVerbsMax = verbs;
165 }
166 if (rectPointsMin > points) {
167 rectPointsMin = points;
168 }
169 if (rectPointsMax < points) {
170 rectPointsMax = points;
171 }
172 SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g);\n",
173 r.fLeft, r.fTop, r.fRight, r.fBottom);
174 } else {
175 if (verbsMin > verbs) {
176 verbsMin = verbs;
177 }
178 if (verbsMax < verbs) {
179 verbsMax = verbs;
180 }
181 if (pointsMin > points) {
182 pointsMin = points;
183 }
184 if (pointsMax < points) {
185 pointsMax = points;
186 }
187 SkDebugf("no interior bounds\n");
188 }
189 path.hasRectangularInterior(&copy);
190 SkDebugf("</div>\n\n");
191 }
192
193 virtual void drawPosTextH(const void* text, size_t byteLength,
194 const SkScalar xpos[], SkScalar constY,
195 const SkPaint& paint) {
196 }
197
198public:
199 void divName(const SkString& str, bool only) {
200 filename = str;
201 char* chars = filename.writable_str();
202 while (*chars) {
203 if (*chars == '.' || *chars == '-') *chars = '_';
204 chars++;
205 }
206 count = 0;
207 nameonly = only;
208 }
209
210 void init() {
211 pointsMin = verbsMin = SK_MaxS32;
212 pointsMax = verbsMax = SK_MinS32;
213 rectPointsMin = rectVerbsMin = SK_MaxS32;
214 rectPointsMax = rectVerbsMax = SK_MinS32;
215 }
216
217 SkString filename;
218 int count;
219 bool nameonly;
220 int pointsMin;
221 int pointsMax;
222 int verbsMin;
223 int verbsMax;
224 int rectPointsMin;
225 int rectPointsMax;
226 int rectVerbsMin;
227 int rectVerbsMax;
228};
229
230bool runone = false;
231
yangsu@google.com69f2e052011-08-30 17:08:08 +0000232void application_init() {
233 SkGraphics::Init();
234 SkEvent::Init();
caryclark@google.comaa358312013-01-29 20:28:49 +0000235 if (runone) {
236 return;
237 }
238 const char pictDir[] = "/Volumes/chrome/nih/skia/skp/skp";
239 SkOSFile::Iter iter(pictDir, "skp");
240 SkString filename;
241 PathCanvas canvas;
242 canvas.init();
243 while (iter.next(&filename)) {
244 SkString path;
245 // if (true) filename.set("tabl_www_sahadan_com.skp");
246 make_filepath(&path, pictDir, filename);
247 canvas.divName(filename, false);
248 SkPicture* pic = LoadPicture(path.c_str());
249 pic->draw(&canvas);
250 SkDELETE(pic);
251 }
252 SkDebugf("\n</div>\n\n");
253
254 SkDebugf("<script type=\"text/javascript\">\n\n");
255 SkDebugf("var testDivs = [\n");
256
257 iter.reset(pictDir, "skp");
258 while (iter.next(&filename)) {
259 SkString path;
260 make_filepath(&path, pictDir, filename);
261 canvas.divName(filename, true);
262 SkPicture* pic = LoadPicture(path.c_str());
263 pic->draw(&canvas);
264 SkDELETE(pic);
265 }
266 SkDebugf("];\n\n");
267
268 SkDebugf("points min=%d max=%d verbs min=%d max=%d\n", canvas.pointsMin, canvas.pointsMax,
269 canvas.verbsMin, canvas.verbsMax);
270 SkDebugf("rect points min=%d max=%d verbs min=%d max=%d\n", canvas.rectPointsMin, canvas.rectPointsMax,
271 canvas.rectVerbsMin, canvas.rectVerbsMax);
272
273 SkDebugf("\n");
yangsu@google.com69f2e052011-08-30 17:08:08 +0000274}
275
276void application_term() {
277 SkGraphics::Term();
278 SkEvent::Term();
279}
280
281class FillLayout : public SkView::Layout {
282protected:
283 virtual void onLayoutChildren(SkView* parent) {
284 SkView* view = SkView::F2BIter(parent).next();
285 view->setSize(parent->width(), parent->height());
286 }
287};
288
289#import "SimpleApp.h"
290@implementation SimpleNSView
291
292- (id)initWithDefaults {
caryclark@google.comaa358312013-01-29 20:28:49 +0000293 if ((self = [super initWithDefaults])) {
yangsu@google.com69f2e052011-08-30 17:08:08 +0000294 fWind = new SkOSWindow(self);
295 fWind->setLayout(new FillLayout, false);
296 fWind->attachChildToFront(new SkSampleView)->unref();
297 }
298 return self;
299}
300
301- (void)drawRect:(NSRect)dirtyRect {
302 CGContextRef ctx = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
303 SkCGDrawBitmap(ctx, fWind->getBitmap(), 0, 0);
304}
305
caryclark@google.comaa358312013-01-29 20:28:49 +0000306@end