Home | History | Annotate | Download | only in SimpleCocoaApp
      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(&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     
    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