| /* | |
| * Copyright 2011 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "SampleCode.h" | |
| #include "SkDumpCanvas.h" | |
| #include "SkView.h" | |
| #include "SkCanvas.h" | |
| #include "SkGradientShader.h" | |
| #include "SkGraphics.h" | |
| #include "SkImageDecoder.h" | |
| #include "SkOSFile.h" | |
| #include "SkPath.h" | |
| #include "SkPicture.h" | |
| #include "SkPictureRecorder.h" | |
| #include "SkRandom.h" | |
| #include "SkRegion.h" | |
| #include "SkShader.h" | |
| #include "SkUtils.h" | |
| #include "SkColorPriv.h" | |
| #include "SkColorFilter.h" | |
| #include "SkTime.h" | |
| #include "SkTypeface.h" | |
| #include "SkXfermode.h" | |
| #include "SkStream.h" | |
| #include "SkSurface.h" | |
| #include "SkXMLParser.h" | |
| class PictFileView : public SampleView { | |
| public: | |
| PictFileView(const char name[] = NULL) | |
| : fFilename(name) | |
| , fBBox(kNo_BBoxType) | |
| , fTileSize(SkSize::Make(0, 0)) { | |
| for (int i = 0; i < kBBoxTypeCount; ++i) { | |
| fPictures[i] = NULL; | |
| } | |
| } | |
| virtual ~PictFileView() { | |
| for (int i = 0; i < kBBoxTypeCount; ++i) { | |
| SkSafeUnref(fPictures[i]); | |
| } | |
| } | |
| virtual void onTileSizeChanged(const SkSize &tileSize) SK_OVERRIDE { | |
| if (tileSize != fTileSize) { | |
| fTileSize = tileSize; | |
| SkSafeSetNull(fPictures[kTileGrid_BBoxType]); | |
| } | |
| } | |
| protected: | |
| // overrides from SkEventSink | |
| virtual bool onQuery(SkEvent* evt) SK_OVERRIDE { | |
| if (SampleCode::TitleQ(*evt)) { | |
| SkString name("P:"); | |
| const char* basename = strrchr(fFilename.c_str(), SkPATH_SEPARATOR); | |
| name.append(basename ? basename+1: fFilename.c_str()); | |
| switch (fBBox) { | |
| case kNo_BBoxType: | |
| // No name appended | |
| break; | |
| case kRTree_BBoxType: | |
| name.append(" <bbox: R>"); | |
| break; | |
| case kTileGrid_BBoxType: | |
| name.append(" <bbox: T>"); | |
| break; | |
| default: | |
| SkASSERT(false); | |
| break; | |
| } | |
| SampleCode::TitleR(evt, name.c_str()); | |
| return true; | |
| } | |
| return this->INHERITED::onQuery(evt); | |
| } | |
| virtual bool onEvent(const SkEvent& evt) SK_OVERRIDE { | |
| if (evt.isType("PictFileView::toggleBBox")) { | |
| fBBox = (BBoxType)((fBBox + 1) % kBBoxTypeCount); | |
| return true; | |
| } | |
| return this->INHERITED::onEvent(evt); | |
| } | |
| virtual void onDrawContent(SkCanvas* canvas) SK_OVERRIDE { | |
| SkASSERT(static_cast<int>(fBBox) < kBBoxTypeCount); | |
| SkPicture** picture = fPictures + fBBox; | |
| if (!*picture) { | |
| *picture = LoadPicture(fFilename.c_str(), fBBox); | |
| } | |
| if (*picture) { | |
| canvas->drawPicture(*picture); | |
| } | |
| } | |
| private: | |
| enum BBoxType { | |
| kNo_BBoxType, | |
| kRTree_BBoxType, | |
| kTileGrid_BBoxType, | |
| kLast_BBoxType = kTileGrid_BBoxType | |
| }; | |
| static const int kBBoxTypeCount = kLast_BBoxType + 1; | |
| SkString fFilename; | |
| SkPicture* fPictures[kBBoxTypeCount]; | |
| BBoxType fBBox; | |
| SkSize fTileSize; | |
| SkPicture* LoadPicture(const char path[], BBoxType bbox) { | |
| SkAutoTUnref<SkPicture> pic; | |
| SkBitmap bm; | |
| if (SkImageDecoder::DecodeFile(path, &bm)) { | |
| bm.setImmutable(); | |
| SkPictureRecorder recorder; | |
| SkCanvas* can = recorder.beginRecording(SkIntToScalar(bm.width()), | |
| SkIntToScalar(bm.height()), | |
| NULL, 0); | |
| can->drawBitmap(bm, 0, 0, NULL); | |
| pic.reset(recorder.endRecording()); | |
| } else { | |
| SkFILEStream stream(path); | |
| if (stream.isValid()) { | |
| pic.reset(SkPicture::CreateFromStream(&stream)); | |
| } else { | |
| SkDebugf("coun't load picture at \"path\"\n", path); | |
| } | |
| if (false) { | |
| SkSurface* surf = SkSurface::NewRasterPMColor(SkScalarCeilToInt(pic->cullRect().width()), | |
| SkScalarCeilToInt(pic->cullRect().height())); | |
| surf->getCanvas()->drawPicture(pic); | |
| surf->unref(); | |
| } | |
| if (false) { // re-record | |
| SkPictureRecorder recorder; | |
| pic->playback(recorder.beginRecording(pic->cullRect().width(), | |
| pic->cullRect().height(), | |
| NULL, 0)); | |
| SkAutoTUnref<SkPicture> p2(recorder.endRecording()); | |
| SkString path2(path); | |
| path2.append(".new.skp"); | |
| SkFILEWStream writer(path2.c_str()); | |
| p2->serialize(&writer); | |
| } | |
| } | |
| if (NULL == pic) { | |
| return NULL; | |
| } | |
| SkAutoTDelete<SkBBHFactory> factory; | |
| switch (bbox) { | |
| case kNo_BBoxType: | |
| // no bbox playback necessary | |
| return pic.detach(); | |
| case kRTree_BBoxType: | |
| factory.reset(SkNEW(SkRTreeFactory)); | |
| break; | |
| case kTileGrid_BBoxType: { | |
| SkASSERT(!fTileSize.isEmpty()); | |
| SkTileGridFactory::TileGridInfo gridInfo; | |
| gridInfo.fMargin = SkISize::Make(0, 0); | |
| gridInfo.fOffset = SkIPoint::Make(0, 0); | |
| gridInfo.fTileInterval = fTileSize.toRound(); | |
| factory.reset(SkNEW_ARGS(SkTileGridFactory, (gridInfo))); | |
| break; | |
| } | |
| default: | |
| SkASSERT(false); | |
| } | |
| SkPictureRecorder recorder; | |
| pic->playback(recorder.beginRecording(pic->cullRect().width(), | |
| pic->cullRect().height(), | |
| factory.get(), 0)); | |
| return recorder.endRecording(); | |
| } | |
| typedef SampleView INHERITED; | |
| }; | |
| SampleView* CreateSamplePictFileView(const char filename[]); | |
| SampleView* CreateSamplePictFileView(const char filename[]) { | |
| return new PictFileView(filename); | |
| } | |
| ////////////////////////////////////////////////////////////////////////////// | |
| #if 0 | |
| static SkView* MyFactory() { return new PictFileView; } | |
| static SkViewRegister reg(MyFactory); | |
| #endif |