| Index: printing/pdf_metafile_skia.cc
|
| diff --git a/printing/pdf_metafile_skia.cc b/printing/pdf_metafile_skia.cc
|
| index fa8c129e9d10f75c64d9d95149023365a5169181..370df26001db219376e15b110651341b667b9f29 100644
|
| --- a/printing/pdf_metafile_skia.cc
|
| +++ b/printing/pdf_metafile_skia.cc
|
| @@ -13,9 +13,12 @@
|
| #include "base/memory/ptr_util.h"
|
| #include "base/time/time.h"
|
| #include "printing/print_settings.h"
|
| +#include "skia/ext/skia_utils_base.h"
|
| #include "third_party/skia/include/core/SkDocument.h"
|
| +#include "third_party/skia/include/core/SkImageDeserializer.h"
|
| #include "third_party/skia/include/core/SkPictureRecorder.h"
|
| #include "third_party/skia/include/core/SkStream.h"
|
| +//#include "third_party/skia/include/core/SkWriteBuffer.h"
|
| // Note that headers in third_party/skia/src are fragile. This is
|
| // an experimental, fragile, and diagnostic-only document type.
|
| #include "third_party/skia/src/utils/SkMultiPictureDocument.h"
|
| @@ -77,7 +80,7 @@ sk_sp<SkDocument> MakePdfDocument(SkWStream* wStream) {
|
| namespace printing {
|
|
|
| struct Page {
|
| - Page(SkSize s, sk_sp<SkPicture> c) : size_(s), content_(std::move(c)) {}
|
| + Page(SkSize s, sk_sp<SkDrawable> c) : size_(s), content_(std::move(c)) {}
|
| Page(Page&& that) : size_(that.size_), content_(std::move(that.content_)) {}
|
| Page(const Page&) = default;
|
| Page& operator=(const Page&) = default;
|
| @@ -87,7 +90,7 @@ struct Page {
|
| return *this;
|
| }
|
| SkSize size_;
|
| - sk_sp<SkPicture> content_;
|
| + sk_sp<SkDrawable> content_;
|
| };
|
|
|
| struct PdfMetafileSkiaData {
|
| @@ -124,6 +127,29 @@ bool PdfMetafileSkia::InitFromData(const void* src_buffer,
|
| return true;
|
| }
|
|
|
| +bool PdfMetafileSkia::InitFromPageDataBuffer(const char* src_buffer,
|
| + size_t src_buffer_size) {
|
| + size_t pos = 0;
|
| + while (pos < src_buffer_size) {
|
| + size_t size = *((size_t*)(src_buffer + pos));
|
| + pos += sizeof(size_t);
|
| + if (pos + size + 2 * sizeof(SkScalar) > src_buffer_size) {
|
| + return false;
|
| + }
|
| + SkScalar width = *((SkScalar*)(src_buffer + pos));
|
| + pos += sizeof(SkScalar);
|
| + SkScalar height = *((SkScalar*)(src_buffer + pos));
|
| + pos += sizeof(SkScalar);
|
| +
|
| + std::unique_ptr<SkDrawable> d = skia::ReadDrawable(src_buffer + pos, size);
|
| +
|
| + data_->pages_.emplace_back(SkSize::Make(width, height),
|
| + sk_sp<SkDrawable>(d.release()));
|
| + pos += size;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| void PdfMetafileSkia::StartPage(const gfx::Size& page_size,
|
| const gfx::Rect& content_area,
|
| const float& scale_factor) {
|
| @@ -166,18 +192,29 @@ bool PdfMetafileSkia::FinishPage() {
|
| if (!data_->recorder_.getRecordingCanvas())
|
| return false;
|
|
|
| - sk_sp<SkPicture> pic = data_->recorder_.finishRecordingAsPicture();
|
| + sk_sp<SkDrawable> pic = data_->recorder_.finishRecordingAsDrawable();
|
| if (data_->scale_factor_ != 1.0f) {
|
| SkCanvas* canvas = data_->recorder_.beginRecording(data_->size_.width(),
|
| data_->size_.height());
|
| canvas->scale(data_->scale_factor_, data_->scale_factor_);
|
| - canvas->drawPicture(pic);
|
| - pic = data_->recorder_.finishRecordingAsPicture();
|
| + canvas->drawDrawable(pic.get());
|
| + pic = data_->recorder_.finishRecordingAsDrawable();
|
| }
|
| - data_->pages_.emplace_back(data_->size_, std::move(pic));
|
| + data_->pages_.emplace_back(data_->size_, pic);
|
| return true;
|
| }
|
|
|
| +void PdfMetafileSkia::FinishAllPages() {
|
| + // If we've already set the data in InitFromData, leave it be.
|
| + if (data_->pdf_data_) {
|
| + return;
|
| + }
|
| +
|
| + if (data_->recorder_.getRecordingCanvas()) {
|
| + FinishPage();
|
| + }
|
| +}
|
| +
|
| bool PdfMetafileSkia::FinishDocument() {
|
| // If we've already set the data in InitFromData, leave it be.
|
| if (data_->pdf_data_)
|
| @@ -199,7 +236,7 @@ bool PdfMetafileSkia::FinishDocument() {
|
|
|
| for (const Page& page : data_->pages_) {
|
| SkCanvas* canvas = doc->beginPage(page.size_.width(), page.size_.height());
|
| - canvas->drawPicture(page.content_);
|
| + canvas->drawDrawable(page.content_.get());
|
| doc->endPage();
|
| }
|
| doc->close();
|
| @@ -208,6 +245,68 @@ bool PdfMetafileSkia::FinishDocument() {
|
| return true;
|
| }
|
|
|
| +std::unique_ptr<char[]> PdfMetafileSkia::GetPageDataBuffer(size_t* size) const {
|
| + struct PageInfo {
|
| + PageInfo(SkScalar w, SkScalar h, std::vector<char> d)
|
| + : width(w), height(h), data(std::move(d)) {}
|
| + SkScalar width;
|
| + SkScalar height;
|
| + std::vector<char> data;
|
| + };
|
| + std::vector<PageInfo> serialized_pages;
|
| + size_t total_buf_size = 0;
|
| + for (size_t i = 0; i < data_->pages_.size(); ++i) {
|
| + // Flatten each page into buffer.
|
| + std::vector<char> flattened =
|
| + skia::WriteDrawable(data_->pages_[i].content_.get());
|
| + if (!flattened.size() || !flattened.data()) {
|
| + continue;
|
| + }
|
| + total_buf_size += sizeof(size_t) + sizeof(SkScalar) * 2 + flattened.size();
|
| + serialized_pages.emplace_back(data_->pages_[i].size_.width(),
|
| + data_->pages_[i].size_.height(),
|
| + std::move(flattened));
|
| + }
|
| + if (!total_buf_size) {
|
| + *size = 0;
|
| + return nullptr;
|
| + }
|
| + std::unique_ptr<char[]> buf(new char[total_buf_size]);
|
| + char* buf_pos = buf.get();
|
| + for (size_t i = 0; i < serialized_pages.size(); ++i) {
|
| + size_t size = serialized_pages[i].data.size();
|
| + memcpy(buf_pos, &size, sizeof(size_t));
|
| + buf_pos += sizeof(size_t);
|
| + memcpy(buf_pos, &serialized_pages[i].width, sizeof(SkScalar));
|
| + buf_pos += sizeof(SkScalar);
|
| + memcpy(buf_pos, &serialized_pages[i].height, sizeof(SkScalar));
|
| + buf_pos += sizeof(SkScalar);
|
| + memcpy(buf_pos, serialized_pages[i].data.data(), size);
|
| + buf_pos += size;
|
| + }
|
| + *size = total_buf_size;
|
| + return buf;
|
| +}
|
| +
|
| +void PdfMetafileSkia::GetSkp(SkWStream* stream) const {
|
| + if (data_->pages_.size() >= 1)
|
| + data_->pages_[0].content_->newPictureSnapshot()->serialize(stream);
|
| +}
|
| +
|
| +void PdfMetafileSkia::ConvertPagesToPdf() {
|
| + SkDynamicMemoryWStream stream;
|
| + sk_sp<SkDocument> doc = MakePdfDocument(&stream);
|
| +
|
| + for (const Page& page : data_->pages_) {
|
| + SkCanvas* canvas = doc->beginPage(page.size_.width(), page.size_.height());
|
| + canvas->drawPicture(page.content_->newPictureSnapshot());
|
| + doc->endPage();
|
| + }
|
| + doc->close();
|
| +
|
| + data_->pdf_data_.reset(stream.detachAsStream());
|
| +}
|
| +
|
| uint32_t PdfMetafileSkia::GetDataSize() const {
|
| if (!data_->pdf_data_)
|
| return 0;
|
| @@ -320,8 +419,8 @@ std::unique_ptr<PdfMetafileSkia> PdfMetafileSkia::GetMetafileForCurrentPage(
|
|
|
| metafile->data_->pages_.push_back(data_->pages_.back());
|
|
|
| - if (!metafile->FinishDocument()) // Generate PDF.
|
| - metafile.reset();
|
| + // if (!metafile->FinishDocument()) // Generate PDF.
|
| + // metafile.reset();
|
|
|
| return metafile;
|
| }
|
|
|