Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: printing/pdf_metafile_skia.cc

Issue 2653963002: [Experimental] Supporting OOPIF printing
Patch Set: Rename service, fix for webview, and connect to DiscardableMemoryManager Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « printing/pdf_metafile_skia.h ('k') | services/pdf_compositor/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "printing/pdf_metafile_skia.h" 5 #include "printing/pdf_metafile_skia.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/files/file.h" 12 #include "base/files/file.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/time/time.h" 14 #include "base/time/time.h"
15 #include "printing/print_settings.h" 15 #include "printing/print_settings.h"
16 #include "skia/ext/skia_utils_base.h"
16 #include "third_party/skia/include/core/SkDocument.h" 17 #include "third_party/skia/include/core/SkDocument.h"
18 #include "third_party/skia/include/core/SkImageDeserializer.h"
17 #include "third_party/skia/include/core/SkPictureRecorder.h" 19 #include "third_party/skia/include/core/SkPictureRecorder.h"
18 #include "third_party/skia/include/core/SkStream.h" 20 #include "third_party/skia/include/core/SkStream.h"
21 //#include "third_party/skia/include/core/SkWriteBuffer.h"
19 // Note that headers in third_party/skia/src are fragile. This is 22 // Note that headers in third_party/skia/src are fragile. This is
20 // an experimental, fragile, and diagnostic-only document type. 23 // an experimental, fragile, and diagnostic-only document type.
21 #include "third_party/skia/src/utils/SkMultiPictureDocument.h" 24 #include "third_party/skia/src/utils/SkMultiPictureDocument.h"
22 #include "ui/gfx/geometry/safe_integer_conversions.h" 25 #include "ui/gfx/geometry/safe_integer_conversions.h"
23 #include "ui/gfx/skia_util.h" 26 #include "ui/gfx/skia_util.h"
24 27
25 #if defined(OS_MACOSX) 28 #if defined(OS_MACOSX)
26 #include "printing/pdf_metafile_cg_mac.h" 29 #include "printing/pdf_metafile_cg_mac.h"
27 #endif 30 #endif
28 31
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 : SkString(agent.c_str(), agent.size()); 73 : SkString(agent.c_str(), agent.size());
71 return SkDocument::MakePDF(wStream, SK_ScalarDefaultRasterDPI, metadata, 74 return SkDocument::MakePDF(wStream, SK_ScalarDefaultRasterDPI, metadata,
72 nullptr, false); 75 nullptr, false);
73 } 76 }
74 77
75 } // namespace 78 } // namespace
76 79
77 namespace printing { 80 namespace printing {
78 81
79 struct Page { 82 struct Page {
80 Page(SkSize s, sk_sp<SkPicture> c) : size_(s), content_(std::move(c)) {} 83 Page(SkSize s, sk_sp<SkDrawable> c) : size_(s), content_(std::move(c)) {}
81 Page(Page&& that) : size_(that.size_), content_(std::move(that.content_)) {} 84 Page(Page&& that) : size_(that.size_), content_(std::move(that.content_)) {}
82 Page(const Page&) = default; 85 Page(const Page&) = default;
83 Page& operator=(const Page&) = default; 86 Page& operator=(const Page&) = default;
84 Page& operator=(Page&& that) { 87 Page& operator=(Page&& that) {
85 size_ = that.size_; 88 size_ = that.size_;
86 content_ = std::move(that.content_); 89 content_ = std::move(that.content_);
87 return *this; 90 return *this;
88 } 91 }
89 SkSize size_; 92 SkSize size_;
90 sk_sp<SkPicture> content_; 93 sk_sp<SkDrawable> content_;
91 }; 94 };
92 95
93 struct PdfMetafileSkiaData { 96 struct PdfMetafileSkiaData {
94 SkPictureRecorder recorder_; // Current recording 97 SkPictureRecorder recorder_; // Current recording
95 98
96 std::vector<Page> pages_; 99 std::vector<Page> pages_;
97 std::unique_ptr<SkStreamAsset> pdf_data_; 100 std::unique_ptr<SkStreamAsset> pdf_data_;
98 101
99 // The scale factor is used because Blink occasionally calls 102 // The scale factor is used because Blink occasionally calls
100 // SkCanvas::getTotalMatrix() even though the total matrix is not as 103 // SkCanvas::getTotalMatrix() even though the total matrix is not as
(...skipping 16 matching lines...) Expand all
117 // TODO(halcanary): Create a Metafile class that only stores data. 120 // TODO(halcanary): Create a Metafile class that only stores data.
118 // Metafile::InitFromData is orthogonal to what the rest of 121 // Metafile::InitFromData is orthogonal to what the rest of
119 // PdfMetafileSkia does. 122 // PdfMetafileSkia does.
120 bool PdfMetafileSkia::InitFromData(const void* src_buffer, 123 bool PdfMetafileSkia::InitFromData(const void* src_buffer,
121 size_t src_buffer_size) { 124 size_t src_buffer_size) {
122 data_->pdf_data_ = base::MakeUnique<SkMemoryStream>( 125 data_->pdf_data_ = base::MakeUnique<SkMemoryStream>(
123 src_buffer, src_buffer_size, true /* copy_data? */); 126 src_buffer, src_buffer_size, true /* copy_data? */);
124 return true; 127 return true;
125 } 128 }
126 129
130 bool PdfMetafileSkia::InitFromPageDataBuffer(const char* src_buffer,
131 size_t src_buffer_size) {
132 size_t pos = 0;
133 while (pos < src_buffer_size) {
134 size_t size = *((size_t*)(src_buffer + pos));
135 pos += sizeof(size_t);
136 if (pos + size + 2 * sizeof(SkScalar) > src_buffer_size) {
137 return false;
138 }
139 SkScalar width = *((SkScalar*)(src_buffer + pos));
140 pos += sizeof(SkScalar);
141 SkScalar height = *((SkScalar*)(src_buffer + pos));
142 pos += sizeof(SkScalar);
143
144 std::unique_ptr<SkDrawable> d = skia::ReadDrawable(src_buffer + pos, size);
145
146 data_->pages_.emplace_back(SkSize::Make(width, height),
147 sk_sp<SkDrawable>(d.release()));
148 pos += size;
149 }
150 return true;
151 }
152
127 void PdfMetafileSkia::StartPage(const gfx::Size& page_size, 153 void PdfMetafileSkia::StartPage(const gfx::Size& page_size,
128 const gfx::Rect& content_area, 154 const gfx::Rect& content_area,
129 const float& scale_factor) { 155 const float& scale_factor) {
130 DCHECK_GT(page_size.width(), 0); 156 DCHECK_GT(page_size.width(), 0);
131 DCHECK_GT(page_size.height(), 0); 157 DCHECK_GT(page_size.height(), 0);
132 DCHECK_GT(scale_factor, 0.0f); 158 DCHECK_GT(scale_factor, 0.0f);
133 if (data_->recorder_.getRecordingCanvas()) 159 if (data_->recorder_.getRecordingCanvas())
134 FinishPage(); 160 FinishPage();
135 DCHECK(!data_->recorder_.getRecordingCanvas()); 161 DCHECK(!data_->recorder_.getRecordingCanvas());
136 162
(...skipping 22 matching lines...) Expand all
159 const gfx::Rect& content_area, 185 const gfx::Rect& content_area,
160 const float& scale_factor) { 186 const float& scale_factor) {
161 StartPage(page_size, content_area, scale_factor); 187 StartPage(page_size, content_area, scale_factor);
162 return data_->recorder_.getRecordingCanvas(); 188 return data_->recorder_.getRecordingCanvas();
163 } 189 }
164 190
165 bool PdfMetafileSkia::FinishPage() { 191 bool PdfMetafileSkia::FinishPage() {
166 if (!data_->recorder_.getRecordingCanvas()) 192 if (!data_->recorder_.getRecordingCanvas())
167 return false; 193 return false;
168 194
169 sk_sp<SkPicture> pic = data_->recorder_.finishRecordingAsPicture(); 195 sk_sp<SkDrawable> pic = data_->recorder_.finishRecordingAsDrawable();
170 if (data_->scale_factor_ != 1.0f) { 196 if (data_->scale_factor_ != 1.0f) {
171 SkCanvas* canvas = data_->recorder_.beginRecording(data_->size_.width(), 197 SkCanvas* canvas = data_->recorder_.beginRecording(data_->size_.width(),
172 data_->size_.height()); 198 data_->size_.height());
173 canvas->scale(data_->scale_factor_, data_->scale_factor_); 199 canvas->scale(data_->scale_factor_, data_->scale_factor_);
174 canvas->drawPicture(pic); 200 canvas->drawDrawable(pic.get());
175 pic = data_->recorder_.finishRecordingAsPicture(); 201 pic = data_->recorder_.finishRecordingAsDrawable();
176 } 202 }
177 data_->pages_.emplace_back(data_->size_, std::move(pic)); 203 data_->pages_.emplace_back(data_->size_, pic);
178 return true; 204 return true;
179 } 205 }
180 206
207 void PdfMetafileSkia::FinishAllPages() {
208 // If we've already set the data in InitFromData, leave it be.
209 if (data_->pdf_data_) {
210 return;
211 }
212
213 if (data_->recorder_.getRecordingCanvas()) {
214 FinishPage();
215 }
216 }
217
181 bool PdfMetafileSkia::FinishDocument() { 218 bool PdfMetafileSkia::FinishDocument() {
182 // If we've already set the data in InitFromData, leave it be. 219 // If we've already set the data in InitFromData, leave it be.
183 if (data_->pdf_data_) 220 if (data_->pdf_data_)
184 return false; 221 return false;
185 222
186 if (data_->recorder_.getRecordingCanvas()) 223 if (data_->recorder_.getRecordingCanvas())
187 FinishPage(); 224 FinishPage();
188 225
189 SkDynamicMemoryWStream stream; 226 SkDynamicMemoryWStream stream;
190 sk_sp<SkDocument> doc; 227 sk_sp<SkDocument> doc;
191 switch (data_->type_) { 228 switch (data_->type_) {
192 case PDF_SKIA_DOCUMENT_TYPE: 229 case PDF_SKIA_DOCUMENT_TYPE:
193 doc = MakePdfDocument(&stream); 230 doc = MakePdfDocument(&stream);
194 break; 231 break;
195 case MSKP_SKIA_DOCUMENT_TYPE: 232 case MSKP_SKIA_DOCUMENT_TYPE:
196 doc = SkMakeMultiPictureDocument(&stream); 233 doc = SkMakeMultiPictureDocument(&stream);
197 break; 234 break;
198 } 235 }
199 236
200 for (const Page& page : data_->pages_) { 237 for (const Page& page : data_->pages_) {
201 SkCanvas* canvas = doc->beginPage(page.size_.width(), page.size_.height()); 238 SkCanvas* canvas = doc->beginPage(page.size_.width(), page.size_.height());
202 canvas->drawPicture(page.content_); 239 canvas->drawDrawable(page.content_.get());
203 doc->endPage(); 240 doc->endPage();
204 } 241 }
205 doc->close(); 242 doc->close();
206 243
207 data_->pdf_data_.reset(stream.detachAsStream()); 244 data_->pdf_data_.reset(stream.detachAsStream());
208 return true; 245 return true;
209 } 246 }
210 247
248 std::unique_ptr<char[]> PdfMetafileSkia::GetPageDataBuffer(size_t* size) const {
249 struct PageInfo {
250 PageInfo(SkScalar w, SkScalar h, std::vector<char> d)
251 : width(w), height(h), data(std::move(d)) {}
252 SkScalar width;
253 SkScalar height;
254 std::vector<char> data;
255 };
256 std::vector<PageInfo> serialized_pages;
257 size_t total_buf_size = 0;
258 for (size_t i = 0; i < data_->pages_.size(); ++i) {
259 // Flatten each page into buffer.
260 std::vector<char> flattened =
261 skia::WriteDrawable(data_->pages_[i].content_.get());
262 if (!flattened.size() || !flattened.data()) {
263 continue;
264 }
265 total_buf_size += sizeof(size_t) + sizeof(SkScalar) * 2 + flattened.size();
266 serialized_pages.emplace_back(data_->pages_[i].size_.width(),
267 data_->pages_[i].size_.height(),
268 std::move(flattened));
269 }
270 if (!total_buf_size) {
271 *size = 0;
272 return nullptr;
273 }
274 std::unique_ptr<char[]> buf(new char[total_buf_size]);
275 char* buf_pos = buf.get();
276 for (size_t i = 0; i < serialized_pages.size(); ++i) {
277 size_t size = serialized_pages[i].data.size();
278 memcpy(buf_pos, &size, sizeof(size_t));
279 buf_pos += sizeof(size_t);
280 memcpy(buf_pos, &serialized_pages[i].width, sizeof(SkScalar));
281 buf_pos += sizeof(SkScalar);
282 memcpy(buf_pos, &serialized_pages[i].height, sizeof(SkScalar));
283 buf_pos += sizeof(SkScalar);
284 memcpy(buf_pos, serialized_pages[i].data.data(), size);
285 buf_pos += size;
286 }
287 *size = total_buf_size;
288 return buf;
289 }
290
291 void PdfMetafileSkia::GetSkp(SkWStream* stream) const {
292 if (data_->pages_.size() >= 1)
293 data_->pages_[0].content_->newPictureSnapshot()->serialize(stream);
294 }
295
296 void PdfMetafileSkia::ConvertPagesToPdf() {
297 SkDynamicMemoryWStream stream;
298 sk_sp<SkDocument> doc = MakePdfDocument(&stream);
299
300 for (const Page& page : data_->pages_) {
301 SkCanvas* canvas = doc->beginPage(page.size_.width(), page.size_.height());
302 canvas->drawPicture(page.content_->newPictureSnapshot());
303 doc->endPage();
304 }
305 doc->close();
306
307 data_->pdf_data_.reset(stream.detachAsStream());
308 }
309
211 uint32_t PdfMetafileSkia::GetDataSize() const { 310 uint32_t PdfMetafileSkia::GetDataSize() const {
212 if (!data_->pdf_data_) 311 if (!data_->pdf_data_)
213 return 0; 312 return 0;
214 return base::checked_cast<uint32_t>(data_->pdf_data_->getLength()); 313 return base::checked_cast<uint32_t>(data_->pdf_data_->getLength());
215 } 314 }
216 315
217 bool PdfMetafileSkia::GetData(void* dst_buffer, 316 bool PdfMetafileSkia::GetData(void* dst_buffer,
218 uint32_t dst_buffer_size) const { 317 uint32_t dst_buffer_size) const {
219 if (!data_->pdf_data_) 318 if (!data_->pdf_data_)
220 return false; 319 return false;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 std::unique_ptr<PdfMetafileSkia> metafile(new PdfMetafileSkia(type)); 412 std::unique_ptr<PdfMetafileSkia> metafile(new PdfMetafileSkia(type));
314 413
315 if (data_->pages_.size() == 0) 414 if (data_->pages_.size() == 0)
316 return metafile; 415 return metafile;
317 416
318 if (data_->recorder_.getRecordingCanvas()) // page outstanding 417 if (data_->recorder_.getRecordingCanvas()) // page outstanding
319 return metafile; 418 return metafile;
320 419
321 metafile->data_->pages_.push_back(data_->pages_.back()); 420 metafile->data_->pages_.push_back(data_->pages_.back());
322 421
323 if (!metafile->FinishDocument()) // Generate PDF. 422 // if (!metafile->FinishDocument()) // Generate PDF.
324 metafile.reset(); 423 // metafile.reset();
325 424
326 return metafile; 425 return metafile;
327 } 426 }
328 427
329 } // namespace printing 428 } // namespace printing
OLDNEW
« no previous file with comments | « printing/pdf_metafile_skia.h ('k') | services/pdf_compositor/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698