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

Side by Side Diff: printing/pdf_metafile_cg_mac.cc

Issue 611693002: Printing: Take the PDF rotation into account when printing on Mac. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 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
« no previous file with comments | « no previous file | no next file » | 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> 7 #include <algorithm>
8 8
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
(...skipping 22 matching lines...) Expand all
33 // the destination PDF context will crash. So the outermost instantiation of 33 // the destination PDF context will crash. So the outermost instantiation of
34 // PdfMetafileCg creates a pool for deeper instantiations to dump their used 34 // PdfMetafileCg creates a pool for deeper instantiations to dump their used
35 // PDFs into rather than releasing them. When the top-level PDF is closed, then 35 // PDFs into rather than releasing them. When the top-level PDF is closed, then
36 // it's safe to clear the pool. A thread local is used to allow this to work in 36 // it's safe to clear the pool. A thread local is used to allow this to work in
37 // single-process mode. TODO(avi): This Apple bug appears fixed in 10.7; when 37 // single-process mode. TODO(avi): This Apple bug appears fixed in 10.7; when
38 // 10.7 is the minimum required version for Chromium, remove this hack. 38 // 10.7 is the minimum required version for Chromium, remove this hack.
39 39
40 base::LazyInstance<base::ThreadLocalPointer<struct __CFSet> >::Leaky 40 base::LazyInstance<base::ThreadLocalPointer<struct __CFSet> >::Leaky
41 thread_pdf_docs = LAZY_INSTANCE_INITIALIZER; 41 thread_pdf_docs = LAZY_INSTANCE_INITIALIZER;
42 42
43 // Rotate a page by |num_rotations| * 90 degrees, counter-clockwise.
44 void RotatePage(CGContextRef context, const CGRect rect, int num_rotations) {
45 switch (num_rotations) {
46 case 0:
47 break;
48 case 1:
49 // After rotating by 90 degrees with the axis at the origin, the page
50 // content is now "off screen". Shift it right to move it back on screen.
51 CGContextTranslateCTM(context, rect.size.width, 0);
52 // Rotates counter-clockwise by 90 degrees.
53 CGContextRotateCTM(context, M_PI_2);
54 break;
55 case 2:
56 // After rotating by 180 degrees with the axis at the origin, the page
57 // content is now "off screen". Shift it right and up to move it back on
58 // screen.
59 CGContextTranslateCTM(context, rect.size.width, rect.size.height);
60 // Rotates counter-clockwise by 90 degrees.
61 CGContextRotateCTM(context, M_PI);
62 break;
63 case 3:
64 // After rotating by 270 degrees with the axis at the origin, the page
65 // content is now "off screen". Shift it right to move it back on screen.
66 CGContextTranslateCTM(context, 0, rect.size.height);
67 // Rotates counter-clockwise by 90 degrees.
68 CGContextRotateCTM(context, -M_PI_2);
69 break;
70 default:
71 NOTREACHED();
72 break;
73 };
74 }
75
43 } // namespace 76 } // namespace
44 77
45 namespace printing { 78 namespace printing {
46 79
47 PdfMetafileCg::PdfMetafileCg() 80 PdfMetafileCg::PdfMetafileCg()
48 : page_is_open_(false), 81 : page_is_open_(false),
49 thread_pdf_docs_owned_(false) { 82 thread_pdf_docs_owned_(false) {
50 if (!thread_pdf_docs.Pointer()->Get() && 83 if (!thread_pdf_docs.Pointer()->Get() &&
51 base::mac::IsOSSnowLeopard()) { 84 base::mac::IsOSSnowLeopard()) {
52 thread_pdf_docs_owned_ = true; 85 thread_pdf_docs_owned_ = true;
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 CGContextRef context, 208 CGContextRef context,
176 const CGRect rect, 209 const CGRect rect,
177 const MacRenderPageParams& params) const { 210 const MacRenderPageParams& params) const {
178 CGPDFDocumentRef pdf_doc = GetPDFDocument(); 211 CGPDFDocumentRef pdf_doc = GetPDFDocument();
179 if (!pdf_doc) { 212 if (!pdf_doc) {
180 LOG(ERROR) << "Unable to create PDF document from data"; 213 LOG(ERROR) << "Unable to create PDF document from data";
181 return false; 214 return false;
182 } 215 }
183 CGPDFPageRef pdf_page = CGPDFDocumentGetPage(pdf_doc, page_number); 216 CGPDFPageRef pdf_page = CGPDFDocumentGetPage(pdf_doc, page_number);
184 CGRect source_rect = CGPDFPageGetBoxRect(pdf_page, kCGPDFCropBox); 217 CGRect source_rect = CGPDFPageGetBoxRect(pdf_page, kCGPDFCropBox);
218 int pdf_src_rotation = CGPDFPageGetRotationAngle(pdf_page);
185 float scaling_factor = 1.0; 219 float scaling_factor = 1.0;
186 const bool source_is_landscape = 220 const bool source_is_landscape =
187 (source_rect.size.width > source_rect.size.height); 221 (source_rect.size.width > source_rect.size.height);
188 const bool dest_is_landscape = (rect.size.width > rect.size.height); 222 const bool dest_is_landscape = (rect.size.width > rect.size.height);
189 const bool rotate = 223 const bool rotate =
190 params.autorotate ? (source_is_landscape != dest_is_landscape) : false; 224 params.autorotate ? (source_is_landscape != dest_is_landscape) : false;
191 const float source_width = 225 const float source_width =
192 rotate ? source_rect.size.height : source_rect.size.width; 226 rotate ? source_rect.size.height : source_rect.size.width;
193 const float source_height = 227 const float source_height =
194 rotate ? source_rect.size.width : source_rect.size.height; 228 rotate ? source_rect.size.width : source_rect.size.height;
(...skipping 22 matching lines...) Expand all
217 251
218 float y_offset = params.center_vertically ? 252 float y_offset = params.center_vertically ?
219 ((rect.size.height - (source_height * scaling_factor)) / 2) : 0; 253 ((rect.size.height - (source_height * scaling_factor)) / 2) : 0;
220 254
221 CGContextSaveGState(context); 255 CGContextSaveGState(context);
222 256
223 // The transform operations specified here gets applied in reverse order. 257 // The transform operations specified here gets applied in reverse order.
224 // i.e. the origin offset translation happens first. 258 // i.e. the origin offset translation happens first.
225 // Origin is at bottom-left. 259 // Origin is at bottom-left.
226 CGContextTranslateCTM(context, x_offset, y_offset); 260 CGContextTranslateCTM(context, x_offset, y_offset);
261
262 int num_rotations = 0;
227 if (rotate) { 263 if (rotate) {
228 // After rotating by 90 degrees with the axis at the origin, the page 264 if (pdf_src_rotation == 0 || pdf_src_rotation == 270) {
229 // content is now "off screen". Shift it right to move it back on screen. 265 num_rotations = 1;
230 CGContextTranslateCTM(context, rect.size.width, 0); 266 } else {
231 // Rotates counter-clockwise by 90 degrees. 267 num_rotations = 3;
232 CGContextRotateCTM(context, M_PI_2); 268 }
269 } else {
270 if (pdf_src_rotation == 180 || pdf_src_rotation == 270) {
271 num_rotations = 2;
272 }
233 } 273 }
274 RotatePage(context, rect, num_rotations);
275
234 CGContextScaleCTM(context, scaling_factor, scaling_factor); 276 CGContextScaleCTM(context, scaling_factor, scaling_factor);
235 CGContextTranslateCTM(context, x_origin_offset, y_origin_offset); 277 CGContextTranslateCTM(context, x_origin_offset, y_origin_offset);
236 278
237 CGContextDrawPDFPage(context, pdf_page); 279 CGContextDrawPDFPage(context, pdf_page);
238 CGContextRestoreGState(context); 280 CGContextRestoreGState(context);
239 281
240 return true; 282 return true;
241 } 283 }
242 284
243 unsigned int PdfMetafileCg::GetPageCount() const { 285 unsigned int PdfMetafileCg::GetPageCount() const {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 339
298 if (!pdf_doc_.get()) { 340 if (!pdf_doc_.get()) {
299 ScopedCFTypeRef<CGDataProviderRef> pdf_data_provider( 341 ScopedCFTypeRef<CGDataProviderRef> pdf_data_provider(
300 CGDataProviderCreateWithCFData(pdf_data_)); 342 CGDataProviderCreateWithCFData(pdf_data_));
301 pdf_doc_.reset(CGPDFDocumentCreateWithProvider(pdf_data_provider)); 343 pdf_doc_.reset(CGPDFDocumentCreateWithProvider(pdf_data_provider));
302 } 344 }
303 return pdf_doc_.get(); 345 return pdf_doc_.get();
304 } 346 }
305 347
306 } // namespace printing 348 } // namespace printing
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698