summaryrefslogtreecommitdiffstats
path: root/printing/pdf_metafile_skia.cc
diff options
context:
space:
mode:
authorvitalybuka <vitalybuka@chromium.org>2014-11-17 17:25:59 -0800
committerCommit bot <commit-bot@chromium.org>2014-11-18 01:26:13 +0000
commitd054bfdd5eb4a364d1aa7dbf139018d3b9b885b3 (patch)
tree1eeefe8b06f17c883921e5ef3818b51a38b882b7 /printing/pdf_metafile_skia.cc
parent76c3721a7142d3abec14f849c583a4a9d8c593c8 (diff)
downloadchromium_src-d054bfdd5eb4a364d1aa7dbf139018d3b9b885b3.zip
chromium_src-d054bfdd5eb4a364d1aa7dbf139018d3b9b885b3.tar.gz
chromium_src-d054bfdd5eb4a364d1aa7dbf139018d3b9b885b3.tar.bz2
Revert of Remove calls to deprecated SkPDFDevice and SkPDFDocuemnt. (patchset #4 id:370001 of https://codereview.chromium.org/694213002/)
Reason for revert: Breaks printing. BUG=434079 Original issue's description: > Remove calls to deprecated SkPDFDevice and SkPDFDocuemnt. > > In the PdfMetafileSkia class, Instead of storing a > SkPDFDocument, store a vector of pages as > SkPictures. This allows access to individual at any > time. When FinishDocument() is called, use the > SkDocument API to print all pages to PDF. > > BUG=278148 > > Committed: https://crrev.com/816b7105b078f7300f825cd81f379e312efdb821 > Cr-Commit-Position: refs/heads/master@{#304379} TBR=robertphillips@google.com,reed@google.com,halcanary@google.com BUG=278148 Review URL: https://codereview.chromium.org/731143004 Cr-Commit-Position: refs/heads/master@{#304536}
Diffstat (limited to 'printing/pdf_metafile_skia.cc')
-rw-r--r--printing/pdf_metafile_skia.cc235
1 files changed, 85 insertions, 150 deletions
diff --git a/printing/pdf_metafile_skia.cc b/printing/pdf_metafile_skia.cc
index e00ca9f..c63e308 100644
--- a/printing/pdf_metafile_skia.cc
+++ b/printing/pdf_metafile_skia.cc
@@ -12,13 +12,12 @@
#include "skia/ext/refptr.h"
#include "skia/ext/vector_canvas.h"
#include "third_party/skia/include/core/SkData.h"
-#include "third_party/skia/include/core/SkDocument.h"
-#include "third_party/skia/include/core/SkPictureRecorder.h"
-#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkScalar.h"
-#include "third_party/skia/include/core/SkSize.h"
#include "third_party/skia/include/core/SkStream.h"
+#include "third_party/skia/include/core/SkTypeface.h"
+#include "third_party/skia/include/pdf/SkPDFDevice.h"
+#include "third_party/skia/include/pdf/SkPDFDocument.h"
#include "ui/gfx/point.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
@@ -31,56 +30,13 @@
#include "base/file_descriptor_posix.h"
#endif
-namespace {
-// This struct represents all the data we need to draw and redraw this
-// page into a SkDocument.
-struct Page {
- Page(const SkSize& page_size, const SkRect& content_area)
- : page_size_(page_size),
- content_area_(content_area),
- content_(/*NULL*/) {}
- SkSize page_size_;
- SkRect content_area_;
- skia::RefPtr<SkPicture> content_;
-};
-} // namespace
-
-static SkSize ToSkSize(const gfx::Size& size) {
- return SkSize::Make(SkIntToScalar(size.width()),
- SkIntToScalar(size.height()));
-}
-
-static SkRect ToSkRect(const gfx::Rect& rect) {
- return SkRect::MakeLTRB(SkIntToScalar(rect.x()), SkIntToScalar(rect.y()),
- SkIntToScalar(rect.right()),
- SkIntToScalar(rect.bottom()));
-}
-
-static gfx::Size ToGfxSize(const SkSize& size) {
- return gfx::Size(SkScalarTruncToInt(size.width()),
- SkScalarTruncToInt(size.height()));
-}
-
-static bool WriteAssetToBuffer(SkStreamAsset* asset,
- void* buffer,
- size_t size) {
- DCHECK(asset->getPosition() == 0); // Be kind: please rewind.
- size_t length = asset->getLength();
- if (length > size)
- return false;
- bool success = (length == asset->read(buffer, length));
- (void)asset->rewind();
- return success;
-}
-
namespace printing {
struct PdfMetafileSkiaData {
- scoped_ptr<SkPictureRecorder> recorder_; // Current recording
-
- std::vector<Page> pages_;
- skia::RefPtr<SkStreamAsset> pdf_data_;
-
+ skia::RefPtr<SkPDFDevice> current_page_;
+ skia::RefPtr<SkCanvas> current_page_canvas_;
+ SkPDFDocument pdf_doc_;
+ SkDynamicMemoryWStream pdf_stream_;
#if defined(OS_MACOSX)
PdfMetafileCg pdf_cg_;
#endif
@@ -91,37 +47,31 @@ PdfMetafileSkia::~PdfMetafileSkia() {}
bool PdfMetafileSkia::Init() {
return true;
}
-
-// TODO(halcanary): Create a Metafile class that only stores data.
-// Metafile::InitFromData is orthogonal to what the rest of
-// PdfMetafileSkia does.
bool PdfMetafileSkia::InitFromData(const void* src_buffer,
uint32 src_buffer_size) {
- if (data_->pdf_data_)
- data_->pdf_data_.clear(); // free up RAM first.
- SkDynamicMemoryWStream dynamic_memory;
- if (!dynamic_memory.write(src_buffer, src_buffer_size))
- return false;
- data_->pdf_data_ = skia::AdoptRef(dynamic_memory.detachAsStream());
- return true;
+ return data_->pdf_stream_.write(src_buffer, src_buffer_size);
}
bool PdfMetafileSkia::StartPage(const gfx::Size& page_size,
const gfx::Rect& content_area,
const float& scale_factor) {
- if (data_->recorder_)
- this->FinishPage();
- DCHECK(!data_->recorder_);
- data_->recorder_.reset(SkNEW(SkPictureRecorder));
- SkSize sk_page_size = ToSkSize(page_size);
- data_->pages_.push_back(Page(sk_page_size, ToSkRect(content_area)));
-
- SkCanvas* recordingCanvas = data_->recorder_->beginRecording(
- sk_page_size.width(), sk_page_size.height(), NULL, 0);
- // recordingCanvas is owned by the data_->recorder_. No ref() necessary.
- if (!recordingCanvas)
- return false;
- recordingCanvas->scale(scale_factor, scale_factor);
+ DCHECK(!data_->current_page_canvas_);
+
+ // Adjust for the margins and apply the scale factor.
+ SkMatrix transform;
+ transform.setTranslate(SkIntToScalar(content_area.x()),
+ SkIntToScalar(content_area.y()));
+ transform.preScale(SkFloatToScalar(scale_factor),
+ SkFloatToScalar(scale_factor));
+
+ SkISize pdf_page_size = SkISize::Make(page_size.width(), page_size.height());
+ SkISize pdf_content_size =
+ SkISize::Make(content_area.width(), content_area.height());
+
+ data_->current_page_ = skia::AdoptRef(
+ new SkPDFDevice(pdf_page_size, pdf_content_size, transform));
+ data_->current_page_canvas_ =
+ skia::AdoptRef(new SkCanvas(data_->current_page_.get()));
return true;
}
@@ -131,65 +81,68 @@ skia::VectorCanvas* PdfMetafileSkia::GetVectorCanvasForNewPage(
const float& scale_factor) {
if (!StartPage(page_size, content_area, scale_factor))
return nullptr;
- return data_->recorder_->getRecordingCanvas();
+ return data_->current_page_canvas_.get();
}
bool PdfMetafileSkia::FinishPage() {
- if (!data_->recorder_)
- return false;
- DCHECK(!(data_->pages_.back().content_));
- data_->pages_.back().content_ =
- skia::AdoptRef(data_->recorder_->endRecording());
- data_->recorder_.reset();
+ DCHECK(data_->current_page_canvas_);
+ DCHECK(data_->current_page_);
+
+ data_->current_page_canvas_.clear(); // Unref SkCanvas.
+ data_->pdf_doc_.appendPage(data_->current_page_.get());
return true;
}
bool PdfMetafileSkia::FinishDocument() {
- // If we've already set the data in InitFromData, overwrite it.
- if (data_->pdf_data_)
- data_->pdf_data_.clear(); // Free up RAM first.
-
- if (data_->recorder_)
- this->FinishPage();
-
- SkDynamicMemoryWStream pdf_stream;
- skia::RefPtr<SkDocument> pdf_doc =
- skia::AdoptRef(SkDocument::CreatePDF(&pdf_stream));
- for (const auto& page : data_->pages_) {
- SkCanvas* canvas = pdf_doc->beginPage(
- page.page_size_.width(), page.page_size_.height(), &page.content_area_);
- canvas->drawPicture(page.content_.get());
- pdf_doc->endPage();
+ // Don't do anything if we've already set the data in InitFromData.
+ if (data_->pdf_stream_.getOffset())
+ return true;
+
+ if (data_->current_page_canvas_)
+ FinishPage();
+
+ data_->current_page_.clear();
+
+ int font_counts[SkAdvancedTypefaceMetrics::kOther_Font + 2];
+ data_->pdf_doc_.getCountOfFontTypes(font_counts);
+ for (int type = 0;
+ type <= SkAdvancedTypefaceMetrics::kOther_Font + 1;
+ type++) {
+ for (int count = 0; count < font_counts[type]; count++) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "PrintPreview.FontType", type,
+ SkAdvancedTypefaceMetrics::kOther_Font + 2);
+ }
}
- if (!pdf_doc->close())
- return false;
- data_->pdf_data_ = skia::AdoptRef(pdf_stream.detachAsStream());
- return true;
+ return data_->pdf_doc_.emitPDF(&data_->pdf_stream_);
}
uint32 PdfMetafileSkia::GetDataSize() const {
- if (!data_->pdf_data_)
- return 0;
- return base::checked_cast<uint32>(data_->pdf_data_->getLength());
+ return base::checked_cast<uint32>(data_->pdf_stream_.getOffset());
}
bool PdfMetafileSkia::GetData(void* dst_buffer,
uint32 dst_buffer_size) const {
- if (!data_->pdf_data_)
+ if (dst_buffer_size < GetDataSize())
return false;
- return WriteAssetToBuffer(data_->pdf_data_.get(), dst_buffer,
- base::checked_cast<size_t>(dst_buffer_size));
+
+ SkAutoDataUnref data(data_->pdf_stream_.copyToData());
+ memcpy(dst_buffer, data->bytes(), dst_buffer_size);
+ return true;
}
gfx::Rect PdfMetafileSkia::GetPageBounds(unsigned int page_number) const {
- if (page_number < data_->pages_.size())
- return gfx::Rect(ToGfxSize(data_->pages_[page_number].page_size_));
+ // TODO(vandebo) add a method to get the page size for a given page to
+ // SkPDFDocument.
+ NOTIMPLEMENTED();
return gfx::Rect();
}
unsigned int PdfMetafileSkia::GetPageCount() const {
- return base::checked_cast<unsigned int>(data_->pages_.size());
+ // TODO(vandebo) add a method to get the number of pages to SkPDFDocument.
+ NOTIMPLEMENTED();
+ return 0;
}
gfx::NativeDrawingContext PdfMetafileSkia::context() const {
@@ -221,14 +174,10 @@ bool PdfMetafileSkia::RenderPage(unsigned int page_number,
CGContextRef context,
const CGRect rect,
const MacRenderPageParams& params) const {
- DCHECK_GT(GetDataSize(), 0U);
+ DCHECK_GT(data_->pdf_stream_.getOffset(), 0U);
if (data_->pdf_cg_.GetDataSize() == 0) {
- if (GetDataSize() == 0)
- return false;
- size_t length = data_->pdf_data_->getLength();
- std::vector<uint8_t> buffer(length);
- (void)WriteAssetToBuffer(data_->pdf_data_.get(), &buffer[0], length);
- data_->pdf_cg_.InitFromData(&buffer[0], base::checked_cast<uint32>(length));
+ SkAutoDataUnref data(data_->pdf_stream_.copyToData());
+ data_->pdf_cg_.InitFromData(data->bytes(), data->size());
}
return data_->pdf_cg_.RenderPage(page_number, context, rect, params);
}
@@ -237,31 +186,17 @@ bool PdfMetafileSkia::RenderPage(unsigned int page_number,
bool PdfMetafileSkia::SaveTo(base::File* file) const {
if (GetDataSize() == 0U)
return false;
- DCHECK(data_->pdf_data_.get());
- SkStreamAsset* asset = data_->pdf_data_.get();
- DCHECK_EQ(asset->getPosition(), 0U);
-
- const size_t maximum_buffer_size = 1024 * 1024;
- std::vector<char> buffer(std::min(maximum_buffer_size, asset->getLength()));
- do {
- size_t read_size = asset->read(&buffer[0], buffer.size());
- if (read_size == 0)
- break;
- DCHECK_GE(buffer.size(), read_size);
- if (!file->WriteAtCurrentPos(&buffer[0],
- base::checked_cast<int>(read_size))) {
- (void)asset->rewind();
- return false;
- }
- } while (!asset->isAtEnd());
-
- (void)asset->rewind();
- return true;
+ SkAutoDataUnref data(data_->pdf_stream_.copyToData());
+ // TODO(halcanary): rewrite this function without extra data copy
+ // using SkStreamAsset.
+ const char* ptr = reinterpret_cast<const char*>(data->data());
+ int size = base::checked_cast<int>(data->size());
+ return file->WriteAtCurrentPos(ptr, size) == size;
}
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
bool PdfMetafileSkia::SaveToFD(const base::FileDescriptor& fd) const {
- DCHECK_GT(GetDataSize(), 0U);
+ DCHECK_GT(data_->pdf_stream_.getOffset(), 0U);
if (fd.fd < 0) {
DLOG(ERROR) << "Invalid file descriptor!";
@@ -281,24 +216,24 @@ PdfMetafileSkia::PdfMetafileSkia() : data_(new PdfMetafileSkiaData) {
}
scoped_ptr<PdfMetafileSkia> PdfMetafileSkia::GetMetafileForCurrentPage() {
- // If we only ever need the metafile for the last page, should we
- // only keep a handle on one SkPicture?
- scoped_ptr<PdfMetafileSkia> metafile(new PdfMetafileSkia);
-
- if (data_->pages_.size() == 0)
+ scoped_ptr<PdfMetafileSkia> metafile;
+ SkPDFDocument pdf_doc(SkPDFDocument::kDraftMode_Flags);
+ if (!pdf_doc.appendPage(data_->current_page_.get()))
return metafile.Pass();
- if (data_->recorder_) // page outstanding
+ SkDynamicMemoryWStream pdf_stream;
+ if (!pdf_doc.emitPDF(&pdf_stream))
return metafile.Pass();
- const Page& page = data_->pages_.back();
-
- metafile->data_->pages_.push_back(page); // Copy page data;
- // Should increment refcnt on page->content_.
+ SkAutoDataUnref data_copy(pdf_stream.copyToData());
+ if (data_copy->size() == 0)
+ return scoped_ptr<PdfMetafileSkia>();
- if (!metafile->FinishDocument()) // Generate PDF.
+ metafile.reset(new PdfMetafileSkia);
+ if (!metafile->InitFromData(data_copy->bytes(),
+ base::checked_cast<uint32>(data_copy->size()))) {
metafile.reset();
-
+ }
return metafile.Pass();
}