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