diff options
author | vitalybuka <vitalybuka@chromium.org> | 2014-11-17 17:25:59 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-11-18 01:26:13 +0000 |
commit | d054bfdd5eb4a364d1aa7dbf139018d3b9b885b3 (patch) | |
tree | 1eeefe8b06f17c883921e5ef3818b51a38b882b7 /printing | |
parent | 76c3721a7142d3abec14f849c583a4a9d8c593c8 (diff) | |
download | chromium_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')
-rw-r--r-- | printing/pdf_metafile_skia.cc | 235 |
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(); } |