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