Chromium Code Reviews| Index: printing/pdf_metafile_cg_mac.cc |
| =================================================================== |
| --- printing/pdf_metafile_cg_mac.cc (revision 142466) |
| +++ printing/pdf_metafile_cg_mac.cc (working copy) |
| @@ -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" |
| @@ -175,7 +177,8 @@ |
| bool shrink_to_fit, |
| bool stretch_to_fit, |
| bool center_horizontally, |
| - bool center_vertically) const { |
| + bool center_vertically, |
| + bool autorotate) const { |
| CGPDFDocumentRef pdf_doc = GetPDFDocument(); |
| if (!pdf_doc) { |
| LOG(ERROR) << "Unable to create PDF document from data"; |
| @@ -184,38 +187,58 @@ |
| 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 = |
| + 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 = |
| + (shrink_to_fit && ((source_width > rect.size.width) || |
| + (source_height > rect.size.height))) || |
| + (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 (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; |
| - } |
| + // If the PDF needs to be centered, calculate the offsets here. |
| + float x_offset = center_horizontally ? |
| + ((rect.size.width - (source_width * scaling_factor)) / 2) : 0; |
| + if (rotate) |
| + x_offset = -x_offset; |
| + |
| + float y_offset = center_vertically ? |
| + ((rect.size.height - (source_height * scaling_factor)) / 2) : 0; |
| + |
| 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); |
|
kmadhusu
2012/06/16 00:44:11
Why can't we do a single Translation operation lik
Lei Zhang
2012/06/16 01:47:20
We may be able to, but it's easier to visualize wh
|
| + if (rotate) { |
| + CGContextTranslateCTM(context, rect.size.width, 0); |
|
kmadhusu
2012/06/16 00:44:11
Can you add a comment on why we need to do this tr
Lei Zhang
2012/06/16 01:47:20
Done.
|
| + // 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; |
| } |
| @@ -269,7 +292,7 @@ |
| DCHECK(pdf_data_.get()); |
| DCHECK(!context_.get()); |
| - std::string path_string = file_path.value(); |
| + const std::string& path_string = file_path.value(); |
| ScopedCFTypeRef<CFURLRef> path_url(CFURLCreateFromFileSystemRepresentation( |
| kCFAllocatorDefault, reinterpret_cast<const UInt8*>(path_string.c_str()), |
| path_string.length(), false)); |