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 kTileGrid_BBoxType:
     72                 name.append(" <bbox: T>");
     73                 break;
     74             default:
     75                 SkASSERT(false);
     76                 break;
     77             }
     78             SampleCode::TitleR(evt, name.c_str());
     79             return true;
     80         }
     81         return this->INHERITED::onQuery(evt);
     82     }
     83 
     84     virtual bool onEvent(const SkEvent& evt) SK_OVERRIDE {
     85         if (evt.isType("PictFileView::toggleBBox")) {
     86             fBBox = (BBoxType)((fBBox + 1) % kBBoxTypeCount);
     87             return true;
     88         }
     89         return this->INHERITED::onEvent(evt);
     90     }
     91 
     92     virtual void onDrawContent(SkCanvas* canvas) SK_OVERRIDE {
     93         SkASSERT(static_cast<int>(fBBox) < kBBoxTypeCount);
     94         SkPicture** picture = fPictures + fBBox;
     95 
     96         if (!*picture) {
     97             *picture = LoadPicture(fFilename.c_str(), fBBox);
     98         }
     99         if (*picture) {
    100             canvas->drawPicture(*picture);
    101         }
    102     }
    103 
    104 private:
    105     enum BBoxType {
    106         kNo_BBoxType,
    107         kRTree_BBoxType,
    108         kTileGrid_BBoxType,
    109 
    110         kLast_BBoxType = kTileGrid_BBoxType
    111     };
    112     static const int kBBoxTypeCount = kLast_BBoxType + 1;
    113 
    114     SkString    fFilename;
    115     SkPicture*  fPictures[kBBoxTypeCount];
    116     BBoxType    fBBox;
    117     SkSize      fTileSize;
    118 
    119     SkPicture* LoadPicture(const char path[], BBoxType bbox) {
    120         SkAutoTUnref<SkPicture> pic;
    121 
    122         SkBitmap bm;
    123         if (SkImageDecoder::DecodeFile(path, &bm)) {
    124             bm.setImmutable();
    125             SkPictureRecorder recorder;
    126             SkCanvas* can = recorder.beginRecording(SkIntToScalar(bm.width()),
    127                                                     SkIntToScalar(bm.height()),
    128                                                     NULL, 0);
    129             can->drawBitmap(bm, 0, 0, NULL);
    130             pic.reset(recorder.endRecording());
    131         } else {
    132             SkFILEStream stream(path);
    133             if (stream.isValid()) {
    134                 pic.reset(SkPicture::CreateFromStream(&stream));
    135             } else {
    136                 SkDebugf("coun't load picture at \"path\"\n", path);
    137             }
    138 
    139             if (false) {
    140                 SkSurface* surf = SkSurface::NewRasterPMColor(SkScalarCeilToInt(pic->cullRect().width()),
    141                                                               SkScalarCeilToInt(pic->cullRect().height()));
    142                 surf->getCanvas()->drawPicture(pic);
    143                 surf->unref();
    144             }
    145             if (false) { // re-record
    146                 SkPictureRecorder recorder;
    147                 pic->playback(recorder.beginRecording(pic->cullRect().width(),
    148                                                       pic->cullRect().height(),
    149                                                       NULL, 0));
    150                 SkAutoTUnref<SkPicture> p2(recorder.endRecording());
    151 
    152                 SkString path2(path);
    153                 path2.append(".new.skp");
    154                 SkFILEWStream writer(path2.c_str());
    155                 p2->serialize(&writer);
    156             }
    157         }
    158 
    159         if (NULL == pic) {
    160             return NULL;
    161         }
    162 
    163         SkAutoTDelete<SkBBHFactory> factory;
    164         switch (bbox) {
    165         case kNo_BBoxType:
    166             // no bbox playback necessary
    167             return pic.detach();
    168         case kRTree_BBoxType:
    169             factory.reset(SkNEW(SkRTreeFactory));
    170             break;
    171         case kTileGrid_BBoxType: {
    172             SkASSERT(!fTileSize.isEmpty());
    173             SkTileGridFactory::TileGridInfo gridInfo;
    174             gridInfo.fMargin = SkISize::Make(0, 0);
    175             gridInfo.fOffset = SkIPoint::Make(0, 0);
    176             gridInfo.fTileInterval = fTileSize.toRound();
    177             factory.reset(SkNEW_ARGS(SkTileGridFactory, (gridInfo)));
    178             break;
    179         }
    180         default:
    181             SkASSERT(false);
    182         }
    183 
    184         SkPictureRecorder recorder;
    185         pic->playback(recorder.beginRecording(pic->cullRect().width(),
    186                                               pic->cullRect().height(),
    187                                               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