| Index: printing/pdf_metafile_cg_mac.cc
|
| diff --git a/printing/pdf_metafile_cg_mac.cc b/printing/pdf_metafile_cg_mac.cc
|
| index 16744bfde6c702ab27c3e3fa91df1cde8bd6148f..f339dae3545911de4ef9989eb3f8849bf761fe49 100644
|
| --- a/printing/pdf_metafile_cg_mac.cc
|
| +++ b/printing/pdf_metafile_cg_mac.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "printing/pdf_metafile_cg_mac.h"
|
|
|
| +#include <ApplicationServices/ApplicationServices.h>
|
| +#include <CoreFoundation/CoreFoundation.h>
|
| #include <stdint.h>
|
|
|
| #include <algorithm>
|
| @@ -57,116 +59,41 @@ void RotatePage(CGContextRef context, const CGRect rect, int num_rotations) {
|
|
|
| namespace printing {
|
|
|
| -PdfMetafileCg::PdfMetafileCg() : page_is_open_(false) {}
|
| -
|
| -PdfMetafileCg::~PdfMetafileCg() {}
|
| -
|
| -bool PdfMetafileCg::Init() {
|
| - // Ensure that Init hasn't already been called.
|
| - DCHECK(!context_.get());
|
| - DCHECK(!pdf_data_.get());
|
| -
|
| - pdf_data_.reset(CFDataCreateMutable(kCFAllocatorDefault, 0));
|
| - if (!pdf_data_.get()) {
|
| - LOG(ERROR) << "Failed to create pdf data for metafile";
|
| +/* TODO(caryclark): The set up of PluginInstance::PrintPDFOutput may result in
|
| + rasterized output. Even if that flow uses PdfMetafileCg::RenderPage,
|
| + the drawing of the PDF into the canvas may result in a rasterized output.
|
| + PDFMetafileSkia::RenderPage should be not implemented as shown and instead
|
| + should do something like the following CL in PluginInstance::PrintPDFOutput:
|
| + http://codereview.chromium.org/7200040/diff/1/webkit/plugins/ppapi/ppapi_plugin_instance.cc
|
| +*/
|
| +bool PdfMetafileCg::RenderPage(const void* src_buffer,
|
| + size_t src_buffer_size,
|
| + unsigned int page_number,
|
| + CGContextRef context,
|
| + const CGRect rect,
|
| + const PdfMetafileCg::RenderPageParams& params) {
|
| + if (!src_buffer || !src_buffer_size) {
|
| + LOG(ERROR) << "Empty PDF document";
|
| return false;
|
| }
|
| - ScopedCFTypeRef<CGDataConsumerRef> pdf_consumer(
|
| - CGDataConsumerCreateWithCFData(pdf_data_));
|
| - if (!pdf_consumer.get()) {
|
| - LOG(ERROR) << "Failed to create data consumer for metafile";
|
| - pdf_data_.reset();
|
| + if (!base::IsValueInRangeForNumericType<CFIndex>(src_buffer_size)) {
|
| + LOG(ERROR) << "Src PDF too long";
|
| return false;
|
| }
|
| - context_.reset(CGPDFContextCreate(pdf_consumer, nullptr, nullptr));
|
| - if (!context_.get()) {
|
| - LOG(ERROR) << "Failed to create pdf context for metafile";
|
| - pdf_data_.reset();
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool PdfMetafileCg::InitFromData(const void* src_buffer,
|
| - size_t src_buffer_size) {
|
| - DCHECK(!context_.get());
|
| - DCHECK(!pdf_data_.get());
|
| -
|
| - if (!src_buffer || !src_buffer_size)
|
| - return false;
|
| -
|
| - if (!base::IsValueInRangeForNumericType<CFIndex>(src_buffer_size))
|
| - return false;
|
| -
|
| - pdf_data_.reset(CFDataCreateMutable(kCFAllocatorDefault, src_buffer_size));
|
| - CFDataAppendBytes(pdf_data_, static_cast<const UInt8*>(src_buffer),
|
| + base::ScopedCFTypeRef<CFMutableDataRef> pdf_data(
|
| + CFDataCreateMutable(kCFAllocatorDefault, src_buffer_size));
|
| + DCHECK(pdf_data.get());
|
| + CFDataAppendBytes(pdf_data, static_cast<const UInt8*>(src_buffer),
|
| src_buffer_size);
|
| -
|
| - return true;
|
| -}
|
| -
|
| -void PdfMetafileCg::StartPage(const gfx::Size& page_size,
|
| - const gfx::Rect& content_area,
|
| - const float& scale_factor) {
|
| - DCHECK(context_.get());
|
| - DCHECK(!page_is_open_);
|
| -
|
| - double height = page_size.height();
|
| - double width = page_size.width();
|
| -
|
| - CGRect bounds = CGRectMake(0, 0, width, height);
|
| - CGContextBeginPage(context_, &bounds);
|
| - page_is_open_ = true;
|
| - CGContextSaveGState(context_);
|
| -
|
| - // Move to the context origin.
|
| - CGContextTranslateCTM(context_, content_area.x(), -content_area.y());
|
| -
|
| - // Flip the context.
|
| - CGContextTranslateCTM(context_, 0, height);
|
| - CGContextScaleCTM(context_, scale_factor, -scale_factor);
|
| -}
|
| -
|
| -bool PdfMetafileCg::FinishPage() {
|
| - DCHECK(context_.get());
|
| - DCHECK(page_is_open_);
|
| -
|
| - CGContextRestoreGState(context_);
|
| - CGContextEndPage(context_);
|
| - page_is_open_ = false;
|
| - return true;
|
| -}
|
| -
|
| -bool PdfMetafileCg::FinishDocument() {
|
| - DCHECK(context_.get());
|
| - DCHECK(!page_is_open_);
|
| -
|
| -#ifndef NDEBUG
|
| - // Check that the context will be torn down properly; if it's not, pdf_data_
|
| - // will be incomplete and generate invalid PDF files/documents.
|
| - if (context_.get()) {
|
| - CFIndex extra_retain_count = CFGetRetainCount(context_.get()) - 1;
|
| - if (extra_retain_count > 0) {
|
| - LOG(ERROR) << "Metafile context has " << extra_retain_count
|
| - << " extra retain(s) on Close";
|
| - }
|
| - }
|
| -#endif
|
| - CGPDFContextClose(context_.get());
|
| - context_.reset();
|
| - return true;
|
| -}
|
| -
|
| -bool PdfMetafileCg::RenderPage(unsigned int page_number,
|
| - CGContextRef context,
|
| - const CGRect rect,
|
| - const MacRenderPageParams& params) const {
|
| - CGPDFDocumentRef pdf_doc = GetPDFDocument();
|
| - if (!pdf_doc) {
|
| + ScopedCFTypeRef<CGDataProviderRef> pdf_data_provider(
|
| + CGDataProviderCreateWithCFData(pdf_data));
|
| + base::ScopedCFTypeRef<CGPDFDocumentRef> pdf_doc(
|
| + CGPDFDocumentCreateWithProvider(pdf_data_provider));
|
| + if (!pdf_doc.get()) {
|
| LOG(ERROR) << "Unable to create PDF document from data";
|
| return false;
|
| }
|
| - CGPDFPageRef pdf_page = CGPDFDocumentGetPage(pdf_doc, page_number);
|
| + CGPDFPageRef pdf_page = CGPDFDocumentGetPage(pdf_doc.get(), page_number);
|
| CGRect source_rect = CGPDFPageGetBoxRect(pdf_page, kCGPDFCropBox);
|
| int pdf_src_rotation = CGPDFPageGetRotationAngle(pdf_page);
|
| float scaling_factor = 1.0;
|
| @@ -235,67 +162,4 @@ bool PdfMetafileCg::RenderPage(unsigned int page_number,
|
| return true;
|
| }
|
|
|
| -unsigned int PdfMetafileCg::GetPageCount() const {
|
| - CGPDFDocumentRef pdf_doc = GetPDFDocument();
|
| - return pdf_doc ? CGPDFDocumentGetNumberOfPages(pdf_doc) : 0;
|
| -}
|
| -
|
| -gfx::Rect PdfMetafileCg::GetPageBounds(unsigned int page_number) const {
|
| - CGPDFDocumentRef pdf_doc = GetPDFDocument();
|
| - if (!pdf_doc) {
|
| - LOG(ERROR) << "Unable to create PDF document from data";
|
| - return gfx::Rect();
|
| - }
|
| - if (page_number > GetPageCount()) {
|
| - LOG(ERROR) << "Invalid page number: " << page_number;
|
| - return gfx::Rect();
|
| - }
|
| - CGPDFPageRef pdf_page = CGPDFDocumentGetPage(pdf_doc, page_number);
|
| - CGRect page_rect = CGPDFPageGetBoxRect(pdf_page, kCGPDFMediaBox);
|
| - return gfx::Rect(page_rect);
|
| -}
|
| -
|
| -uint32_t PdfMetafileCg::GetDataSize() const {
|
| - // PDF data is only valid/complete once the context is released.
|
| - DCHECK(!context_);
|
| -
|
| - if (!pdf_data_)
|
| - return 0;
|
| - return static_cast<uint32_t>(CFDataGetLength(pdf_data_));
|
| -}
|
| -
|
| -bool PdfMetafileCg::GetData(void* dst_buffer, uint32_t dst_buffer_size) const {
|
| - // PDF data is only valid/complete once the context is released.
|
| - DCHECK(!context_);
|
| - DCHECK(pdf_data_);
|
| - DCHECK(dst_buffer);
|
| - DCHECK_GT(dst_buffer_size, 0U);
|
| -
|
| - uint32_t data_size = GetDataSize();
|
| - if (dst_buffer_size > data_size) {
|
| - return false;
|
| - }
|
| -
|
| - CFDataGetBytes(pdf_data_, CFRangeMake(0, dst_buffer_size),
|
| - static_cast<UInt8*>(dst_buffer));
|
| - return true;
|
| -}
|
| -
|
| -CGContextRef PdfMetafileCg::context() const {
|
| - return context_.get();
|
| -}
|
| -
|
| -CGPDFDocumentRef PdfMetafileCg::GetPDFDocument() const {
|
| - // Make sure that we have data, and that it's not being modified any more.
|
| - DCHECK(pdf_data_.get());
|
| - DCHECK(!context_.get());
|
| -
|
| - if (!pdf_doc_.get()) {
|
| - ScopedCFTypeRef<CGDataProviderRef> pdf_data_provider(
|
| - CGDataProviderCreateWithCFData(pdf_data_));
|
| - pdf_doc_.reset(CGPDFDocumentCreateWithProvider(pdf_data_provider));
|
| - }
|
| - return pdf_doc_.get();
|
| -}
|
| -
|
| } // namespace printing
|
|
|