blob: 7baa9816e63e297f4c1dd941c7214ddbd0a78201 [file] [log] [blame]
[email protected]0a4392a2012-03-23 17:50:191// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]8f879292011-04-08 00:21:202// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Wei Liab754772018-08-22 22:41:175#include "printing/metafile_skia.h"
[email protected]8f879292011-04-08 00:21:206
thestig6b4461f2016-10-28 19:34:307#include <algorithm>
Lei Zhang8780d73e2018-08-10 18:45:558#include <map>
thestig6b4461f2016-10-28 19:34:309#include <utility>
10#include <vector>
11
Wei Lie13ea642018-02-17 07:55:1912#include "base/bind.h"
13#include "base/bind_helpers.h"
halcanary223f70a2016-06-09 00:07:4214#include "base/files/file.h"
Wei Lie13ea642018-02-17 07:55:1915#include "base/stl_util.h"
halcanary67ce00b82015-09-27 21:59:5316#include "base/time/time.h"
enne7b64edf32017-02-16 20:10:0217#include "cc/paint/paint_record.h"
18#include "cc/paint/paint_recorder.h"
enne59df29de2017-05-02 03:23:3719#include "cc/paint/skia_paint_canvas.h"
halcanary73b63fd2015-11-06 00:02:1420#include "printing/print_settings.h"
Wei Lie13ea642018-02-17 07:55:1921#include "third_party/skia/include/core/SkCanvas.h"
22#include "third_party/skia/include/core/SkPicture.h"
Wei Li5bb659742018-02-14 03:07:5823#include "third_party/skia/include/core/SkSerialProcs.h"
[email protected]8f879292011-04-08 00:21:2024#include "third_party/skia/include/core/SkStream.h"
halcanaryffa005b2016-06-15 17:13:1625// Note that headers in third_party/skia/src are fragile. This is
26// an experimental, fragile, and diagnostic-only document type.
27#include "third_party/skia/src/utils/SkMultiPictureDocument.h"
halcanary223f70a2016-06-09 00:07:4228#include "ui/gfx/geometry/safe_integer_conversions.h"
halcanaryff214762015-01-22 20:34:3229#include "ui/gfx/skia_util.h"
[email protected]8f879292011-04-08 00:21:2030
thestig99fc2132017-04-27 03:37:5431#if defined(OS_MACOSX)
32#include "printing/pdf_metafile_cg_mac.h"
33#endif
34
35#if defined(OS_POSIX)
36#include "base/file_descriptor_posix.h"
37#endif
38
Shimi Zhang5ccdf202020-02-13 01:13:1939#if defined(OS_ANDROID)
40#include "base/files/file_util.h"
41#endif // defined(OS_ANDROID)
42
halcanaryff214762015-01-22 20:34:3243namespace {
thestige3f5f5d42015-07-16 19:46:2444
Wei Liab754772018-08-22 22:41:1745bool WriteAssetToBuffer(const SkStreamAsset* asset, void* buffer, size_t size) {
halcanaryff214762015-01-22 20:34:3246 // Calling duplicate() keeps original asset state unchanged.
dchengc3df9ba2016-04-07 23:09:3247 std::unique_ptr<SkStreamAsset> assetCopy(asset->duplicate());
halcanaryff214762015-01-22 20:34:3248 size_t length = assetCopy->getLength();
Lei Zhang662e4222017-12-14 20:18:3449 return length <= size && length == assetCopy->read(buffer, length);
halcanaryff214762015-01-22 20:34:3250}
51
thestige3f5f5d42015-07-16 19:46:2452} // namespace
53
[email protected]8f879292011-04-08 00:21:2054namespace printing {
55
halcanary8dd6f0242016-06-13 19:40:2356struct Page {
Lei Zhang8780d73e2018-08-10 18:45:5557 Page(const SkSize& s, sk_sp<cc::PaintRecord> c)
58 : size(s), content(std::move(c)) {}
59 Page(Page&& that) : size(that.size), content(std::move(that.content)) {}
halcanary8dd6f0242016-06-13 19:40:2360 Page(const Page&) = default;
61 Page& operator=(const Page&) = default;
62 Page& operator=(Page&& that) {
Lei Zhang8780d73e2018-08-10 18:45:5563 size = that.size;
64 content = std::move(that.content);
halcanary8dd6f0242016-06-13 19:40:2365 return *this;
66 }
Lei Zhang8780d73e2018-08-10 18:45:5567 SkSize size;
68 sk_sp<cc::PaintRecord> content;
halcanary8dd6f0242016-06-13 19:40:2369};
70
Wei Liab754772018-08-22 22:41:1771struct MetafileSkiaData {
Lei Zhang8780d73e2018-08-10 18:45:5572 cc::PaintRecorder recorder; // Current recording
halcanaryff214762015-01-22 20:34:3273
Lei Zhang8780d73e2018-08-10 18:45:5574 std::vector<Page> pages;
Wei Liab754772018-08-22 22:41:1775 std::unique_ptr<SkStreamAsset> data_stream;
Lei Zhang8780d73e2018-08-10 18:45:5576 ContentToProxyIdMap subframe_content_info;
77 std::map<uint32_t, sk_sp<SkPicture>> subframe_pics;
78 int document_cookie = 0;
halcanaryff214762015-01-22 20:34:3279
halcanary223f70a2016-06-09 00:07:4280 // The scale factor is used because Blink occasionally calls
enne7b64edf32017-02-16 20:10:0281 // PaintCanvas::getTotalMatrix() even though the total matrix is not as
halcanary223f70a2016-06-09 00:07:4282 // meaningful for a vector canvas as for a raster canvas.
Lei Zhang8780d73e2018-08-10 18:45:5583 float scale_factor;
84 SkSize size;
85 SkiaDocumentType type;
thestig99fc2132017-04-27 03:37:5486
87#if defined(OS_MACOSX)
Lei Zhang8780d73e2018-08-10 18:45:5588 PdfMetafileCg pdf_cg;
thestig99fc2132017-04-27 03:37:5489#endif
[email protected]8f879292011-04-08 00:21:2090};
91
Wei Liab754772018-08-22 22:41:1792MetafileSkia::MetafileSkia() : data_(std::make_unique<MetafileSkiaData>()) {
Lei Zhang8780d73e2018-08-10 18:45:5593 data_->type = SkiaDocumentType::PDF;
Wei Lie13ea642018-02-17 07:55:1994}
95
Wei Liab754772018-08-22 22:41:1796MetafileSkia::MetafileSkia(SkiaDocumentType type, int document_cookie)
97 : data_(std::make_unique<MetafileSkiaData>()) {
Lei Zhang8780d73e2018-08-10 18:45:5598 data_->type = type;
99 data_->document_cookie = document_cookie;
Lei Zhang662e4222017-12-14 20:18:34100}
101
Wei Liab754772018-08-22 22:41:17102MetafileSkia::~MetafileSkia() = default;
[email protected]8f879292011-04-08 00:21:20103
Wei Liab754772018-08-22 22:41:17104bool MetafileSkia::Init() {
[email protected]8f879292011-04-08 00:21:20105 return true;
106}
halcanaryff214762015-01-22 20:34:32107
108// TODO(halcanary): Create a Metafile class that only stores data.
109// Metafile::InitFromData is orthogonal to what the rest of
Wei Liab754772018-08-22 22:41:17110// MetafileSkia does.
Lei Zhangb4ef0d5d2020-03-27 23:18:29111bool MetafileSkia::InitFromData(base::span<const uint8_t> data) {
Wei Liab754772018-08-22 22:41:17112 data_->data_stream = std::make_unique<SkMemoryStream>(
Lei Zhangb4ef0d5d2020-03-27 23:18:29113 data.data(), data.size(), /*copy_data=*/true);
halcanaryff214762015-01-22 20:34:32114 return true;
[email protected]8f879292011-04-08 00:21:20115}
116
Wei Liab754772018-08-22 22:41:17117void MetafileSkia::StartPage(const gfx::Size& page_size,
118 const gfx::Rect& content_area,
Lei Zhang5c6ed5b2020-03-24 17:42:53119 float scale_factor) {
halcanary223f70a2016-06-09 00:07:42120 DCHECK_GT(page_size.width(), 0);
121 DCHECK_GT(page_size.height(), 0);
122 DCHECK_GT(scale_factor, 0.0f);
Lei Zhang8780d73e2018-08-10 18:45:55123 if (data_->recorder.getRecordingCanvas())
thestig5ff7db22016-02-13 04:42:45124 FinishPage();
Lei Zhang8780d73e2018-08-10 18:45:55125 DCHECK(!data_->recorder.getRecordingCanvas());
halcanary223f70a2016-06-09 00:07:42126
127 float inverse_scale = 1.0 / scale_factor;
Lei Zhang8780d73e2018-08-10 18:45:55128 cc::PaintCanvas* canvas = data_->recorder.beginRecording(
halcanary223f70a2016-06-09 00:07:42129 inverse_scale * page_size.width(), inverse_scale * page_size.height());
Lei Zhang8780d73e2018-08-10 18:45:55130 // Recording canvas is owned by the |data_->recorder|. No ref() necessary.
halcanary223f70a2016-06-09 00:07:42131 if (content_area != gfx::Rect(page_size)) {
132 canvas->scale(inverse_scale, inverse_scale);
133 SkRect sk_content_area = gfx::RectToSkRect(content_area);
134 canvas->clipRect(sk_content_area);
135 canvas->translate(sk_content_area.x(), sk_content_area.y());
136 canvas->scale(scale_factor, scale_factor);
137 }
138
Lei Zhang8780d73e2018-08-10 18:45:55139 data_->size = gfx::SizeFToSkSize(gfx::SizeF(page_size));
140 data_->scale_factor = scale_factor;
halcanary5baa8fb42015-04-03 21:39:30141 // We scale the recording canvas's size so that
142 // canvas->getTotalMatrix() returns a value that ignores the scale
halcanary223f70a2016-06-09 00:07:42143 // factor. We store the scale factor and re-apply it later.
144 // http://crbug.com/469656
[email protected]8f879292011-04-08 00:21:20145}
146
Wei Liab754772018-08-22 22:41:17147cc::PaintCanvas* MetafileSkia::GetVectorCanvasForNewPage(
halcanary5be808e2014-11-10 22:20:05148 const gfx::Size& page_size,
149 const gfx::Rect& content_area,
Lei Zhang5c6ed5b2020-03-24 17:42:53150 float scale_factor) {
halcanary223f70a2016-06-09 00:07:42151 StartPage(page_size, content_area, scale_factor);
Lei Zhang8780d73e2018-08-10 18:45:55152 return data_->recorder.getRecordingCanvas();
[email protected]8f879292011-04-08 00:21:20153}
154
Wei Liab754772018-08-22 22:41:17155bool MetafileSkia::FinishPage() {
Lei Zhang8780d73e2018-08-10 18:45:55156 if (!data_->recorder.getRecordingCanvas())
halcanaryff214762015-01-22 20:34:32157 return false;
halcanary223f70a2016-06-09 00:07:42158
Lei Zhang8780d73e2018-08-10 18:45:55159 sk_sp<cc::PaintRecord> pic = data_->recorder.finishRecordingAsPicture();
160 if (data_->scale_factor != 1.0f) {
161 cc::PaintCanvas* canvas = data_->recorder.beginRecording(
162 data_->size.width(), data_->size.height());
163 canvas->scale(data_->scale_factor, data_->scale_factor);
halcanary223f70a2016-06-09 00:07:42164 canvas->drawPicture(pic);
Lei Zhang8780d73e2018-08-10 18:45:55165 pic = data_->recorder.finishRecordingAsPicture();
halcanary223f70a2016-06-09 00:07:42166 }
Lei Zhang8780d73e2018-08-10 18:45:55167 data_->pages.emplace_back(data_->size, std::move(pic));
[email protected]8f879292011-04-08 00:21:20168 return true;
169}
170
Wei Liab754772018-08-22 22:41:17171bool MetafileSkia::FinishDocument() {
halcanaryff214762015-01-22 20:34:32172 // If we've already set the data in InitFromData, leave it be.
Wei Liab754772018-08-22 22:41:17173 if (data_->data_stream)
halcanaryff214762015-01-22 20:34:32174 return false;
[email protected]8f879292011-04-08 00:21:20175
Lei Zhang8780d73e2018-08-10 18:45:55176 if (data_->recorder.getRecordingCanvas())
thestig5ff7db22016-02-13 04:42:45177 FinishPage();
[email protected]67e16b392011-05-30 20:58:09178
halcanary223f70a2016-06-09 00:07:42179 SkDynamicMemoryWStream stream;
halcanaryffa005b2016-06-15 17:13:16180 sk_sp<SkDocument> doc;
Wei Lie13ea642018-02-17 07:55:19181 cc::PlaybackParams::CustomDataRasterCallback custom_callback;
Lei Zhang8780d73e2018-08-10 18:45:55182 switch (data_->type) {
Wei Lid0e05022017-08-22 03:56:52183 case SkiaDocumentType::PDF:
Dominic Mazzoni0a39059c2020-01-08 19:30:45184 doc = MakePdfDocument(printing::GetAgent(), accessibility_tree_, &stream);
halcanaryffa005b2016-06-15 17:13:16185 break;
Wei Lid0e05022017-08-22 03:56:52186 case SkiaDocumentType::MSKP:
Lei Zhang8780d73e2018-08-10 18:45:55187 SkSerialProcs procs = SerializationProcs(&data_->subframe_content_info);
Wei Lie13ea642018-02-17 07:55:19188 doc = SkMakeMultiPictureDocument(&stream, &procs);
189 // It is safe to use base::Unretained(this) because the callback
190 // is only used by |canvas| in the following loop which has shorter
191 // lifetime than |this|.
Wei Liab754772018-08-22 22:41:17192 custom_callback = base::BindRepeating(
193 &MetafileSkia::CustomDataToSkPictureCallback, base::Unretained(this));
halcanaryffa005b2016-06-15 17:13:16194 break;
195 }
halcanaryfb232282016-04-28 18:34:24196
Lei Zhang8780d73e2018-08-10 18:45:55197 for (const Page& page : data_->pages) {
enne98c9f8052017-03-15 19:38:22198 cc::SkiaPaintCanvas canvas(
Lei Zhang8780d73e2018-08-10 18:45:55199 doc->beginPage(page.size.width(), page.size.height()));
200 canvas.drawPicture(page.content, custom_callback);
halcanary223f70a2016-06-09 00:07:42201 doc->endPage();
halcanary0aeeb3332016-03-18 14:32:39202 }
reede35e0532016-09-22 17:30:29203 doc->close();
[email protected]67e16b392011-05-30 20:58:09204
Wei Liab754772018-08-22 22:41:17205 data_->data_stream = stream.detachAsStream();
halcanaryff214762015-01-22 20:34:32206 return true;
[email protected]8f879292011-04-08 00:21:20207}
208
Wei Liab754772018-08-22 22:41:17209void MetafileSkia::FinishFrameContent() {
Wei Li5bb659742018-02-14 03:07:58210 // Sanity check to make sure we print the entire frame as a single page
211 // content.
Lei Zhang8780d73e2018-08-10 18:45:55212 DCHECK_EQ(data_->pages.size(), 1u);
Wei Li5bb659742018-02-14 03:07:58213 // Also make sure it is in skia multi-picture document format.
Lei Zhang8780d73e2018-08-10 18:45:55214 DCHECK_EQ(data_->type, SkiaDocumentType::MSKP);
Wei Liab754772018-08-22 22:41:17215 DCHECK(!data_->data_stream);
Wei Li5bb659742018-02-14 03:07:58216
Wei Li6b0cfc92018-08-08 19:52:25217 cc::PlaybackParams::CustomDataRasterCallback custom_callback =
Wei Liab754772018-08-22 22:41:17218 base::BindRepeating(&MetafileSkia::CustomDataToSkPictureCallback,
Wei Li6b0cfc92018-08-08 19:52:25219 base::Unretained(this));
Lei Zhang8780d73e2018-08-10 18:45:55220 sk_sp<SkPicture> pic = ToSkPicture(data_->pages[0].content,
221 SkRect::MakeSize(data_->pages[0].size),
Wei Li6b0cfc92018-08-08 19:52:25222 nullptr, custom_callback);
Lei Zhang8780d73e2018-08-10 18:45:55223 SkSerialProcs procs = SerializationProcs(&data_->subframe_content_info);
Wei Li6b0cfc92018-08-08 19:52:25224 SkDynamicMemoryWStream stream;
Wei Li5bb659742018-02-14 03:07:58225 pic->serialize(&stream, &procs);
Wei Liab754772018-08-22 22:41:17226 data_->data_stream = stream.detachAsStream();
Wei Li5bb659742018-02-14 03:07:58227}
228
Wei Liab754772018-08-22 22:41:17229uint32_t MetafileSkia::GetDataSize() const {
230 if (!data_->data_stream)
halcanaryff214762015-01-22 20:34:32231 return 0;
Wei Liab754772018-08-22 22:41:17232 return base::checked_cast<uint32_t>(data_->data_stream->getLength());
[email protected]8f879292011-04-08 00:21:20233}
234
Wei Liab754772018-08-22 22:41:17235bool MetafileSkia::GetData(void* dst_buffer, uint32_t dst_buffer_size) const {
236 if (!data_->data_stream)
[email protected]8f879292011-04-08 00:21:20237 return false;
Wei Liab754772018-08-22 22:41:17238 return WriteAssetToBuffer(data_->data_stream.get(), dst_buffer,
halcanaryff214762015-01-22 20:34:32239 base::checked_cast<size_t>(dst_buffer_size));
[email protected]8f879292011-04-08 00:21:20240}
241
Wei Liab754772018-08-22 22:41:17242gfx::Rect MetafileSkia::GetPageBounds(unsigned int page_number) const {
Lei Zhang8780d73e2018-08-10 18:45:55243 if (page_number < data_->pages.size()) {
244 SkSize size = data_->pages[page_number].size;
halcanary8dd6f0242016-06-13 19:40:23245 return gfx::Rect(gfx::ToRoundedInt(size.width()),
246 gfx::ToRoundedInt(size.height()));
halcanaryff214762015-01-22 20:34:32247 }
[email protected]8f879292011-04-08 00:21:20248 return gfx::Rect();
249}
250
Wei Liab754772018-08-22 22:41:17251unsigned int MetafileSkia::GetPageCount() const {
Lei Zhang8780d73e2018-08-10 18:45:55252 return base::checked_cast<unsigned int>(data_->pages.size());
[email protected]8f879292011-04-08 00:21:20253}
254
Wei Liab754772018-08-22 22:41:17255printing::NativeDrawingContext MetafileSkia::context() const {
[email protected]8f879292011-04-08 00:21:20256 NOTREACHED();
thestig192677ec2016-06-09 07:43:17257 return nullptr;
[email protected]8f879292011-04-08 00:21:20258}
259
260#if defined(OS_WIN)
Wei Liab754772018-08-22 22:41:17261bool MetafileSkia::Playback(printing::NativeDrawingContext hdc,
262 const RECT* rect) const {
thestig3109df12017-04-26 21:57:25263 NOTREACHED();
264 return false;
265}
266
Wei Liab754772018-08-22 22:41:17267bool MetafileSkia::SafePlayback(printing::NativeDrawingContext hdc) const {
[email protected]8f879292011-04-08 00:21:20268 NOTREACHED();
269 return false;
270}
thestig99fc2132017-04-27 03:37:54271
272#elif defined(OS_MACOSX)
273/* TODO(caryclark): The set up of PluginInstance::PrintPDFOutput may result in
274 rasterized output. Even if that flow uses PdfMetafileCg::RenderPage,
275 the drawing of the PDF into the canvas may result in a rasterized output.
276 PDFMetafileSkia::RenderPage should be not implemented as shown and instead
277 should do something like the following CL in PluginInstance::PrintPDFOutput:
278http://codereview.chromium.org/7200040/diff/1/webkit/plugins/ppapi/ppapi_plugin_instance.cc
279*/
Wei Liab754772018-08-22 22:41:17280bool MetafileSkia::RenderPage(unsigned int page_number,
281 CGContextRef context,
Lei Zhangf69ea3b2020-03-24 17:53:48282 const CGRect& rect,
Wei Liab754772018-08-22 22:41:17283 const MacRenderPageParams& params) const {
thestig99fc2132017-04-27 03:37:54284 DCHECK_GT(GetDataSize(), 0U);
Lei Zhang8780d73e2018-08-10 18:45:55285 if (data_->pdf_cg.GetDataSize() == 0) {
thestig99fc2132017-04-27 03:37:54286 if (GetDataSize() == 0)
287 return false;
Wei Liab754772018-08-22 22:41:17288 size_t length = data_->data_stream->getLength();
thestig99fc2132017-04-27 03:37:54289 std::vector<uint8_t> buffer(length);
Wei Liab754772018-08-22 22:41:17290 (void)WriteAssetToBuffer(data_->data_stream.get(), &buffer[0], length);
Lei Zhangb4ef0d5d2020-03-27 23:18:29291 data_->pdf_cg.InitFromData(buffer);
thestig99fc2132017-04-27 03:37:54292 }
Lei Zhang8780d73e2018-08-10 18:45:55293 return data_->pdf_cg.RenderPage(page_number, context, rect, params);
thestig99fc2132017-04-27 03:37:54294}
[email protected]b8d85bc2011-06-22 13:34:57295#endif
[email protected]8f879292011-04-08 00:21:20296
Shimi Zhang5ccdf202020-02-13 01:13:19297#if defined(OS_ANDROID)
298bool MetafileSkia::SaveToFileDescriptor(int fd) const {
299 if (GetDataSize() == 0u)
300 return false;
301
302 std::unique_ptr<SkStreamAsset> asset(data_->data_stream->duplicate());
303
304 static constexpr size_t kMaximumBufferSize = 1024 * 1024;
305 std::vector<uint8_t> buffer(std::min(kMaximumBufferSize, asset->getLength()));
306 do {
307 size_t read_size = asset->read(&buffer[0], buffer.size());
308 if (read_size == 0u)
309 break;
310 DCHECK_GE(buffer.size(), read_size);
311 if (!base::WriteFileDescriptor(
312 fd, reinterpret_cast<const char*>(buffer.data()), read_size)) {
313 return false;
314 }
315 } while (!asset->isAtEnd());
316
317 return true;
318}
319#else
Wei Liab754772018-08-22 22:41:17320bool MetafileSkia::SaveTo(base::File* file) const {
halcanary5be808e2014-11-10 22:20:05321 if (GetDataSize() == 0U)
322 return false;
halcanaryff214762015-01-22 20:34:32323
324 // Calling duplicate() keeps original asset state unchanged.
Wei Liab754772018-08-22 22:41:17325 std::unique_ptr<SkStreamAsset> asset(data_->data_stream->duplicate());
halcanaryff214762015-01-22 20:34:32326
Lei Zhang8780d73e2018-08-10 18:45:55327 static constexpr size_t kMaximumBufferSize = 1024 * 1024;
Lei Zhang12893bb62019-09-25 18:31:04328 std::vector<uint8_t> buffer(std::min(kMaximumBufferSize, asset->getLength()));
halcanaryff214762015-01-22 20:34:32329 do {
330 size_t read_size = asset->read(&buffer[0], buffer.size());
331 if (read_size == 0)
332 break;
333 DCHECK_GE(buffer.size(), read_size);
Lei Zhang12893bb62019-09-25 18:31:04334 if (!file->WriteAtCurrentPosAndCheck(
335 base::make_span(&buffer[0], read_size))) {
halcanaryff214762015-01-22 20:34:32336 return false;
337 }
338 } while (!asset->isAtEnd());
339
340 return true;
halcanary5be808e2014-11-10 22:20:05341}
Shimi Zhang5ccdf202020-02-13 01:13:19342#endif // defined(OS_ANDROID)
halcanary5be808e2014-11-10 22:20:05343
Wei Liab754772018-08-22 22:41:17344std::unique_ptr<MetafileSkia> MetafileSkia::GetMetafileForCurrentPage(
halcanaryffa005b2016-06-15 17:13:16345 SkiaDocumentType type) {
halcanaryff214762015-01-22 20:34:32346 // If we only ever need the metafile for the last page, should we
enne7b64edf32017-02-16 20:10:02347 // only keep a handle on one PaintRecord?
Wei Liab754772018-08-22 22:41:17348 auto metafile = std::make_unique<MetafileSkia>(type, data_->document_cookie);
Lei Zhang8780d73e2018-08-10 18:45:55349 if (data_->pages.size() == 0)
dchenge48600452015-12-28 02:24:50350 return metafile;
[email protected]597516372011-07-01 05:10:44351
Lei Zhang8780d73e2018-08-10 18:45:55352 if (data_->recorder.getRecordingCanvas()) // page outstanding
dchenge48600452015-12-28 02:24:50353 return metafile;
[email protected]597516372011-07-01 05:10:44354
Lei Zhang8780d73e2018-08-10 18:45:55355 metafile->data_->pages.push_back(data_->pages.back());
356 metafile->data_->subframe_content_info = data_->subframe_content_info;
357 metafile->data_->subframe_pics = data_->subframe_pics;
halcanaryff214762015-01-22 20:34:32358
359 if (!metafile->FinishDocument()) // Generate PDF.
vitalybuka5d1290582014-09-12 09:19:59360 metafile.reset();
halcanaryff214762015-01-22 20:34:32361
dchenge48600452015-12-28 02:24:50362 return metafile;
[email protected]597516372011-07-01 05:10:44363}
[email protected]8f879292011-04-08 00:21:20364
Wei Liab754772018-08-22 22:41:17365uint32_t MetafileSkia::CreateContentForRemoteFrame(const gfx::Rect& rect,
366 int render_proxy_id) {
Wei Lie13ea642018-02-17 07:55:19367 // Create a place holder picture.
368 sk_sp<SkPicture> pic = SkPicture::MakePlaceholder(
369 SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()));
370
371 // Store the map between content id and the proxy id.
372 uint32_t content_id = pic->uniqueID();
Jan Wilken Dörrie3ced3ccc2019-06-06 21:41:58373 DCHECK(!base::Contains(data_->subframe_content_info, content_id));
Lei Zhang8780d73e2018-08-10 18:45:55374 data_->subframe_content_info[content_id] = render_proxy_id;
Wei Lie13ea642018-02-17 07:55:19375
376 // Store the picture content.
Lei Zhang8780d73e2018-08-10 18:45:55377 data_->subframe_pics[content_id] = pic;
Wei Lie13ea642018-02-17 07:55:19378 return content_id;
379}
380
Wei Liab754772018-08-22 22:41:17381int MetafileSkia::GetDocumentCookie() const {
Lei Zhang8780d73e2018-08-10 18:45:55382 return data_->document_cookie;
Wei Lie13ea642018-02-17 07:55:19383}
384
Wei Liab754772018-08-22 22:41:17385const ContentToProxyIdMap& MetafileSkia::GetSubframeContentInfo() const {
Lei Zhang8780d73e2018-08-10 18:45:55386 return data_->subframe_content_info;
Wei Lie13ea642018-02-17 07:55:19387}
388
Wei Liab754772018-08-22 22:41:17389void MetafileSkia::AppendPage(const SkSize& page_size,
390 sk_sp<cc::PaintRecord> record) {
Lei Zhang8780d73e2018-08-10 18:45:55391 data_->pages.emplace_back(page_size, std::move(record));
Wei Li1d345bf2018-08-10 02:52:37392}
393
Wei Liab754772018-08-22 22:41:17394void MetafileSkia::AppendSubframeInfo(uint32_t content_id,
395 int proxy_id,
396 sk_sp<SkPicture> pic_holder) {
Lei Zhang8780d73e2018-08-10 18:45:55397 data_->subframe_content_info[content_id] = proxy_id;
398 data_->subframe_pics[content_id] = pic_holder;
Wei Li1d345bf2018-08-10 02:52:37399}
400
Wei Liab754772018-08-22 22:41:17401SkStreamAsset* MetafileSkia::GetPdfData() const {
402 return data_->data_stream.get();
Wei Li1d345bf2018-08-10 02:52:37403}
404
Wei Liab754772018-08-22 22:41:17405void MetafileSkia::CustomDataToSkPictureCallback(SkCanvas* canvas,
406 uint32_t content_id) {
Wei Lie13ea642018-02-17 07:55:19407 // Check whether this is the one we need to handle.
Jan Wilken Dörrie3ced3ccc2019-06-06 21:41:58408 if (!base::Contains(data_->subframe_content_info, content_id))
Wei Lie13ea642018-02-17 07:55:19409 return;
410
Lei Zhang8780d73e2018-08-10 18:45:55411 auto it = data_->subframe_pics.find(content_id);
412 DCHECK(it != data_->subframe_pics.end());
Wei Lie13ea642018-02-17 07:55:19413
414 // Found the picture, draw it on canvas.
415 sk_sp<SkPicture> pic = it->second;
416 SkRect rect = pic->cullRect();
417 SkMatrix matrix = SkMatrix::MakeTrans(rect.x(), rect.y());
418 canvas->drawPicture(it->second, &matrix, nullptr);
419}
420
[email protected]8f879292011-04-08 00:21:20421} // namespace printing