1 #include "SkCanvas.h" 2 #include "SkCGUtils.h" 3 #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 11 static 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 20 static 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 51 class SkSampleView : public SkView { 52 public: 53 SkSampleView() { 54 this->setVisibleP(true); 55 this->setClipToBounds(false); 56 }; 57 protected: 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); 64 // SkRect r = {50, 50, 80, 80}; 65 p.setColor(0xAA11EEAA); 66 // 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 90 } 91 private: 92 typedef SkView INHERITED; 93 }; 94 95 void application_init(); 96 void application_term(); 97 98 static 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 137 class 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(©); 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 198 public: 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 230 bool runone = false; 231 232 void application_init() { 233 SkGraphics::Init(); 234 SkEvent::Init(); 235 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"); 274 } 275 276 void application_term() { 277 SkGraphics::Term(); 278 SkEvent::Term(); 279 } 280 281 class FillLayout : public SkView::Layout { 282 protected: 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 { 293 if ((self = [super initWithDefaults])) { 294 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 306 @end 307