• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
PictFileView(const char name[]=NULL)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 
~PictFileView()44     virtual ~PictFileView() {
45         for (int i = 0; i < kBBoxTypeCount; ++i) {
46             SkSafeUnref(fPictures[i]);
47         }
48     }
49 
onTileSizeChanged(const SkSize & tileSize)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
onQuery(SkEvent * evt)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 
onEvent(const SkEvent & evt)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 
onDrawContent(SkCanvas * canvas)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 
LoadPicture(const char path[],BBoxType bbox)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[]);
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