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

Side by Side Diff: printing/pdf_metafile_mac.cc

Issue 6611032: Unifying NativeMetafile class interface (as much as possible) for Linux, Mac, Win (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Removing dead code, using gfx::Size in PdfPsMetafile::StartPage Created 9 years, 9 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_mac.h ('k') | printing/pdf_metafile_mac_unittest.cc » ('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) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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_mac.h" 5 #include "printing/pdf_metafile_mac.h"
6 6
7 #include "base/file_path.h" 7 #include "base/file_path.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/mac/scoped_cftyperef.h" 9 #include "base/mac/scoped_cftyperef.h"
10 #include "base/sys_string_conversions.h" 10 #include "base/sys_string_conversions.h"
11 #include "ui/gfx/rect.h" 11 #include "ui/gfx/rect.h"
12 #include "ui/gfx/size.h"
dpapad 2011/03/08 22:17:19 The code was compiling without this, but I think i
12 13
13 using base::mac::ScopedCFTypeRef; 14 using base::mac::ScopedCFTypeRef;
14 15
15 namespace printing { 16 namespace printing {
16 17
17 PdfMetafile::PdfMetafile() 18 PdfMetafile::PdfMetafile()
18 : page_is_open_(false) { 19 : page_is_open_(false) {
19 } 20 }
20 21
21 PdfMetafile::~PdfMetafile() {} 22 PdfMetafile::~PdfMetafile() {}
22 23
23 CGContextRef PdfMetafile::Init() { 24 bool PdfMetafile::Init() {
24 // Ensure that Init hasn't already been called. 25 // Ensure that Init hasn't already been called.
25 DCHECK(!context_.get()); 26 DCHECK(!context_.get());
26 DCHECK(!pdf_data_.get()); 27 DCHECK(!pdf_data_.get());
27 28
28 pdf_data_.reset(CFDataCreateMutable(kCFAllocatorDefault, 0)); 29 pdf_data_.reset(CFDataCreateMutable(kCFAllocatorDefault, 0));
29 if (!pdf_data_.get()) { 30 if (!pdf_data_.get()) {
30 LOG(ERROR) << "Failed to create pdf data for metafile"; 31 LOG(ERROR) << "Failed to create pdf data for metafile";
31 return NULL; 32 return false;
32 } 33 }
33 ScopedCFTypeRef<CGDataConsumerRef> pdf_consumer( 34 ScopedCFTypeRef<CGDataConsumerRef> pdf_consumer(
34 CGDataConsumerCreateWithCFData(pdf_data_)); 35 CGDataConsumerCreateWithCFData(pdf_data_));
35 if (!pdf_consumer.get()) { 36 if (!pdf_consumer.get()) {
36 LOG(ERROR) << "Failed to create data consumer for metafile"; 37 LOG(ERROR) << "Failed to create data consumer for metafile";
37 pdf_data_.reset(NULL); 38 pdf_data_.reset(NULL);
38 return NULL; 39 return false;
39 } 40 }
40 context_.reset(CGPDFContextCreate(pdf_consumer, NULL, NULL)); 41 context_.reset(CGPDFContextCreate(pdf_consumer, NULL, NULL));
41 if (!context_.get()) { 42 if (!context_.get()) {
42 LOG(ERROR) << "Failed to create pdf context for metafile"; 43 LOG(ERROR) << "Failed to create pdf context for metafile";
43 pdf_data_.reset(NULL); 44 pdf_data_.reset(NULL);
44 } 45 }
45 46
46 return context_.get(); 47 return true;
47 } 48 }
48 49
49 bool PdfMetafile::Init(const void* src_buffer, uint32 src_buffer_size) { 50 bool PdfMetafile::Init(const void* src_buffer, uint32 src_buffer_size) {
50 DCHECK(!context_.get()); 51 DCHECK(!context_.get());
51 DCHECK(!pdf_data_.get()); 52 DCHECK(!pdf_data_.get());
52 53
53 if (!src_buffer || src_buffer_size == 0) { 54 if (!src_buffer || src_buffer_size == 0) {
54 return false; 55 return false;
55 } 56 }
56 57
57 pdf_data_.reset(CFDataCreateMutable(kCFAllocatorDefault, src_buffer_size)); 58 pdf_data_.reset(CFDataCreateMutable(kCFAllocatorDefault, src_buffer_size));
58 CFDataAppendBytes(pdf_data_, static_cast<const UInt8*>(src_buffer), 59 CFDataAppendBytes(pdf_data_, static_cast<const UInt8*>(src_buffer),
59 src_buffer_size); 60 src_buffer_size);
60 61
61 return true; 62 return true;
62 } 63 }
63 64
64 CGContextRef PdfMetafile::StartPage(const gfx::Size& page_size, 65 uint32 PdfMetafile::GetDataSize() const {
65 const gfx::Point& content_origin, const float& scale_factor) { 66 // PDF data is only valid/complete once the context is released.
66 DCHECK(context_.get()); 67 DCHECK(!context_);
67 DCHECK(!page_is_open_);
68 68
69 double height = page_size.height(); 69 if (!pdf_data_)
70 double width = page_size.width(); 70 return 0;
71 71 return static_cast<uint32>(CFDataGetLength(pdf_data_));
72 CGRect bounds = CGRectMake(0, 0, width, height);
73 CGContextBeginPage(context_, &bounds);
74 page_is_open_ = true;
75 CGContextSaveGState(context_);
76
77 // Flip the context.
78 CGContextTranslateCTM(context_, 0, height);
79 CGContextScaleCTM(context_, scale_factor, -scale_factor);
80
81 // Move the context to origin.
82 CGContextTranslateCTM(context_, content_origin.x(), content_origin.y());
83
84 return context_.get();
85 } 72 }
86 73
87 void PdfMetafile::FinishPage() { 74 bool PdfMetafile::GetData(void* dst_buffer, uint32 dst_buffer_size) const {
75 // PDF data is only valid/complete once the context is released.
76 DCHECK(!context_);
77 DCHECK(pdf_data_);
78 DCHECK(dst_buffer);
79 DCHECK_GT(dst_buffer_size, 0U);
80
81 uint32 data_size = GetDataSize();
82 if (dst_buffer_size > data_size) {
83 return false;
84 }
85
86 CFDataGetBytes(pdf_data_, CFRangeMake(0, dst_buffer_size),
87 static_cast<UInt8*>(dst_buffer));
88 return true;
89 }
90
91 bool PdfMetafile::FinishPage() {
88 DCHECK(context_.get()); 92 DCHECK(context_.get());
89 DCHECK(page_is_open_); 93 DCHECK(page_is_open_);
90 94
91 CGContextRestoreGState(context_); 95 CGContextRestoreGState(context_);
92 CGContextEndPage(context_); 96 CGContextEndPage(context_);
93 page_is_open_ = false; 97 page_is_open_ = false;
98 return true;
94 } 99 }
95 100
96 void PdfMetafile::Close() { 101 void PdfMetafile::Close() {
97 DCHECK(context_.get()); 102 DCHECK(context_.get());
98 DCHECK(!page_is_open_); 103 DCHECK(!page_is_open_);
99 104
100 #ifndef NDEBUG 105 #ifndef NDEBUG
101 // Check that the context will be torn down properly; if it's not, pdf_data_ 106 // Check that the context will be torn down properly; if it's not, pdf_data_
102 // will be incomplete and generate invalid PDF files/documents. 107 // will be incomplete and generate invalid PDF files/documents.
103 if (context_.get()) { 108 if (context_.get()) {
104 CFIndex extra_retain_count = CFGetRetainCount(context_.get()) - 1; 109 CFIndex extra_retain_count = CFGetRetainCount(context_.get()) - 1;
105 if (extra_retain_count > 0) { 110 if (extra_retain_count > 0) {
106 LOG(ERROR) << "Metafile context has " << extra_retain_count 111 LOG(ERROR) << "Metafile context has " << extra_retain_count
107 << " extra retain(s) on Close"; 112 << " extra retain(s) on Close";
108 } 113 }
109 } 114 }
110 #endif 115 #endif
111 CGPDFContextClose(context_.get()); 116 CGPDFContextClose(context_.get());
112 context_.reset(NULL); 117 context_.reset(NULL);
113 } 118 }
114 119
115 bool PdfMetafile::RenderPage(unsigned int page_number, CGContextRef context, 120 bool PdfMetafile::SaveTo(const FilePath& file_path) const {
121 DCHECK(pdf_data_.get());
122 DCHECK(!context_.get());
123
124 std::string path_string = file_path.value();
125 ScopedCFTypeRef<CFURLRef> path_url(CFURLCreateFromFileSystemRepresentation(
126 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(path_string.c_str()),
127 path_string.length(), false));
128 SInt32 error_code;
129 CFURLWriteDataAndPropertiesToResource(path_url, pdf_data_, NULL, &error_code);
130 return error_code == 0;
131 }
132
133 gfx::Rect PdfMetafile::GetPageBounds(unsigned int page_number) const {
134 CGPDFDocumentRef pdf_doc = GetPDFDocument();
135 if (!pdf_doc) {
136 LOG(ERROR) << "Unable to create PDF document from data";
137 return gfx::Rect();
138 }
139 if (page_number > GetPageCount()) {
140 LOG(ERROR) << "Invalid page number: " << page_number;
141 return gfx::Rect();
142 }
143 CGPDFPageRef pdf_page = CGPDFDocumentGetPage(pdf_doc, page_number);
144 CGRect page_rect = CGPDFPageGetBoxRect(pdf_page, kCGPDFMediaBox);
145 return gfx::Rect(page_rect);
146 }
147
148 unsigned int PdfMetafile::GetPageCount() const {
149 CGPDFDocumentRef pdf_doc = GetPDFDocument();
150 return pdf_doc ? CGPDFDocumentGetNumberOfPages(pdf_doc) : 0;
151 }
152
153 PlatformContext PdfMetafile::StartPage(const gfx::Size& page_size,
154 const gfx::Point& content_origin, const float& scale_factor) {
155 DCHECK(context_.get());
156 DCHECK(!page_is_open_);
157
158 double height = page_size.height();
159 double width = page_size.width();
160
161 CGRect bounds = CGRectMake(0, 0, width, height);
162 CGContextBeginPage(context_, &bounds);
163 page_is_open_ = true;
164 CGContextSaveGState(context_);
165
166 // Flip the context.
167 CGContextTranslateCTM(context_, 0, height);
168 CGContextScaleCTM(context_, scale_factor, -scale_factor);
169
170 // Move the context to origin.
171 CGContextTranslateCTM(context_, content_origin.x(), content_origin.y());
172
173 return context_.get();
174 }
175
176 bool PdfMetafile::RenderPage(unsigned int page_number, PlatformContext context,
116 const CGRect rect, bool shrink_to_fit, 177 const CGRect rect, bool shrink_to_fit,
117 bool stretch_to_fit, 178 bool stretch_to_fit,
118 bool center_horizontally, 179 bool center_horizontally,
119 bool center_vertically) const { 180 bool center_vertically) const {
120 CGPDFDocumentRef pdf_doc = GetPDFDocument(); 181 CGPDFDocumentRef pdf_doc = GetPDFDocument();
121 if (!pdf_doc) { 182 if (!pdf_doc) {
122 LOG(ERROR) << "Unable to create PDF document from data"; 183 LOG(ERROR) << "Unable to create PDF document from data";
123 return false; 184 return false;
124 } 185 }
125 CGPDFPageRef pdf_page = CGPDFDocumentGetPage(pdf_doc, page_number); 186 CGPDFPageRef pdf_page = CGPDFDocumentGetPage(pdf_doc, page_number);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 y_offset += rect.size.height - (source_rect.size.height * scaling_factor); 218 y_offset += rect.size.height - (source_rect.size.height * scaling_factor);
158 } 219 }
159 CGContextSaveGState(context); 220 CGContextSaveGState(context);
160 CGContextTranslateCTM(context, x_offset, y_offset); 221 CGContextTranslateCTM(context, x_offset, y_offset);
161 CGContextScaleCTM(context, scaling_factor, scaling_factor); 222 CGContextScaleCTM(context, scaling_factor, scaling_factor);
162 CGContextDrawPDFPage(context, pdf_page); 223 CGContextDrawPDFPage(context, pdf_page);
163 CGContextRestoreGState(context); 224 CGContextRestoreGState(context);
164 return true; 225 return true;
165 } 226 }
166 227
167 unsigned int PdfMetafile::GetPageCount() const {
168 CGPDFDocumentRef pdf_doc = GetPDFDocument();
169 return pdf_doc ? CGPDFDocumentGetNumberOfPages(pdf_doc) : 0;
170 }
171
172 gfx::Rect PdfMetafile::GetPageBounds(unsigned int page_number) const {
173 CGPDFDocumentRef pdf_doc = GetPDFDocument();
174 if (!pdf_doc) {
175 LOG(ERROR) << "Unable to create PDF document from data";
176 return gfx::Rect();
177 }
178 if (page_number > GetPageCount()) {
179 LOG(ERROR) << "Invalid page number: " << page_number;
180 return gfx::Rect();
181 }
182 CGPDFPageRef pdf_page = CGPDFDocumentGetPage(pdf_doc, page_number);
183 CGRect page_rect = CGPDFPageGetBoxRect(pdf_page, kCGPDFMediaBox);
184 return gfx::Rect(page_rect);
185 }
186
187 uint32 PdfMetafile::GetDataSize() const {
188 // PDF data is only valid/complete once the context is released.
189 DCHECK(!context_);
190
191 if (!pdf_data_)
192 return 0;
193 return static_cast<uint32>(CFDataGetLength(pdf_data_));
194 }
195
196 bool PdfMetafile::GetData(void* dst_buffer, uint32 dst_buffer_size) const {
197 // PDF data is only valid/complete once the context is released.
198 DCHECK(!context_);
199 DCHECK(pdf_data_);
200 DCHECK(dst_buffer);
201 DCHECK_GT(dst_buffer_size, 0U);
202
203 uint32 data_size = GetDataSize();
204 if (dst_buffer_size > data_size) {
205 return false;
206 }
207
208 CFDataGetBytes(pdf_data_, CFRangeMake(0, dst_buffer_size),
209 static_cast<UInt8*>(dst_buffer));
210 return true;
211 }
212
213 bool PdfMetafile::SaveTo(const FilePath& file_path) const {
214 DCHECK(pdf_data_.get());
215 DCHECK(!context_.get());
216
217 std::string path_string = file_path.value();
218 ScopedCFTypeRef<CFURLRef> path_url(CFURLCreateFromFileSystemRepresentation(
219 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(path_string.c_str()),
220 path_string.length(), false));
221 SInt32 error_code;
222 CFURLWriteDataAndPropertiesToResource(path_url, pdf_data_, NULL, &error_code);
223 return error_code == 0;
224 }
225
226 CGPDFDocumentRef PdfMetafile::GetPDFDocument() const { 228 CGPDFDocumentRef PdfMetafile::GetPDFDocument() const {
227 // Make sure that we have data, and that it's not being modified any more. 229 // Make sure that we have data, and that it's not being modified any more.
228 DCHECK(pdf_data_.get()); 230 DCHECK(pdf_data_.get());
229 DCHECK(!context_.get()); 231 DCHECK(!context_.get());
230 232
231 if (!pdf_doc_.get()) { 233 if (!pdf_doc_.get()) {
232 ScopedCFTypeRef<CGDataProviderRef> pdf_data_provider( 234 ScopedCFTypeRef<CGDataProviderRef> pdf_data_provider(
233 CGDataProviderCreateWithCFData(pdf_data_)); 235 CGDataProviderCreateWithCFData(pdf_data_));
234 pdf_doc_.reset(CGPDFDocumentCreateWithProvider(pdf_data_provider)); 236 pdf_doc_.reset(CGPDFDocumentCreateWithProvider(pdf_data_provider));
235 } 237 }
236 return pdf_doc_.get(); 238 return pdf_doc_.get();
237 } 239 }
238 240
239 } // namespace printing 241 } // namespace printing
OLDNEW
« no previous file with comments | « printing/pdf_metafile_mac.h ('k') | printing/pdf_metafile_mac_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698