Home | History | Annotate | Download | only in samplecode
      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 "SampleCode.h"
      9 #include "SkDumpCanvas.h"
     10 #include "SkView.h"
     11 #include "SkCanvas.h"
     12 #include "SkGradientShader.h"
     13 #include "SkGraphics.h"
     14 #include "SkImageDecoder.h"
     15 #include "SkOSFile.h"
     16 #include "SkPath.h"
     17 #include "SkPicture.h"
     18 #include "SkPictureRecorder.h"
     19 #include "SkRandom.h"
     20 #include "SkRegion.h"
     21 #include "SkShader.h"
     22 #include "SkUtils.h"
     23 #include "SkColorPriv.h"
     24 #include "SkColorFilter.h"
     25 #include "SkTime.h"
     26 #include "SkTypeface.h"
     27 #include "SkXfermode.h"
     28 
     29 #include "SkStream.h"
     30 #include "SkSurface.h"
     31 #include "SkXMLParser.h"
     32 
     33 class PictFileView : public SampleView {
     34 public:
     35     PictFileView(const char name[] = NULL)
     36         : fFilename(name)
     37         , fBBox(kNo_BBoxType)
     38         , fTileSize(SkSize::Make(0, 0)) {
     39         for (int i = 0; i < kBBoxTypeCount; ++i) {
     40             fPictures[i] = NULL;
     41         }
     42     }
     43 
     44     virtual ~PictFileView() {
     45         for (int i = 0; i < kBBoxTypeCount; ++i) {
     46             SkSafeUnref(fPictures[i]);
     47         }
     48     }
     49 
     50     virtual void onTileSizeChanged(const SkSize &tileSize) SK_OVERRIDE {
     51         if (tileSize != fTileSize) {
     52             fTileSize = tileSize;
     53             SkSafeSetNull(fPictures[kTileGrid_BBoxType]);
     54         }
     55     }
     56 
     57 protected:
     58     // overrides from SkEventSink
     59     virtual bool onQuery(SkEvent* evt) SK_OVERRIDE {
     60         if (SampleCode::TitleQ(*evt)) {
     61             SkString name("P:");
     62             const char* basename = strrchr(fFilename.c_str(), SkPATH_SEPARATOR);
     63             name.append(basename ? basename+1: fFilename.c_str());
     64             switch (fBBox) {
     65             case kNo_BBoxType:
     66                 // No name appended
     67                 break;
     68             case kRTree_BBoxType:
     69                 name.append(" <bbox: R>");
     70                 break;
     71             case kQuadTree_BBoxType:
     72                 name.append(" <bbox: Q>");
     73                 break;
     74             case kTileGrid_BBoxType:
     75                 name.append(" <bbox: T>");
     76                 break;
     77             default:
     78                 SkASSERT(false);
     79                 break;
     80             }
     81             SampleCode::TitleR(evt, name.c_str());
     82             return true;
     83         }
     84         return this->INHERITED::onQuery(evt);
     85     }
     86 
     87     virtual bool onEvent(const SkEvent& evt) SK_OVERRIDE {
     88         if (evt.isType("PictFileView::toggleBBox")) {
     89             fBBox = (BBoxType)((fBBox + 1) % kBBoxTypeCount);
     90             return true;
     91         }
     92         return this->INHERITED::onEvent(evt);
     93     }
     94 
     95     virtual void onDrawContent(SkCanvas* canvas) SK_OVERRIDE {
     96         SkASSERT(static_cast<int>(fBBox) < kBBoxTypeCount);
     97         SkPicture** picture = fPictures + fBBox;
     98 
     99         if (!*picture) {
    100             *picture = LoadPicture(fFilename.c_str(), fBBox);
    101         }
    102         if (*picture) {
    103             canvas->drawPicture(*picture);
    104         }
    105     }
    106 
    107 private:
    108     enum BBoxType {
    109         kNo_BBoxType,
    110         kQuadTree_BBoxType,
    111         kRTree_BBoxType,
    112         kTileGrid_BBoxType,
    113 
    114         kLast_BBoxType = kTileGrid_BBoxType
    115     };
    116     static const int kBBoxTypeCount = kLast_BBoxType + 1;
    117 
    118     SkString    fFilename;
    119     SkPicture*  fPictures[kBBoxTypeCount];
    120     BBoxType    fBBox;
    121     SkSize      fTileSize;
    122 
    123     SkPicture* LoadPicture(const char path[], BBoxType bbox) {
    124         SkAutoTUnref<SkPicture> pic;
    125 
    126         SkBitmap bm;
    127         if (SkImageDecoder::DecodeFile(path, &bm)) {
    128             bm.setImmutable();
    129             SkPictureRecorder recorder;
    130             SkCanvas* can = recorder.beginRecording(bm.width(), bm.height(), NULL, 0);
    131             can->drawBitmap(bm, 0, 0, NULL);
    132             pic.reset(recorder.endRecording());
    133         } else {
    134             SkFILEStream stream(path);
    135             if (stream.isValid()) {
    136                 pic.reset(SkPicture::CreateFromStream(&stream));
    137             } else {
    138                 SkDebugf("coun't load picture at \"path\"\n", path);
    139             }
    140 
    141             if (false) {
    142                 SkSurface* surf = SkSurface::NewRasterPMColor(pic->width(), pic->height());
    143                 surf->getCanvas()->drawPicture(pic);
    144                 surf->unref();
    145             }
    146             if (false) { // re-record
    147                 SkPictureRecorder recorder;
    148                 pic->draw(recorder.beginRecording(pic->width(), pic->height(), NULL, 0));
    149                 SkAutoTUnref<SkPicture> p2(recorder.endRecording());
    150 
    151                 SkString path2(path);
    152                 path2.append(".new.skp");
    153                 SkFILEWStream writer(path2.c_str());
    154                 p2->serialize(&writer);
    155             }
    156         }
    157 
    158         if (NULL == pic) {
    159             return NULL;
    160         }
    161 
    162         SkAutoTDelete<SkBBHFactory> factory;
    163         switch (bbox) {
    164         case kNo_BBoxType:
    165             // no bbox playback necessary
    166             return pic.detach();
    167         case kRTree_BBoxType:
    168             factory.reset(SkNEW(SkRTreeFactory));
    169             break;
    170         case kQuadTree_BBoxType:
    171             factory.reset(SkNEW(SkQuadTreeFactory));
    172             break;
    173         case kTileGrid_BBoxType: {
    174             SkASSERT(!fTileSize.isEmpty());
    175             SkTileGridFactory::TileGridInfo gridInfo;
    176             gridInfo.fMargin = SkISize::Make(0, 0);
    177             gridInfo.fOffset = SkIPoint::Make(0, 0);
    178             gridInfo.fTileInterval = fTileSize.toRound();
    179             factory.reset(SkNEW_ARGS(SkTileGridFactory, (gridInfo)));
    180             break;
    181         }
    182         default:
    183             SkASSERT(false);
    184         }
    185 
    186         SkPictureRecorder recorder;
    187         pic->draw(recorder.beginRecording(pic->width(), pic->height(), factory.get(), 0));
    188         return recorder.endRecording();
    189     }
    190 
    191     typedef SampleView INHERITED;
    192 };
    193 
    194 SampleView* CreateSamplePictFileView(const char filename[]);
    195 SampleView* CreateSamplePictFileView(const char filename[]) {
    196     return new PictFileView(filename);
    197 }
    198 
    199 //////////////////////////////////////////////////////////////////////////////
    200 
    201 #if 0
    202 static SkView* MyFactory() { return new PictFileView; }
    203 static SkViewRegister reg(MyFactory);
    204 #endif
    205