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/pdf_metafile_cg_mac.cc | |
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/pdf_metafile_cg_mac.cc')
-rw-r--r-- | printing/pdf_metafile_cg_mac.cc | 75 |
1 files changed, 48 insertions, 27 deletions
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; } |