OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "components/printing/service/pdf_compositor_impl.h" | |
6 | |
7 #include <utility> | |
8 #include <vector> | |
9 | |
10 #include "base/logging.h" | |
11 #include "base/memory/shared_memory.h" | |
12 #include "base/memory/shared_memory_handle.h" | |
13 #include "mojo/public/cpp/system/platform_handle.h" | |
14 #include "printing/common/pdf_metafile_utils.h" | |
15 #include "third_party/skia/include/core/SkCanvas.h" | |
16 #include "third_party/skia/include/core/SkDocument.h" | |
17 #include "third_party/skia/src/utils/SkMultiPictureDocument.h" | |
18 | |
19 namespace printing { | |
20 | |
21 PdfCompositorImpl::PdfCompositorImpl( | |
22 const std::string& creator, | |
23 std::unique_ptr<service_manager::ServiceContextRef> service_ref) | |
24 : service_ref_(std::move(service_ref)), creator_(creator) {} | |
25 | |
26 PdfCompositorImpl::~PdfCompositorImpl() = default; | |
27 | |
28 void PdfCompositorImpl::CompositePdf( | |
29 mojo::ScopedSharedBufferHandle sk_handle, | |
30 const mojom::PdfCompositor::CompositePdfCallback& callback) { | |
31 DCHECK(sk_handle.is_valid()); | |
32 | |
33 base::SharedMemoryHandle memory_handle; | |
34 size_t memory_size = 0; | |
35 bool read_only_flag = false; | |
36 | |
37 const MojoResult result = mojo::UnwrapSharedMemoryHandle( | |
38 std::move(sk_handle), &memory_handle, &memory_size, &read_only_flag); | |
39 DCHECK_EQ(MOJO_RESULT_OK, result); | |
40 DCHECK_GT(memory_size, 0u); | |
41 | |
42 std::unique_ptr<base::SharedMemory> shm = | |
43 base::MakeUnique<base::SharedMemory>(memory_handle, true); | |
44 if (!shm->Map(memory_size) || shm->mapped_size() == 0) { | |
45 DLOG(ERROR) << "CompositePdf: Shared memory map failed."; | |
46 callback.Run(mojo::ScopedSharedBufferHandle()); | |
47 return; | |
48 } | |
49 | |
50 SkMemoryStream stream(shm->memory(), memory_size); | |
51 int page_count = SkMultiPictureDocumentReadPageCount(&stream); | |
52 if (!page_count) { | |
53 DLOG(ERROR) << "CompositePdf: No page is read."; | |
54 callback.Run(mojo::ScopedSharedBufferHandle()); | |
55 return; | |
56 } | |
57 | |
58 std::vector<SkDocumentPage> pages(page_count); | |
59 if (!SkMultiPictureDocumentRead(&stream, pages.data(), page_count)) { | |
60 DLOG(ERROR) << "CompositePdf: Page reading failed."; | |
61 callback.Run(mojo::ScopedSharedBufferHandle()); | |
62 return; | |
63 } | |
64 | |
65 SkDynamicMemoryWStream wstream; | |
66 sk_sp<SkDocument> doc = | |
67 MakePdfDocument(creator_.size() ? creator_ : "Chromium", &wstream); | |
dcheng
2017/05/10 07:36:48
Nit: .empty() instead of .size()
Wei Li
2017/05/11 16:53:01
Done.
| |
68 | |
69 for (const auto& page : pages) { | |
70 SkCanvas* canvas = doc->beginPage(page.fSize.width(), page.fSize.height()); | |
71 canvas->drawPicture(page.fPicture); | |
72 doc->endPage(); | |
73 } | |
74 doc->close(); | |
75 | |
76 mojo::ScopedSharedBufferHandle buffer = | |
77 mojo::SharedBufferHandle::Create(wstream.bytesWritten()); | |
78 DCHECK(buffer.is_valid()); | |
79 | |
80 mojo::ScopedSharedBufferMapping mapping = buffer->Map(wstream.bytesWritten()); | |
81 DCHECK(mapping); | |
82 wstream.copyToAndReset(mapping.get()); | |
83 | |
84 callback.Run(std::move(buffer)); | |
85 } | |
86 | |
87 } // namespace printing | |
OLD | NEW |