Chromium Code Reviews| 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 |