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

Unified Diff: components/printing/service/pdf_compositor_impl.cc

Issue 2832633002: Add PDF compositor service (Closed)
Patch Set: remove headers 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 side-by-side diff with in-line comments
Download patch
Index: components/printing/service/pdf_compositor_impl.cc
diff --git a/components/printing/service/pdf_compositor_impl.cc b/components/printing/service/pdf_compositor_impl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..11908a36bc48c59b8f08fe2ebeeb08600fb063f0
--- /dev/null
+++ b/components/printing/service/pdf_compositor_impl.cc
@@ -0,0 +1,127 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/printing/service/pdf_compositor_impl.h"
+
+#include <utility>
+#include <vector>
+
+#include "base/logging.h"
+#include "base/memory/shared_memory.h"
+#include "base/memory/shared_memory_handle.h"
+#include "base/time/time.h"
+#include "mojo/public/cpp/system/platform_handle.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkDocument.h"
+#include "third_party/skia/include/core/SkSize.h"
+#include "third_party/skia/include/core/SkStream.h"
+#include "third_party/skia/include/core/SkTime.h"
+#include "third_party/skia/include/core/SkTypes.h"
+#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.
+
+namespace {
+
+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.
+ base::Time::Exploded exploded;
+ time.UTCExplode(&exploded);
+ SkTime::DateTime skdate;
+ skdate.fTimeZoneMinutes = 0;
+ skdate.fYear = exploded.year;
+ skdate.fMonth = exploded.month;
+ skdate.fDayOfWeek = exploded.day_of_week;
+ skdate.fDay = exploded.day_of_month;
+ skdate.fHour = exploded.hour;
+ skdate.fMinute = exploded.minute;
+ skdate.fSecond = exploded.second;
+ return skdate;
+}
+
+sk_sp<SkDocument> MakePdfDocument(const std::string& creator,
+ SkWStream* wStream) {
+ SkDocument::PDFMetadata metadata;
+ SkTime::DateTime now = TimeToSkTime(base::Time::Now());
+ metadata.fCreation.fEnabled = true;
+ metadata.fCreation.fDateTime = now;
+ metadata.fModified.fEnabled = true;
+ metadata.fModified.fDateTime = now;
+ metadata.fCreator = creator.empty()
+ ? SkString("Chromium")
+ : SkString(creator.c_str(), creator.size());
+ return SkDocument::MakePDF(wStream, SK_ScalarDefaultRasterDPI, metadata,
+ nullptr, false);
+}
+
+} // namespace
+
+namespace printing {
+
+PdfCompositorImpl::PdfCompositorImpl(
+ const std::string& creator,
+ std::unique_ptr<service_manager::ServiceContextRef> service_ref)
+ : service_ref_(std::move(service_ref)), creator_(creator) {}
+
+PdfCompositorImpl::~PdfCompositorImpl() = default;
+
+void PdfCompositorImpl::CompositePdf(
+ mojo::ScopedSharedBufferHandle sk_handle,
+ const mojom::PdfCompositor::CompositePdfCallback& callback) {
+ DCHECK(sk_handle.is_valid());
+
+ base::SharedMemoryHandle memory_handle;
+ size_t memory_size = 0;
+ bool read_only_flag = false;
+
+ const MojoResult result = mojo::UnwrapSharedMemoryHandle(
+ std::move(sk_handle), &memory_handle, &memory_size, &read_only_flag);
+ DCHECK_EQ(MOJO_RESULT_OK, result);
+ DCHECK_GT(memory_size, 0u);
+
+ std::unique_ptr<base::SharedMemory> shm =
+ base::MakeUnique<base::SharedMemory>(memory_handle, true);
+ if (!shm->Map(memory_size)) {
+ 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.
+ return;
+ }
+
+ if (shm->mapped_size() == 0) {
+ callback.Run(mojo::ScopedSharedBufferHandle());
+ return;
+ }
+
+ SkMemoryStream stream(shm->memory(), memory_size);
+ int page_count = SkMultiPictureDocumentReadPageCount(&stream);
+ if (!page_count) {
+ DLOG(ERROR) << "No page is read.";
+ return;
+ }
+
+ std::vector<SkDocumentPage> pages(page_count);
+ if (!SkMultiPictureDocumentRead(&stream, pages.data(), page_count)) {
+ DLOG(ERROR) << "Page read error.";
+ return;
+ }
+
+ SkDynamicMemoryWStream wstream;
+ sk_sp<SkDocument> doc =
+ MakePdfDocument(creator_.size() ? creator_ : "Chromium", &wstream);
+
+ for (const auto& page : pages) {
+ SkCanvas* canvas = doc->beginPage(page.fSize.width(), page.fSize.height());
+ canvas->drawPicture(page.fPicture);
+ doc->endPage();
+ }
+ doc->close();
+
+ mojo::ScopedSharedBufferHandle buffer =
+ mojo::SharedBufferHandle::Create(wstream.bytesWritten());
+ DCHECK(buffer.is_valid());
+
+ mojo::ScopedSharedBufferMapping mapping = buffer->Map(wstream.bytesWritten());
+ DCHECK(mapping);
+ 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.
+
+ callback.Run(std::move(buffer));
+}
+
+} // namespace printing

Powered by Google App Engine
This is Rietveld 408576698