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