summaryrefslogtreecommitdiffstats
path: root/printing
diff options
context:
space:
mode:
authorthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-18 21:49:20 +0000
committerthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-18 21:49:20 +0000
commitb5cf844c86b06367280e5bf5b3584c9a284cd10d (patch)
treebdcc07d666ef0e5c1b99ac8598c9bb0d6be417c4 /printing
parent68c6f395372974da145e57d31974a6f1d1b4fdc5 (diff)
downloadchromium_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.cc7
-rw-r--r--printing/metafile.h54
-rw-r--r--printing/pdf_metafile_cg_mac.cc75
-rw-r--r--printing/pdf_metafile_cg_mac.h9
-rw-r--r--printing/pdf_metafile_skia.cc9
-rw-r--r--printing/pdf_metafile_skia.h9
-rw-r--r--printing/printed_document_mac.cc7
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