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 #include "SkDrawFilter.h"
     36 class SkCounterDrawFilter : public SkDrawFilter {
     37 public:
     38     SkCounterDrawFilter(int count) : fCount(count) {}
     39 
     40     bool filter(SkPaint*, Type t) override {
     41         return --fCount >= 0;
     42     }
     43 
     44     int fCount;
     45 };
     46 
     47 class PictFileView : public SampleView {
     48 public:
     49     PictFileView(const char name[] = nullptr)
     50         : fFilename(name)
     51         , fBBox(kNo_BBoxType)
     52         , fTileSize(SkSize::Make(0, 0)) {
     53         for (int i = 0; i < kBBoxTypeCount; ++i) {
     54             fPictures[i] = nullptr;
     55         }
     56         fCount = 0;
     57     }
     58 
     59     virtual ~PictFileView() {
     60         for (int i = 0; i < kBBoxTypeCount; ++i) {
     61             SkSafeUnref(fPictures[i]);
     62         }
     63     }
     64 
     65     void onTileSizeChanged(const SkSize &tileSize) override {
     66         if (tileSize != fTileSize) {
     67             fTileSize = tileSize;
     68         }
     69     }
     70 
     71 protected:
     72     // overrides from SkEventSink
     73     bool onQuery(SkEvent* evt) override {
     74         if (SampleCode::TitleQ(*evt)) {
     75             SkString name("P:");
     76             const char* basename = strrchr(fFilename.c_str(), SkPATH_SEPARATOR);
     77             name.append(basename ? basename+1: fFilename.c_str());
     78             switch (fBBox) {
     79             case kNo_BBoxType:
     80                 // No name appended
     81                 break;
     82             case kRTree_BBoxType:
     83                 name.append(" <bbox: R>");
     84                 break;
     85             default:
     86                 SkASSERT(false);
     87                 break;
     88             }
     89             SampleCode::TitleR(evt, name.c_str());
     90             return true;
     91         }
     92         SkUnichar uni;
     93         if (SampleCode::CharQ(*evt, &uni)) {
     94             switch (uni) {
     95                 case 'n': fCount += 1; this->inval(nullptr); return true;
     96                 case 'p': fCount -= 1; this->inval(nullptr); return true;
     97                 case 's': fCount =  0; this->inval(nullptr); return true;
     98                 default: break;
     99             }
    100         }
    101         return this->INHERITED::onQuery(evt);
    102     }
    103 
    104     bool onEvent(const SkEvent& evt) override {
    105         if (evt.isType("PictFileView::toggleBBox")) {
    106             fBBox = (BBoxType)((fBBox + 1) % kBBoxTypeCount);
    107             return true;
    108         }
    109         return this->INHERITED::onEvent(evt);
    110     }
    111 
    112     void onDrawContent(SkCanvas* canvas) override {
    113         SkASSERT(static_cast<int>(fBBox) < kBBoxTypeCount);
    114         SkPicture** picture = fPictures + fBBox;
    115 
    116 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
    117         SkGraphics::PurgeFontCache();
    118 #endif
    119 
    120         if (!*picture) {
    121             *picture = LoadPicture(fFilename.c_str(), fBBox);
    122         }
    123         if (*picture) {
    124             SkCounterDrawFilter filter(fCount);
    125             if (fCount > 0) {
    126                 canvas->setDrawFilter(&filter);
    127             }
    128             canvas->drawPicture(*picture);
    129             canvas->setDrawFilter(nullptr);
    130         }
    131 
    132 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
    133         SkGlyphCache::Dump();
    134         SkDebugf("\n");
    135 #endif
    136     }
    137 
    138 private:
    139     enum BBoxType {
    140         kNo_BBoxType,
    141         kRTree_BBoxType,
    142 
    143         kLast_BBoxType = kRTree_BBoxType,
    144     };
    145     static const int kBBoxTypeCount = kLast_BBoxType + 1;
    146 
    147     SkString    fFilename;
    148     SkPicture*  fPictures[kBBoxTypeCount];
    149     BBoxType    fBBox;
    150     SkSize      fTileSize;
    151     int         fCount;
    152 
    153     SkPicture* LoadPicture(const char path[], BBoxType bbox) {
    154         SkAutoTUnref<SkPicture> pic;
    155 
    156         SkBitmap bm;
    157         if (SkImageDecoder::DecodeFile(path, &bm)) {
    158             bm.setImmutable();
    159             SkPictureRecorder recorder;
    160             SkCanvas* can = recorder.beginRecording(SkIntToScalar(bm.width()),
    161                                                     SkIntToScalar(bm.height()),
    162                                                     nullptr, 0);
    163             can->drawBitmap(bm, 0, 0, nullptr);
    164             pic.reset(recorder.endRecording());
    165         } else {
    166             SkFILEStream stream(path);
    167             if (stream.isValid()) {
    168                 pic.reset(SkPicture::CreateFromStream(&stream));
    169             } else {
    170                 SkDebugf("coun't load picture at \"path\"\n", path);
    171             }
    172 
    173             if (false) { // re-record
    174                 SkPictureRecorder recorder;
    175                 pic->playback(recorder.beginRecording(pic->cullRect().width(),
    176                                                       pic->cullRect().height(),
    177                                                       nullptr, 0));
    178                 SkAutoTUnref<SkPicture> p2(recorder.endRecording());
    179 
    180                 SkString path2(path);
    181                 path2.append(".new.skp");
    182                 SkFILEWStream writer(path2.c_str());
    183                 p2->serialize(&writer);
    184             }
    185         }
    186 
    187         if (nullptr == pic) {
    188             return nullptr;
    189         }
    190 
    191         SkAutoTDelete<SkBBHFactory> factory;
    192         switch (bbox) {
    193         case kNo_BBoxType:
    194             // no bbox playback necessary
    195             return pic.detach();
    196         case kRTree_BBoxType:
    197             factory.reset(new SkRTreeFactory);
    198             break;
    199         default:
    200             SkASSERT(false);
    201         }
    202 
    203         SkPictureRecorder recorder;
    204         pic->playback(recorder.beginRecording(pic->cullRect().width(),
    205                                               pic->cullRect().height(),
    206                                               factory.get(), 0));
    207         return recorder.endRecording();
    208     }
    209 
    210     typedef SampleView INHERITED;
    211 };
    212 
    213 SampleView* CreateSamplePictFileView(const char filename[]);
    214 SampleView* CreateSamplePictFileView(const char filename[]) {
    215     return new PictFileView(filename);
    216 }
    217 
    218 //////////////////////////////////////////////////////////////////////////////
    219 
    220 #if 0
    221 static SkView* MyFactory() { return new PictFileView; }
    222 static SkViewRegister reg(MyFactory);
    223 #endif
    224