blob: 4ba4f39ed4f0e085d2f84bcf2071efaf004408b9 [file] [log] [blame]
reed@google.com1830c7a2012-06-04 12:05:43 +00001/*
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 */
reed@google.combf0001d2014-01-13 14:53:55 +00007
reed@google.com1830c7a2012-06-04 12:05:43 +00008#include "SampleCode.h"
9#include "SkDumpCanvas.h"
10#include "SkView.h"
11#include "SkCanvas.h"
reed@google.com1830c7a2012-06-04 12:05:43 +000012#include "SkGradientShader.h"
13#include "SkGraphics.h"
14#include "SkImageDecoder.h"
djsollen@google.com796763e2012-12-10 14:12:55 +000015#include "SkOSFile.h"
reed@google.com1830c7a2012-06-04 12:05:43 +000016#include "SkPath.h"
17#include "SkPicture.h"
robertphillips@google.com770963f2014-04-18 18:04:41 +000018#include "SkPictureRecorder.h"
reed@google.com1830c7a2012-06-04 12:05:43 +000019#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"
reed@google.com636d87a2013-09-17 20:03:43 +000030#include "SkSurface.h"
reed@google.com1830c7a2012-06-04 12:05:43 +000031#include "SkXMLParser.h"
32
reed40dab982015-01-28 13:28:53 -080033#include "SkGlyphCache.h"
34
reed093b4e82015-08-04 18:46:38 -070035#include "SkDrawFilter.h"
36class SkCounterDrawFilter : public SkDrawFilter {
37public:
38 SkCounterDrawFilter(int count) : fCount(count) {}
39
40 bool filter(SkPaint*, Type t) override {
41 return --fCount >= 0;
42 }
43
44 int fCount;
45};
46
reed@google.com1830c7a2012-06-04 12:05:43 +000047class PictFileView : public SampleView {
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +000048public:
halcanary96fcdcc2015-08-27 07:41:13 -070049 PictFileView(const char name[] = nullptr)
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +000050 : fFilename(name)
51 , fBBox(kNo_BBoxType)
52 , fTileSize(SkSize::Make(0, 0)) {
fmalita@google.com9a65e2c2013-12-10 22:25:53 +000053 for (int i = 0; i < kBBoxTypeCount; ++i) {
halcanary96fcdcc2015-08-27 07:41:13 -070054 fPictures[i] = nullptr;
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +000055 }
reed093b4e82015-08-04 18:46:38 -070056 fCount = 0;
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +000057 }
rmistry@google.comae933ce2012-08-23 18:19:56 +000058
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +000059 virtual ~PictFileView() {
fmalita@google.com9a65e2c2013-12-10 22:25:53 +000060 for (int i = 0; i < kBBoxTypeCount; ++i) {
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +000061 SkSafeUnref(fPictures[i]);
62 }
63 }
64
mtklein36352bf2015-03-25 18:17:31 -070065 void onTileSizeChanged(const SkSize &tileSize) override {
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +000066 if (tileSize != fTileSize) {
67 fTileSize = tileSize;
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +000068 }
69 }
70
71protected:
72 // overrides from SkEventSink
mtklein36352bf2015-03-25 18:17:31 -070073 bool onQuery(SkEvent* evt) override {
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +000074 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());
commit-bot@chromium.orgc22d1392014-02-03 18:08:33 +000078 switch (fBBox) {
79 case kNo_BBoxType:
80 // No name appended
81 break;
82 case kRTree_BBoxType:
83 name.append(" <bbox: R>");
84 break;
commit-bot@chromium.orgc22d1392014-02-03 18:08:33 +000085 default:
86 SkASSERT(false);
87 break;
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +000088 }
89 SampleCode::TitleR(evt, name.c_str());
90 return true;
91 }
reed093b4e82015-08-04 18:46:38 -070092 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 }
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +0000101 return this->INHERITED::onQuery(evt);
102 }
103
mtklein36352bf2015-03-25 18:17:31 -0700104 bool onEvent(const SkEvent& evt) override {
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +0000105 if (evt.isType("PictFileView::toggleBBox")) {
106 fBBox = (BBoxType)((fBBox + 1) % kBBoxTypeCount);
107 return true;
108 }
109 return this->INHERITED::onEvent(evt);
110 }
111
mtklein36352bf2015-03-25 18:17:31 -0700112 void onDrawContent(SkCanvas* canvas) override {
commit-bot@chromium.org8c6f4b32014-02-03 19:40:32 +0000113 SkASSERT(static_cast<int>(fBBox) < kBBoxTypeCount);
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +0000114 SkPicture** picture = fPictures + fBBox;
115
reed40dab982015-01-28 13:28:53 -0800116#ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
117 SkGraphics::PurgeFontCache();
118#endif
119
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +0000120 if (!*picture) {
121 *picture = LoadPicture(fFilename.c_str(), fBBox);
122 }
123 if (*picture) {
reed093b4e82015-08-04 18:46:38 -0700124 SkCounterDrawFilter filter(fCount);
125 if (fCount > 0) {
126 canvas->setDrawFilter(&filter);
127 }
robertphillips9b14f262014-06-04 05:40:44 -0700128 canvas->drawPicture(*picture);
halcanary96fcdcc2015-08-27 07:41:13 -0700129 canvas->setDrawFilter(nullptr);
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +0000130 }
reed40dab982015-01-28 13:28:53 -0800131
132#ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
133 SkGlyphCache::Dump();
134 SkDebugf("\n");
135#endif
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +0000136 }
137
138private:
139 enum BBoxType {
140 kNo_BBoxType,
141 kRTree_BBoxType,
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +0000142
mtklein703dd2e2015-01-09 06:41:48 -0800143 kLast_BBoxType = kRTree_BBoxType,
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +0000144 };
fmalita@google.come6a98d42013-12-10 22:12:40 +0000145 static const int kBBoxTypeCount = kLast_BBoxType + 1;
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +0000146
147 SkString fFilename;
148 SkPicture* fPictures[kBBoxTypeCount];
149 BBoxType fBBox;
150 SkSize fTileSize;
reed093b4e82015-08-04 18:46:38 -0700151 int fCount;
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +0000152
153 SkPicture* LoadPicture(const char path[], BBoxType bbox) {
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000154 SkAutoTUnref<SkPicture> pic;
reed@google.comb1963742012-08-03 13:39:57 +0000155
156 SkBitmap bm;
157 if (SkImageDecoder::DecodeFile(path, &bm)) {
158 bm.setImmutable();
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000159 SkPictureRecorder recorder;
mtklein703dd2e2015-01-09 06:41:48 -0800160 SkCanvas* can = recorder.beginRecording(SkIntToScalar(bm.width()),
161 SkIntToScalar(bm.height()),
halcanary96fcdcc2015-08-27 07:41:13 -0700162 nullptr, 0);
163 can->drawBitmap(bm, 0, 0, nullptr);
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000164 pic.reset(recorder.endRecording());
reed@google.comb1963742012-08-03 13:39:57 +0000165 } else {
166 SkFILEStream stream(path);
167 if (stream.isValid()) {
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000168 pic.reset(SkPicture::CreateFromStream(&stream));
reed@google.comb8b830e2013-06-25 20:42:37 +0000169 } else {
170 SkDebugf("coun't load picture at \"path\"\n", path);
reed@google.comb1963742012-08-03 13:39:57 +0000171 }
skia.committer@gmail.com11f86922012-08-31 17:14:46 +0000172
reed@google.com0a5c18b2012-08-31 13:32:47 +0000173 if (false) { // re-record
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000174 SkPictureRecorder recorder;
robertphillipsc5ba71d2014-09-04 08:42:50 -0700175 pic->playback(recorder.beginRecording(pic->cullRect().width(),
mtklein703dd2e2015-01-09 06:41:48 -0800176 pic->cullRect().height(),
halcanary96fcdcc2015-08-27 07:41:13 -0700177 nullptr, 0));
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000178 SkAutoTUnref<SkPicture> p2(recorder.endRecording());
skia.committer@gmail.com11f86922012-08-31 17:14:46 +0000179
reed@google.com0a5c18b2012-08-31 13:32:47 +0000180 SkString path2(path);
181 path2.append(".new.skp");
182 SkFILEWStream writer(path2.c_str());
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000183 p2->serialize(&writer);
reed@google.com0a5c18b2012-08-31 13:32:47 +0000184 }
reed@google.comb1963742012-08-03 13:39:57 +0000185 }
djsollen@google.com796763e2012-12-10 14:12:55 +0000186
halcanary96fcdcc2015-08-27 07:41:13 -0700187 if (nullptr == pic) {
188 return nullptr;
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +0000189 }
190
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000191 SkAutoTDelete<SkBBHFactory> factory;
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +0000192 switch (bbox) {
193 case kNo_BBoxType:
194 // no bbox playback necessary
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000195 return pic.detach();
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +0000196 case kRTree_BBoxType:
halcanary385fe4d2015-08-26 13:07:48 -0700197 factory.reset(new SkRTreeFactory);
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +0000198 break;
commit-bot@chromium.orgbbe43a92013-12-10 21:51:06 +0000199 default:
200 SkASSERT(false);
201 }
202
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000203 SkPictureRecorder recorder;
robertphillipsc5ba71d2014-09-04 08:42:50 -0700204 pic->playback(recorder.beginRecording(pic->cullRect().width(),
mtklein703dd2e2015-01-09 06:41:48 -0800205 pic->cullRect().height(),
robertphillipsc5ba71d2014-09-04 08:42:50 -0700206 factory.get(), 0));
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000207 return recorder.endRecording();
reed@google.comb1963742012-08-03 13:39:57 +0000208 }
209
reed@google.com1830c7a2012-06-04 12:05:43 +0000210 typedef SampleView INHERITED;
211};
212
213SampleView* CreateSamplePictFileView(const char filename[]);
214SampleView* CreateSamplePictFileView(const char filename[]) {
215 return new PictFileView(filename);
216}
217
218//////////////////////////////////////////////////////////////////////////////
219
220#if 0
221static SkView* MyFactory() { return new PictFileView; }
222static SkViewRegister reg(MyFactory);
223#endif