• 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 #include "SkGlyphCache.h"
34 
35 #include "SkDrawFilter.h"
36 class SkCounterDrawFilter : public SkDrawFilter {
37 public:
SkCounterDrawFilter(int count)38     SkCounterDrawFilter(int count) : fCount(count) {}
39 
filter(SkPaint *,Type t)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:
PictFileView(const char name[]=nullptr)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 
~PictFileView()59     virtual ~PictFileView() {
60         for (int i = 0; i < kBBoxTypeCount; ++i) {
61             SkSafeUnref(fPictures[i]);
62         }
63     }
64 
onTileSizeChanged(const SkSize & tileSize)65     void onTileSizeChanged(const SkSize &tileSize) override {
66         if (tileSize != fTileSize) {
67             fTileSize = tileSize;
68         }
69     }
70 
71 protected:
72     // overrides from SkEventSink
onQuery(SkEvent * evt)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 
onEvent(const SkEvent & evt)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 
onDrawContent(SkCanvas * canvas)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 
LoadPicture(const char path[],BBoxType bbox)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[]);
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