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 "base/time/time.h" | |
14 #include "mojo/public/cpp/system/platform_handle.h" | |
15 #include "third_party/skia/include/core/SkCanvas.h" | |
16 #include "third_party/skia/include/core/SkDocument.h" | |
17 #include "third_party/skia/include/core/SkSize.h" | |
18 #include "third_party/skia/include/core/SkStream.h" | |
19 #include "third_party/skia/include/core/SkTime.h" | |
20 #include "third_party/skia/include/core/SkTypes.h" | |
21 #include "third_party/skia/src/utils/SkMultiPictureDocument.h" | |
hal.canary
2017/04/24 19:13:17
FYI: I am trying to get this API blessed: https://
Wei Li
2017/04/27 05:34:16
Acknowledged.
| |
22 | |
23 namespace { | |
24 | |
25 SkTime::DateTime TimeToSkTime(base::Time time) { | |
Lei Zhang
2017/04/22 00:12:26
Do we want to reuse the existing code in printing/
Wei Li
2017/04/27 05:34:16
Done.
| |
26 base::Time::Exploded exploded; | |
27 time.UTCExplode(&exploded); | |
28 SkTime::DateTime skdate; | |
29 skdate.fTimeZoneMinutes = 0; | |
30 skdate.fYear = exploded.year; | |
31 skdate.fMonth = exploded.month; | |
32 skdate.fDayOfWeek = exploded.day_of_week; | |
33 skdate.fDay = exploded.day_of_month; | |
34 skdate.fHour = exploded.hour; | |
35 skdate.fMinute = exploded.minute; | |
36 skdate.fSecond = exploded.second; | |
37 return skdate; | |
38 } | |
39 | |
40 sk_sp<SkDocument> MakePdfDocument(const std::string& creator, | |
41 SkWStream* wStream) { | |
42 SkDocument::PDFMetadata metadata; | |
43 SkTime::DateTime now = TimeToSkTime(base::Time::Now()); | |
44 metadata.fCreation.fEnabled = true; | |
45 metadata.fCreation.fDateTime = now; | |
46 metadata.fModified.fEnabled = true; | |
47 metadata.fModified.fDateTime = now; | |
48 metadata.fCreator = creator.empty() | |
49 ? SkString("Chromium") | |
50 : SkString(creator.c_str(), creator.size()); | |
51 return SkDocument::MakePDF(wStream, SK_ScalarDefaultRasterDPI, metadata, | |
52 nullptr, false); | |
53 } | |
54 | |
55 } // namespace | |
56 | |
57 namespace printing { | |
58 | |
59 PdfCompositorImpl::PdfCompositorImpl( | |
60 const std::string& creator, | |
61 std::unique_ptr<service_manager::ServiceContextRef> service_ref) | |
62 : service_ref_(std::move(service_ref)), creator_(creator) {} | |
63 | |
64 PdfCompositorImpl::~PdfCompositorImpl() = default; | |
65 | |
66 void PdfCompositorImpl::CompositePdf( | |
67 mojo::ScopedSharedBufferHandle sk_handle, | |
68 const mojom::PdfCompositor::CompositePdfCallback& callback) { | |
69 DCHECK(sk_handle.is_valid()); | |
70 | |
71 base::SharedMemoryHandle memory_handle; | |
72 size_t memory_size = 0; | |
73 bool read_only_flag = false; | |
74 | |
75 const MojoResult result = mojo::UnwrapSharedMemoryHandle( | |
76 std::move(sk_handle), &memory_handle, &memory_size, &read_only_flag); | |
77 DCHECK_EQ(MOJO_RESULT_OK, result); | |
78 DCHECK_GT(memory_size, 0u); | |
79 | |
80 std::unique_ptr<base::SharedMemory> shm = | |
81 base::MakeUnique<base::SharedMemory>(memory_handle, true); | |
82 if (!shm->Map(memory_size)) { | |
83 DLOG(ERROR) << "OnBufferCreated: Map failed."; | |
Lei Zhang
2017/04/22 00:12:26
Do we need to run |callback| here and anywhere els
Wei Li
2017/04/27 05:34:16
Done.
| |
84 return; | |
85 } | |
86 | |
87 if (shm->mapped_size() == 0) { | |
88 callback.Run(mojo::ScopedSharedBufferHandle()); | |
89 return; | |
90 } | |
91 | |
92 SkMemoryStream stream(shm->memory(), memory_size); | |
93 int page_count = SkMultiPictureDocumentReadPageCount(&stream); | |
94 if (!page_count) { | |
95 DLOG(ERROR) << "No page is read."; | |
96 return; | |
97 } | |
98 | |
99 std::vector<SkDocumentPage> pages(page_count); | |
100 if (!SkMultiPictureDocumentRead(&stream, pages.data(), page_count)) { | |
101 DLOG(ERROR) << "Page read error."; | |
102 return; | |
103 } | |
104 | |
105 SkDynamicMemoryWStream wstream; | |
106 sk_sp<SkDocument> doc = | |
107 MakePdfDocument(creator_.size() ? creator_ : "Chromium", &wstream); | |
108 | |
109 for (const auto& page : pages) { | |
110 SkCanvas* canvas = doc->beginPage(page.fSize.width(), page.fSize.height()); | |
111 canvas->drawPicture(page.fPicture); | |
112 doc->endPage(); | |
113 } | |
114 doc->close(); | |
115 | |
116 mojo::ScopedSharedBufferHandle buffer = | |
117 mojo::SharedBufferHandle::Create(wstream.bytesWritten()); | |
118 DCHECK(buffer.is_valid()); | |
119 | |
120 mojo::ScopedSharedBufferMapping mapping = buffer->Map(wstream.bytesWritten()); | |
121 DCHECK(mapping); | |
122 wstream.copyTo(mapping.get()); | |
hal.canary
2017/04/24 19:13:17
`wstream.copyToAndReset(mapping.get());`
is the ne
Wei Li
2017/04/27 05:34:16
Done.
| |
123 | |
124 callback.Run(std::move(buffer)); | |
125 } | |
126 | |
127 } // namespace printing | |
OLD | NEW |