Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: printing/pdf_metafile_cg_mac.cc

Issue 10560021: Mac printing: Autorotate printed pages so their orientation is the same as the destination page. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « printing/pdf_metafile_cg_mac.h ('k') | printing/pdf_metafile_skia.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "printing/pdf_metafile_cg_mac.h" 5 #include "printing/pdf_metafile_cg_mac.h"
6 6
7 #include <algorithm>
8
7 #include "base/file_path.h" 9 #include "base/file_path.h"
8 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
9 #include "base/logging.h" 11 #include "base/logging.h"
10 #include "base/mac/mac_util.h" 12 #include "base/mac/mac_util.h"
11 #include "base/mac/scoped_cftyperef.h" 13 #include "base/mac/scoped_cftyperef.h"
12 #include "base/sys_string_conversions.h" 14 #include "base/sys_string_conversions.h"
13 #include "base/threading/thread_local.h" 15 #include "base/threading/thread_local.h"
14 #include "ui/gfx/rect.h" 16 #include "ui/gfx/rect.h"
15 #include "ui/gfx/size.h" 17 #include "ui/gfx/size.h"
16 18
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 } 167 }
166 #endif 168 #endif
167 CGPDFContextClose(context_.get()); 169 CGPDFContextClose(context_.get());
168 context_.reset(NULL); 170 context_.reset(NULL);
169 return true; 171 return true;
170 } 172 }
171 173
172 bool PdfMetafileCg::RenderPage(unsigned int page_number, 174 bool PdfMetafileCg::RenderPage(unsigned int page_number,
173 CGContextRef context, 175 CGContextRef context,
174 const CGRect rect, 176 const CGRect rect,
175 bool shrink_to_fit, 177 const MacRenderPageParams& params) const {
176 bool stretch_to_fit,
177 bool center_horizontally,
178 bool center_vertically) const {
179 CGPDFDocumentRef pdf_doc = GetPDFDocument(); 178 CGPDFDocumentRef pdf_doc = GetPDFDocument();
180 if (!pdf_doc) { 179 if (!pdf_doc) {
181 LOG(ERROR) << "Unable to create PDF document from data"; 180 LOG(ERROR) << "Unable to create PDF document from data";
182 return false; 181 return false;
183 } 182 }
184 CGPDFPageRef pdf_page = CGPDFDocumentGetPage(pdf_doc, page_number); 183 CGPDFPageRef pdf_page = CGPDFDocumentGetPage(pdf_doc, page_number);
185 CGRect source_rect = CGPDFPageGetBoxRect(pdf_page, kCGPDFCropBox); 184 CGRect source_rect = CGPDFPageGetBoxRect(pdf_page, kCGPDFCropBox);
186 float scaling_factor = 1.0; 185 float scaling_factor = 1.0;
186 const bool source_is_landscape =
187 (source_rect.size.width > source_rect.size.height);
188 const bool dest_is_landscape = (rect.size.width > rect.size.height);
189 const bool rotate =
190 params.autorotate ? (source_is_landscape != dest_is_landscape) : false;
191 const float source_width =
192 rotate ? source_rect.size.height : source_rect.size.width;
193 const float source_height =
194 rotate ? source_rect.size.width : source_rect.size.height;
195
187 // See if we need to scale the output. 196 // See if we need to scale the output.
188 bool scaling_needed = 197 const bool scaling_needed =
189 (shrink_to_fit && ((source_rect.size.width > rect.size.width) || 198 (params.shrink_to_fit && ((source_width > rect.size.width) ||
190 (source_rect.size.height > rect.size.height))) || 199 (source_height > rect.size.height))) ||
191 (stretch_to_fit && (source_rect.size.width < rect.size.width) && 200 (params.stretch_to_fit && ((source_width < rect.size.width) &&
192 (source_rect.size.height < rect.size.height)); 201 (source_height < rect.size.height)));
193 if (scaling_needed) { 202 if (scaling_needed) {
194 float x_scaling_factor = rect.size.width / source_rect.size.width; 203 float x_scaling_factor = rect.size.width / source_width;
195 float y_scaling_factor = rect.size.height / source_rect.size.height; 204 float y_scaling_factor = rect.size.height / source_height;
196 if (x_scaling_factor > y_scaling_factor) { 205 scaling_factor = std::min(x_scaling_factor, y_scaling_factor);
197 scaling_factor = y_scaling_factor;
198 } else {
199 scaling_factor = x_scaling_factor;
200 }
201 } 206 }
202 // Some PDFs have a non-zero origin. Need to take that into account. 207 // Some PDFs have a non-zero origin. Need to take that into account and align
203 float x_offset = -1 * source_rect.origin.x * scaling_factor; 208 // the PDF to the origin.
204 float y_offset = -1 * source_rect.origin.y * scaling_factor; 209 const float x_origin_offset = -1 * source_rect.origin.x;
210 const float y_origin_offset = -1 * source_rect.origin.y;
205 211
206 if (center_horizontally) { 212 // If the PDF needs to be centered, calculate the offsets here.
207 x_offset += (rect.size.width - 213 float x_offset = params.center_horizontally ?
208 (source_rect.size.width * scaling_factor))/2; 214 ((rect.size.width - (source_width * scaling_factor)) / 2) : 0;
215 if (rotate)
216 x_offset = -x_offset;
217
218 float y_offset = params.center_vertically ?
219 ((rect.size.height - (source_height * scaling_factor)) / 2) : 0;
220
221 CGContextSaveGState(context);
222
223 // The transform operations specified here gets applied in reverse order.
224 // i.e. the origin offset translation happens first.
225 // Origin is at bottom-left.
226 CGContextTranslateCTM(context, x_offset, y_offset);
227 if (rotate) {
228 // After rotating by 90 degrees with the axis at the origin, the page
229 // content is now "off screen". Shift it right to move it back on screen.
230 CGContextTranslateCTM(context, rect.size.width, 0);
231 // Rotates counter-clockwise by 90 degrees.
232 CGContextRotateCTM(context, M_PI_2);
209 } 233 }
210 if (center_vertically) {
211 y_offset += (rect.size.height -
212 (source_rect.size.height * scaling_factor))/2;
213 }
214 CGContextSaveGState(context);
215 CGContextTranslateCTM(context, x_offset, y_offset);
216 CGContextScaleCTM(context, scaling_factor, scaling_factor); 234 CGContextScaleCTM(context, scaling_factor, scaling_factor);
235 CGContextTranslateCTM(context, x_origin_offset, y_origin_offset);
236
217 CGContextDrawPDFPage(context, pdf_page); 237 CGContextDrawPDFPage(context, pdf_page);
218 CGContextRestoreGState(context); 238 CGContextRestoreGState(context);
239
219 return true; 240 return true;
220 } 241 }
221 242
222 unsigned int PdfMetafileCg::GetPageCount() const { 243 unsigned int PdfMetafileCg::GetPageCount() const {
223 CGPDFDocumentRef pdf_doc = GetPDFDocument(); 244 CGPDFDocumentRef pdf_doc = GetPDFDocument();
224 return pdf_doc ? CGPDFDocumentGetNumberOfPages(pdf_doc) : 0; 245 return pdf_doc ? CGPDFDocumentGetNumberOfPages(pdf_doc) : 0;
225 } 246 }
226 247
227 gfx::Rect PdfMetafileCg::GetPageBounds(unsigned int page_number) const { 248 gfx::Rect PdfMetafileCg::GetPageBounds(unsigned int page_number) const {
228 CGPDFDocumentRef pdf_doc = GetPDFDocument(); 249 CGPDFDocumentRef pdf_doc = GetPDFDocument();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 310
290 if (!pdf_doc_.get()) { 311 if (!pdf_doc_.get()) {
291 ScopedCFTypeRef<CGDataProviderRef> pdf_data_provider( 312 ScopedCFTypeRef<CGDataProviderRef> pdf_data_provider(
292 CGDataProviderCreateWithCFData(pdf_data_)); 313 CGDataProviderCreateWithCFData(pdf_data_));
293 pdf_doc_.reset(CGPDFDocumentCreateWithProvider(pdf_data_provider)); 314 pdf_doc_.reset(CGPDFDocumentCreateWithProvider(pdf_data_provider));
294 } 315 }
295 return pdf_doc_.get(); 316 return pdf_doc_.get();
296 } 317 }
297 318
298 } // namespace printing 319 } // namespace printing
OLDNEW
« no previous file with comments | « printing/pdf_metafile_cg_mac.h ('k') | printing/pdf_metafile_skia.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698