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 #include "SkGlyphCache.h"
     34 
     35 class PictFileView : public SampleView {
     36 public:
     37     PictFileView(const char name[] = NULL)
     38         : fFilename(name)
     39         , fBBox(kNo_BBoxType)
     40         , fTileSize(SkSize::Make(0, 0)) {
     41         for (int i = 0; i < kBBoxTypeCount; ++i) {
     42             fPictures[i] = NULL;
     43         }
     44     }
     45 
     46     virtual ~PictFileView() {
     47         for (int i = 0; i < kBBoxTypeCount; ++i) {
     48             SkSafeUnref(fPictures[i]);
     49         }
     50     }
     51 
     52     void onTileSizeChanged(const SkSize &tileSize) override {
     53         if (tileSize != fTileSize) {
     54             fTileSize = tileSize;
     55         }
     56     }
     57 
     58 protected:
     59     // overrides from SkEventSink
     60     bool onQuery(SkEvent* evt) override {
     61         if (SampleCode::TitleQ(*evt)) {
     62             SkString name("P:");
     63             const char* basename = strrchr(fFilename.c_str(), SkPATH_SEPARATOR);
     64             name.append(basename ? basename+1: fFilename.c_str());
     65             switch (fBBox) {
     66             case kNo_BBoxType:
     67                 // No name appended
     68                 break;
     69             case kRTree_BBoxType:
     70                 name.append(" <bbox: R>");
     71                 break;
     72             default:
     73                 SkASSERT(false);
     74                 break;
     75             }
     76             SampleCode::TitleR(evt, name.c_str());
     77             return true;
     78         }
     79         return this->INHERITED::onQuery(evt);
     80     }
     81 
     82     bool onEvent(const SkEvent& evt) override {
     83         if (evt.isType("PictFileView::toggleBBox")) {
     84             fBBox = (BBoxType)((fBBox + 1) % kBBoxTypeCount);
     85             return true;
     86         }
     87         return this->INHERITED::onEvent(evt);
     88     }
     89 
     90     void onDrawContent(SkCanvas* canvas) override {
     91         SkASSERT(static_cast<int>(fBBox) < kBBoxTypeCount);
     92         SkPicture** picture = fPictures + fBBox;
     93 
     94 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
     95         SkGraphics::PurgeFontCache();
     96 #endif
     97 
     98         if (!*picture) {
     99             *picture = LoadPicture(fFilename.c_str(), fBBox);
    100         }
    101         if (*picture) {
    102             canvas->drawPicture(*picture);
    103         }
    104 
    105 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
    106         SkGlyphCache::Dump();
    107         SkDebugf("\n");
    108 #endif
    109     }
    110 
    111 private:
    112     enum BBoxType {
    113         kNo_BBoxType,
    114         kRTree_BBoxType,
    115 
    116         kLast_BBoxType = kRTree_BBoxType,
    117     };
    118     static const int kBBoxTypeCount = kLast_BBoxType + 1;
    119 
    120     SkString    fFilename;
    121     SkPicture*  fPictures[kBBoxTypeCount];
    122     BBoxType    fBBox;
    123     SkSize      fTileSize;
    124 
    125     SkPicture* LoadPicture(const char path[], BBoxType bbox) {
    126         SkAutoTUnref<SkPicture> pic;
    127 
    128         SkBitmap bm;
    129         if (SkImageDecoder::DecodeFile(path, &bm)) {
    130             bm.setImmutable();
    131             SkPictureRecorder recorder;
    132             SkCanvas* can = recorder.beginRecording(SkIntToScalar(bm.width()),
    133                                                     SkIntToScalar(bm.height()),
    134                                                     NULL, 0);
    135             can->drawBitmap(bm, 0, 0, NULL);
    136             pic.reset(recorder.endRecording());
    137         } else {
    138             SkFILEStream stream(path);
    139             if (stream.isValid()) {
    140                 pic.reset(SkPicture::CreateFromStream(&stream));
    141             } else {
    142                 SkDebugf("coun't load picture at \"path\"\n", path);
    143             }
    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         default:
    172             SkASSERT(false);
    173         }
    174 
    175         SkPictureRecorder recorder;
    176         pic->playback(recorder.beginRecording(pic->cullRect().width(),
    177                                               pic->cullRect().height(),
    178                                               factory.get(), 0));
    179         return recorder.endRecording();
    180     }
    181 
    182     typedef SampleView INHERITED;
    183 };
    184 
    185 SampleView* CreateSamplePictFileView(const char filename[]);
    186 SampleView* CreateSamplePictFileView(const char filename[]) {
    187     return new PictFileView(filename);
    188 }
    189 
    190 //////////////////////////////////////////////////////////////////////////////
    191 
    192 #if 0
    193 static SkView* MyFactory() { return new PictFileView; }
    194 static SkViewRegister reg(MyFactory);
    195 #endif
    196