diff options
author | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-18 21:49:20 +0000 |
---|---|---|
committer | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-18 21:49:20 +0000 |
commit | b5cf844c86b06367280e5bf5b3584c9a284cd10d (patch) | |
tree | bdcc07d666ef0e5c1b99ac8598c9bb0d6be417c4 /printing | |
parent | 68c6f395372974da145e57d31974a6f1d1b4fdc5 (diff) | |
download | chromium_src-b5cf844c86b06367280e5bf5b3584c9a284cd10d.zip chromium_src-b5cf844c86b06367280e5bf5b3584c9a284cd10d.tar.gz chromium_src-b5cf844c86b06367280e5bf5b3584c9a284cd10d.tar.bz2 |
Mac printing: Autorotate printed pages so their orientation is the same as the destination page.
BUG=93303,132922
TEST=manual
Review URL: https://chromiumcodereview.appspot.com/10560021
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142824 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'printing')
-rw-r--r-- | printing/image_mac.cc | 7 | ||||
-rw-r--r-- | printing/metafile.h | 54 | ||||
-rw-r--r-- | printing/pdf_metafile_cg_mac.cc | 75 | ||||
-rw-r--r-- | printing/pdf_metafile_cg_mac.h | 9 | ||||
-rw-r--r-- | printing/pdf_metafile_skia.cc | 9 | ||||
-rw-r--r-- | printing/pdf_metafile_skia.h | 9 | ||||
-rw-r--r-- | printing/printed_document_mac.cc | 7 |
7 files changed, 99 insertions, 71 deletions
diff --git a/printing/image_mac.cc b/printing/image_mac.cc index 1ed9e0c..7d45178 100644 --- a/printing/image_mac.cc +++ b/printing/image_mac.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -33,9 +33,10 @@ bool Image::LoadMetafile(const Metafile& metafile) { kCGImageAlphaPremultipliedLast)); DCHECK(bitmap_context.get()); + struct Metafile::MacRenderPageParams params; + params.shrink_to_fit = true; metafile.RenderPage(page_number, bitmap_context, - CGRectMake(0, 0, size_.width(), size_.height()), - true, false, false, false); + CGRectMake(0, 0, size_.width(), size_.height()), params); return true; } diff --git a/printing/metafile.h b/printing/metafile.h index 8720f3a..a73c850 100644 --- a/printing/metafile.h +++ b/printing/metafile.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -39,6 +39,37 @@ namespace printing { // (usually PDF or EMF). class PRINTING_EXPORT Metafile { public: +#if defined(OS_MACOSX) + // |shrink_to_fit| specifies whether the output should be shrunk to fit a + // destination page if the source PDF is bigger than the destination page in + // any dimension. If this is false, parts of the source PDF page that lie + // outside the bounds will be clipped. + // |stretch_to_fit| specifies whether the output should be stretched to fit + // the destination page if the source page size is smaller in all dimensions. + // |center_horizontally| specifies whether the output (after any scaling is + // done) should be centered horizontally within the destination page. + // |center_vertically| specifies whether the output (after any scaling is + // done) should be centered vertically within the destination page. + // Note that all scaling preserves the original aspect ratio of the page. + // |autorotate| specifies whether the source PDF should be autorotated to fit + // on the destination page. + struct MacRenderPageParams { + MacRenderPageParams() + : shrink_to_fit(false), + stretch_to_fit(false), + center_horizontally(false), + center_vertically(false), + autorotate(false) { + } + + bool shrink_to_fit; + bool stretch_to_fit; + bool center_horizontally; + bool center_vertically; + bool autorotate; + }; +#endif // defined(OS_MACOSX) + virtual ~Metafile() {} // Initializes a fresh new metafile for rendering. Returns false on failure. @@ -116,27 +147,12 @@ class PRINTING_EXPORT Metafile { virtual HENHMETAFILE emf() const = 0; #elif defined(OS_MACOSX) // Renders the given page into |rect| in the given context. - // Pages use a 1-based index. The rendering uses the following arguments - // to determine scaling and translation factors. - // |shrink_to_fit| specifies whether the output should be shrunk to fit the - // supplied |rect| if the page size is larger than |rect| in any dimension. - // If this is false, parts of the PDF page that lie outside the bounds will be - // clipped. - // |stretch_to_fit| specifies whether the output should be stretched to fit - // the supplied bounds if the page size is smaller than |rect| in all - // dimensions. - // |center_horizontally| specifies whether the final image (after any scaling - // is done) should be centered horizontally within the given |rect|. - // |center_vertically| specifies whether the final image (after any scaling - // is done) should be centered vertically within the given |rect|. - // Note that all scaling preserves the original aspect ratio of the page. + // Pages use a 1-based index. The rendering uses the arguments in + // |params| to determine scaling, translation, and rotation. virtual bool RenderPage(unsigned int page_number, gfx::NativeDrawingContext context, const CGRect rect, - bool shrink_to_fit, - bool stretch_to_fit, - bool center_horizontally, - bool center_vertically) const = 0; + const MacRenderPageParams& params) const = 0; #elif defined(OS_CHROMEOS) // Saves the underlying data to the file associated with fd. This function // should ONLY be called after the metafile is closed. diff --git a/printing/pdf_metafile_cg_mac.cc b/printing/pdf_metafile_cg_mac.cc index 6ac1d6b..6b4e7f3 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 <algorithm> + #include "base/file_path.h" #include "base/lazy_instance.h" #include "base/logging.h" @@ -172,10 +174,7 @@ bool PdfMetafileCg::FinishDocument() { bool PdfMetafileCg::RenderPage(unsigned int page_number, CGContextRef context, const CGRect rect, - bool shrink_to_fit, - bool stretch_to_fit, - bool center_horizontally, - bool center_vertically) const { + const MacRenderPageParams& params) const { CGPDFDocumentRef pdf_doc = GetPDFDocument(); if (!pdf_doc) { LOG(ERROR) << "Unable to create PDF document from data"; @@ -184,38 +183,60 @@ bool PdfMetafileCg::RenderPage(unsigned int page_number, CGPDFPageRef pdf_page = CGPDFDocumentGetPage(pdf_doc, page_number); CGRect source_rect = CGPDFPageGetBoxRect(pdf_page, kCGPDFCropBox); float scaling_factor = 1.0; + const bool source_is_landscape = + (source_rect.size.width > source_rect.size.height); + const bool dest_is_landscape = (rect.size.width > rect.size.height); + const bool rotate = + params.autorotate ? (source_is_landscape != dest_is_landscape) : false; + const float source_width = + rotate ? source_rect.size.height : source_rect.size.width; + const float source_height = + rotate ? source_rect.size.width : source_rect.size.height; + // See if we need to scale the output. - bool scaling_needed = - (shrink_to_fit && ((source_rect.size.width > rect.size.width) || - (source_rect.size.height > rect.size.height))) || - (stretch_to_fit && (source_rect.size.width < rect.size.width) && - (source_rect.size.height < rect.size.height)); + const bool scaling_needed = + (params.shrink_to_fit && ((source_width > rect.size.width) || + (source_height > rect.size.height))) || + (params.stretch_to_fit && ((source_width < rect.size.width) && + (source_height < rect.size.height))); if (scaling_needed) { - float x_scaling_factor = rect.size.width / source_rect.size.width; - float y_scaling_factor = rect.size.height / source_rect.size.height; - if (x_scaling_factor > y_scaling_factor) { - scaling_factor = y_scaling_factor; - } else { - scaling_factor = x_scaling_factor; - } + float x_scaling_factor = rect.size.width / source_width; + float y_scaling_factor = rect.size.height / source_height; + scaling_factor = std::min(x_scaling_factor, y_scaling_factor); } - // Some PDFs have a non-zero origin. Need to take that into account. - float x_offset = -1 * source_rect.origin.x * scaling_factor; - float y_offset = -1 * source_rect.origin.y * scaling_factor; + // Some PDFs have a non-zero origin. Need to take that into account and align + // the PDF to the origin. + const float x_origin_offset = -1 * source_rect.origin.x; + const float y_origin_offset = -1 * source_rect.origin.y; + + // If the PDF needs to be centered, calculate the offsets here. + float x_offset = params.center_horizontally ? + ((rect.size.width - (source_width * scaling_factor)) / 2) : 0; + if (rotate) + x_offset = -x_offset; + + float y_offset = params.center_vertically ? + ((rect.size.height - (source_height * scaling_factor)) / 2) : 0; - if (center_horizontally) { - x_offset += (rect.size.width - - (source_rect.size.width * scaling_factor))/2; - } - if (center_vertically) { - y_offset += (rect.size.height - - (source_rect.size.height * scaling_factor))/2; - } CGContextSaveGState(context); + + // The transform operations specified here gets applied in reverse order. + // i.e. the origin offset translation happens first. + // Origin is at bottom-left. CGContextTranslateCTM(context, x_offset, y_offset); + if (rotate) { + // After rotating by 90 degrees with the axis at the origin, the page + // content is now "off screen". Shift it right to move it back on screen. + CGContextTranslateCTM(context, rect.size.width, 0); + // Rotates counter-clockwise by 90 degrees. + CGContextRotateCTM(context, M_PI_2); + } CGContextScaleCTM(context, scaling_factor, scaling_factor); + CGContextTranslateCTM(context, x_origin_offset, y_origin_offset); + CGContextDrawPDFPage(context, pdf_page); CGContextRestoreGState(context); + return true; } diff --git a/printing/pdf_metafile_cg_mac.h b/printing/pdf_metafile_cg_mac.h index 3ffb40d..09fad56 100644 --- a/printing/pdf_metafile_cg_mac.h +++ b/printing/pdf_metafile_cg_mac.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -58,12 +58,9 @@ class PRINTING_EXPORT PdfMetafileCg : public Metafile { virtual CGContextRef context() const OVERRIDE; virtual bool RenderPage(unsigned int page_number, - CGContextRef context, + gfx::NativeDrawingContext context, const CGRect rect, - bool shrink_to_fit, - bool stretch_to_fit, - bool center_horizontally, - bool center_vertically) const OVERRIDE; + const MacRenderPageParams& params) const OVERRIDE; private: // Returns a CGPDFDocumentRef version of pdf_data_. diff --git a/printing/pdf_metafile_skia.cc b/printing/pdf_metafile_skia.cc index b1b35ed..06d0286 100644 --- a/printing/pdf_metafile_skia.cc +++ b/printing/pdf_metafile_skia.cc @@ -180,18 +180,13 @@ http://codereview.chromium.org/7200040/diff/1/webkit/plugins/ppapi/ppapi_plugin_ bool PdfMetafileSkia::RenderPage(unsigned int page_number, CGContextRef context, const CGRect rect, - bool shrink_to_fit, - bool stretch_to_fit, - bool center_horizontally, - bool center_vertically) const { + const MacRenderPageParams& params) const { DCHECK_GT(data_->pdf_stream_.getOffset(), 0U); if (data_->pdf_cg_.GetDataSize() == 0) { SkAutoDataUnref data(data_->pdf_stream_.copyToData()); data_->pdf_cg_.InitFromData(data.bytes(), data.size()); } - return data_->pdf_cg_.RenderPage(page_number, context, rect, shrink_to_fit, - stretch_to_fit, center_horizontally, - center_vertically); + return data_->pdf_cg_.RenderPage(page_number, context, rect, params); } #endif diff --git a/printing/pdf_metafile_skia.h b/printing/pdf_metafile_skia.h index 64aecc0..7a1a9da 100644 --- a/printing/pdf_metafile_skia.h +++ b/printing/pdf_metafile_skia.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -58,12 +58,9 @@ class PRINTING_EXPORT PdfMetafileSkia : public Metafile { virtual HENHMETAFILE emf() const OVERRIDE; #elif defined(OS_MACOSX) virtual bool RenderPage(unsigned int page_number, - CGContextRef context, + gfx::NativeDrawingContext context, const CGRect rect, - bool shrink_to_fit, - bool stretch_to_fit, - bool center_horizontally, - bool center_vertically) const OVERRIDE; + const MacRenderPageParams& params) const OVERRIDE; #endif #if defined(OS_CHROMEOS) diff --git a/printing/printed_document_mac.cc b/printing/printed_document_mac.cc index 3a7a1f0b..cc671e1 100644 --- a/printing/printed_document_mac.cc +++ b/printing/printed_document_mac.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -32,8 +32,9 @@ void PrintedDocument::RenderPrintedPage( const Metafile* metafile = page.metafile(); // Each Metafile is a one-page PDF, and pages use 1-based indexing. const int page_number = 1; - metafile->RenderPage(page_number, context, content_area.ToCGRect(), - false, false, false, false); + struct Metafile::MacRenderPageParams params; + params.autorotate = true; + metafile->RenderPage(page_number, context, content_area.ToCGRect(), params); } } // namespace printing |