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

Side by Side Diff: printing/pdf_ps_metafile_linux.cc

Issue 196071: Embed fonts information into resulting PDF file for printing. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 3 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_ps_metafile_linux.h ('k') | skia/ext/vector_platform_device_linux.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_ps_metafile_linux.h" 5 #include "printing/pdf_ps_metafile_linux.h"
6 6
7 #include <stdio.h> 7 #include <stdio.h>
8 8
9 #include <cairo.h> 9 #include <cairo.h>
10 #include <cairo-ft.h>
10 #include <cairo-pdf.h> 11 #include <cairo-pdf.h>
11 #include <cairo-ps.h> 12 #include <cairo-ps.h>
12 13
14 #include <ft2build.h>
15 #include FT_FREETYPE_H
16
17 #include <map>
18
13 #include "base/file_util.h" 19 #include "base/file_util.h"
14 #include "base/logging.h" 20 #include "base/logging.h"
21 #include "base/singleton.h"
22 #include "third_party/skia/include/core/SkFontHost.h"
23 #include "third_party/skia/include/core/SkStream.h"
24 #include "third_party/skia/include/core/SkTypeface.h"
15 25
16 namespace { 26 namespace {
17 27
28 FT_Library g_ft_library = NULL; // handle to FreeType library.
29
30 struct FontInfo {
31 SkStream* font_stream;
32 FT_Face ft_face;
33 cairo_font_face_t* cairo_face;
34 cairo_user_data_key_t data_key;
35 };
36
37 typedef std::map<uint32_t, FontInfo> MapFontId2FontInfo;
38
39 // NOTE: Only call this function when no further rendering will be performed,
40 // and/or the metafile is closed.
41 void CleanUpFonts() {
42 MapFontId2FontInfo* g_font_cache = Singleton<MapFontId2FontInfo>::get();
43 DCHECK(g_font_cache);
44
45 for (MapFontId2FontInfo::iterator it = g_font_cache->begin();
46 it !=g_font_cache->end();
47 ++it) {
48 DCHECK(it->second.cairo_face);
49 DCHECK(it->second.font_stream);
50
51 cairo_font_face_destroy(it->second.cairo_face);
52 // |it->second.ft_face| is handled by Cairo.
53 it->second.font_stream->unref();
54 }
55 g_font_cache->clear();
56 }
57
58 void CleanUpFreeType() {
59 if (g_ft_library) {
60 FT_Error ft_error = FT_Done_FreeType(g_ft_library);
61 g_ft_library = NULL;
62 DCHECK_EQ(ft_error, 0);
63 }
64 }
65
18 // Tests if |surface| is valid. 66 // Tests if |surface| is valid.
19 bool IsSurfaceValid(cairo_surface_t* surface) { 67 bool IsSurfaceValid(cairo_surface_t* surface) {
20 return cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS; 68 return cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS;
21 } 69 }
22 70
23 // Tests if |context| is valid. 71 // Tests if |context| is valid.
24 bool IsContextValid(cairo_t* context) { 72 bool IsContextValid(cairo_t* context) {
25 return cairo_status(context) == CAIRO_STATUS_SUCCESS; 73 return cairo_status(context) == CAIRO_STATUS_SUCCESS;
26 } 74 }
27 75
(...skipping 13 matching lines...) Expand all
41 } 89 }
42 } 90 }
43 91
44 // Callback function for Cairo to write PDF/PS stream. 92 // Callback function for Cairo to write PDF/PS stream.
45 // |dst_buffer| is actually a pointer of type `std::string*`. 93 // |dst_buffer| is actually a pointer of type `std::string*`.
46 cairo_status_t WriteCairoStream(void* dst_buffer, 94 cairo_status_t WriteCairoStream(void* dst_buffer,
47 const unsigned char* src_data, 95 const unsigned char* src_data,
48 unsigned int src_data_length) { 96 unsigned int src_data_length) {
49 DCHECK(dst_buffer); 97 DCHECK(dst_buffer);
50 DCHECK(src_data); 98 DCHECK(src_data);
51 DCHECK(src_data_length > 0); 99 DCHECK_GT(src_data_length, 0u);
52 100
53 std::string* buffer = reinterpret_cast<std::string*>(dst_buffer); 101 std::string* buffer = reinterpret_cast<std::string*>(dst_buffer);
54 buffer->append(reinterpret_cast<const char*>(src_data), src_data_length); 102 buffer->append(reinterpret_cast<const char*>(src_data), src_data_length);
55 103
56 return CAIRO_STATUS_SUCCESS; 104 return CAIRO_STATUS_SUCCESS;
57 } 105 }
58 106
59 } // namespace 107 } // namespace
60 108
61 namespace printing { 109 namespace printing {
62 110
63 PdfPsMetafile::PdfPsMetafile(const FileFormat& format) 111 PdfPsMetafile::PdfPsMetafile(const FileFormat& format)
64 : format_(format), 112 : format_(format),
65 surface_(NULL), context_(NULL), 113 surface_(NULL), context_(NULL),
66 page_surface_(NULL), page_context_(NULL) { 114 page_surface_(NULL), page_context_(NULL) {
67 } 115 }
68 116
69 PdfPsMetafile::~PdfPsMetafile() { 117 PdfPsMetafile::~PdfPsMetafile() {
70 // Releases resources if we forgot to do so. 118 // Releases all resources if we forgot to do so.
71 CleanUp(); 119 CleanUpAll();
72 } 120 }
73 121
74 bool PdfPsMetafile::Init() { 122 bool PdfPsMetafile::Init() {
75 // We need to check at least these two members to ensure Init() has not been 123 // We need to check at least these two members to ensure Init() has not been
76 // called before. Passing these two checks also implies that surface_, 124 // called before. Passing these two checks also implies that surface_,
77 // page_surface_, and page_context_ are NULL, and current_page_ is empty. 125 // page_surface_, and page_context_ are NULL, and current_page_ is empty.
78 DCHECK(!context_); 126 DCHECK(!context_);
79 DCHECK(all_pages_.empty()); 127 DCHECK(all_pages_.empty());
128 DCHECK(!g_ft_library);
80 129
81 // Create an 1 by 1 Cairo surface for entire PDF/PS file. 130 // Initializes FreeType library.
131 FT_Error ft_error = FT_Init_FreeType(&g_ft_library);
132 if (ft_error) {
133 DLOG(ERROR) << "Cannot initialize FreeType library for PdfPsMetafile.";
134 g_ft_library = NULL;
135 return false;
136 }
137
138 // Creates an 1 by 1 Cairo surface for entire PDF/PS file.
82 // The size for each page will be overwritten later in StartPage(). 139 // The size for each page will be overwritten later in StartPage().
83 switch (format_) { 140 switch (format_) {
84 case PDF: { 141 case PDF: {
85 surface_ = cairo_pdf_surface_create_for_stream(WriteCairoStream, 142 surface_ = cairo_pdf_surface_create_for_stream(WriteCairoStream,
86 &all_pages_, 1, 1); 143 &all_pages_, 1, 1);
87 } 144 }
88 break; 145 break;
89 146
90 case PS: { 147 case PS: {
91 surface_ = cairo_ps_surface_create_for_stream(WriteCairoStream, 148 surface_ = cairo_ps_surface_create_for_stream(WriteCairoStream,
92 &all_pages_, 1, 1); 149 &all_pages_, 1, 1);
93 } 150 }
94 break; 151 break;
95 152
96 default: 153 default:
97 NOTREACHED(); 154 NOTREACHED();
98 return false; 155 return false;
99 } 156 }
100 157
101 // Cairo always returns a valid pointer. 158 // Cairo always returns a valid pointer.
102 // Hence, we have to check if it points to a "nil" object. 159 // Hence, we have to check if it points to a "nil" object.
103 if (!IsSurfaceValid(surface_)) { 160 if (!IsSurfaceValid(surface_)) {
104 DLOG(ERROR) << "Cannot create Cairo surface for PdfPsMetafile!"; 161 DLOG(ERROR) << "Cannot create Cairo surface for PdfPsMetafile!";
105 CleanUpSurface(&surface_); 162 CleanUpSurface(&surface_);
163 CleanUpFreeType();
106 return false; 164 return false;
107 } 165 }
108 166
109 // Create a context. 167 // Creates a context.
110 context_ = cairo_create(surface_); 168 context_ = cairo_create(surface_);
111 if (!IsContextValid(context_)) { 169 if (!IsContextValid(context_)) {
112 DLOG(ERROR) << "Cannot create Cairo context for PdfPsMetafile!"; 170 DLOG(ERROR) << "Cannot create Cairo context for PdfPsMetafile!";
113 CleanUpContext(&context_); 171 CleanUpContext(&context_);
114 CleanUpSurface(&surface_); 172 CleanUpSurface(&surface_);
173 CleanUpFreeType();
115 return false; 174 return false;
116 } 175 }
117 176
118 return true; 177 return true;
119 } 178 }
120 179
121 bool PdfPsMetafile::Init(const void* src_buffer, size_t src_buffer_size) { 180 bool PdfPsMetafile::Init(const void* src_buffer, size_t src_buffer_size) {
122 // We need to check at least these two members to ensure Init() has not been 181 // We need to check at least these two members to ensure Init() has not been
123 // called before. Passing these two checks also implies that surface_, 182 // called before. Passing these two checks also implies that surface_,
124 // page_surface_, and page_context_ are NULL, and current_page_ is empty. 183 // page_surface_, and page_context_ are NULL, and current_page_ is empty.
(...skipping 13 matching lines...) Expand all
138 cairo_t* PdfPsMetafile::StartPage(double width_in_points, 197 cairo_t* PdfPsMetafile::StartPage(double width_in_points,
139 double height_in_points) { 198 double height_in_points) {
140 DCHECK(IsSurfaceValid(surface_)); 199 DCHECK(IsSurfaceValid(surface_));
141 DCHECK(IsContextValid(context_)); 200 DCHECK(IsContextValid(context_));
142 // Passing this check implies page_surface_ is NULL, and current_page_ is 201 // Passing this check implies page_surface_ is NULL, and current_page_ is
143 // empty. 202 // empty.
144 DCHECK(!page_context_); 203 DCHECK(!page_context_);
145 DCHECK_GT(width_in_points, 0.); 204 DCHECK_GT(width_in_points, 0.);
146 DCHECK_GT(height_in_points, 0.); 205 DCHECK_GT(height_in_points, 0.);
147 206
148 // Create a target surface for the new page. 207 // Creates a target surface for the new page.
149 // Cairo 1.6.0 does NOT allow the first argument be NULL, 208 // Cairo 1.6.0 does NOT allow the first argument be NULL,
150 // but some newer versions do support NULL pointer. 209 // but some newer versions do support NULL pointer.
151 switch (format_) { 210 switch (format_) {
152 case PDF: { 211 case PDF: {
153 page_surface_ = cairo_pdf_surface_create_for_stream(WriteCairoStream, 212 page_surface_ = cairo_pdf_surface_create_for_stream(WriteCairoStream,
154 &current_page_, 213 &current_page_,
155 width_in_points, 214 width_in_points,
156 height_in_points); 215 height_in_points);
157 } 216 }
158 break; 217 break;
159 218
160 case PS: { 219 case PS: {
161 page_surface_ = cairo_ps_surface_create_for_stream(WriteCairoStream, 220 page_surface_ = cairo_ps_surface_create_for_stream(WriteCairoStream,
162 &current_page_, 221 &current_page_,
163 width_in_points, 222 width_in_points,
164 height_in_points); 223 height_in_points);
165 } 224 }
166 break; 225 break;
167 226
168 default: 227 default:
169 NOTREACHED(); 228 NOTREACHED();
170 CleanUp(); 229 CleanUpAll();
171 return NULL; 230 return NULL;
172 } 231 }
173 232
174 // Cairo always returns a valid pointer. 233 // Cairo always returns a valid pointer.
175 // Hence, we have to check if it points to a "nil" object. 234 // Hence, we have to check if it points to a "nil" object.
176 if (!IsSurfaceValid(page_surface_)) { 235 if (!IsSurfaceValid(page_surface_)) {
177 DLOG(ERROR) << "Cannot create Cairo surface for PdfPsMetafile!"; 236 DLOG(ERROR) << "Cannot create Cairo surface for PdfPsMetafile!";
178 CleanUp(); 237 CleanUpAll();
179 return NULL; 238 return NULL;
180 } 239 }
181 240
182 // Create a context. 241 // Creates a context.
183 page_context_ = cairo_create(page_surface_); 242 page_context_ = cairo_create(page_surface_);
184 if (!IsContextValid(page_context_)) { 243 if (!IsContextValid(page_context_)) {
185 DLOG(ERROR) << "Cannot create Cairo context for PdfPsMetafile!"; 244 DLOG(ERROR) << "Cannot create Cairo context for PdfPsMetafile!";
186 CleanUp(); 245 CleanUpAll();
187 return NULL; 246 return NULL;
188 } 247 }
189 248
190 return page_context_; 249 return page_context_;
191 } 250 }
192 251
193 bool PdfPsMetafile::FinishPage(float shrink) { 252 bool PdfPsMetafile::FinishPage(float shrink) {
194 DCHECK(IsSurfaceValid(surface_)); 253 DCHECK(IsSurfaceValid(surface_));
195 DCHECK(IsContextValid(context_)); 254 DCHECK(IsContextValid(context_));
196 DCHECK(IsSurfaceValid(page_surface_)); 255 DCHECK(IsSurfaceValid(page_surface_));
197 DCHECK(IsContextValid(page_context_)); 256 DCHECK(IsContextValid(page_context_));
198 DCHECK(shrink > 0); 257 DCHECK_GT(shrink, 0);
199 258
200 // Flush all rendering for current page. 259 // Flushes all rendering for current page.
201 cairo_surface_flush(page_surface_); 260 cairo_surface_flush(page_surface_);
202 261
203 // TODO(myhuang): Use real page settings. 262 // TODO(myhuang): Use real page settings.
204 // We hard-coded page settings here for testing purpose. 263 // We hard-coded page settings here for testing purpose.
205 // The paper size is US Letter (8.5 in. by 11 in.). 264 // The paper size is US Letter (8.5 in. by 11 in.).
206 // The default margins are: 265 // The default margins are:
207 // Left = 0.25 in. 266 // Left = 0.25 in.
208 // Right = 0.25 in. 267 // Right = 0.25 in.
209 // Top = 0.25 in. 268 // Top = 0.25 in.
210 // Bottom = 0.56 in. 269 // Bottom = 0.56 in.
211 const double kDPI = 72.0; // Dots (points) per inch. 270 const double kDPI = 72.0; // Dots (points) per inch.
212 const double kWidthInInch = 8.5; 271 const double kWidthInInch = 8.5;
213 const double kHeightInInch = 11.0; 272 const double kHeightInInch = 11.0;
214 const double kWidthInPoint = kWidthInInch * kDPI; 273 const double kWidthInPoint = kWidthInInch * kDPI;
215 const double kHeightInPoint = kHeightInInch * kDPI; 274 const double kHeightInPoint = kHeightInInch * kDPI;
216 switch (format_) { 275 switch (format_) {
217 case PDF: { 276 case PDF: {
218 cairo_pdf_surface_set_size(surface_, kWidthInPoint, kHeightInPoint); 277 cairo_pdf_surface_set_size(surface_, kWidthInPoint, kHeightInPoint);
219 } 278 }
220 break; 279 break;
221 280
222 case PS: { 281 case PS: {
223 cairo_ps_surface_set_size(surface_, kWidthInPoint, kHeightInPoint); 282 cairo_ps_surface_set_size(surface_, kWidthInPoint, kHeightInPoint);
224 } 283 }
225 break; 284 break;
226 285
227 default: 286 default:
228 NOTREACHED(); 287 NOTREACHED();
229 CleanUp(); 288 CleanUpAll();
230 return false; 289 return false;
231 } 290 }
232 291
233 // Check if our surface is still valid after resizing. 292 // Checks if our surface is still valid after resizing.
234 if (!IsSurfaceValid(surface_)) { 293 if (!IsSurfaceValid(surface_)) {
235 DLOG(ERROR) << "Cannot resize Cairo surface for PdfPsMetafile!"; 294 DLOG(ERROR) << "Cannot resize Cairo surface for PdfPsMetafile!";
236 CleanUp(); 295 CleanUpAll();
237 return false; 296 return false;
238 } 297 }
239 298
240 // Save context's states. 299 // Saves context's states.
241 cairo_save(context_); 300 cairo_save(context_);
242 // Copy current page onto the surface of final result. 301 // Copies current page onto the surface of final result.
243 // Margins are done by coordinates transformation. 302 // Margins are done by coordinates transformation.
244 // Please NOTE that we have to call cairo_scale() before we call 303 // Please NOTE that we have to call cairo_scale() before we call
245 // cairo_set_source_surface(). 304 // cairo_set_source_surface().
246 const double scale_factor = 1. / shrink; 305 const double scale_factor = 1. / shrink;
247 cairo_scale(context_, scale_factor, scale_factor); 306 cairo_scale(context_, scale_factor, scale_factor);
248 const double kLeftMarginInInch = 0.25; 307 const double kLeftMarginInInch = 0.25;
249 const double kTopMarginInInch = 0.25; 308 const double kTopMarginInInch = 0.25;
250 const double kLeftMarginInPoint = kLeftMarginInInch * kDPI; 309 const double kLeftMarginInPoint = kLeftMarginInInch * kDPI;
251 const double kTopMarginInPoint = kTopMarginInInch * kDPI; 310 const double kTopMarginInPoint = kTopMarginInInch * kDPI;
252 const double kScaledLeftMarginInPoint = kLeftMarginInPoint * shrink; 311 const double kScaledLeftMarginInPoint = kLeftMarginInPoint * shrink;
(...skipping 15 matching lines...) Expand all
268 kPrintableWidthInInch * kDPI * shrink; 327 kPrintableWidthInInch * kDPI * shrink;
269 const double kScaledPrintableHeightInPoint = 328 const double kScaledPrintableHeightInPoint =
270 kPrintableHeightInInch * kDPI * shrink; 329 kPrintableHeightInInch * kDPI * shrink;
271 cairo_rectangle(context_, 330 cairo_rectangle(context_,
272 kScaledLeftMarginInPoint, 331 kScaledLeftMarginInPoint,
273 kScaledTopMarginInPoint, 332 kScaledTopMarginInPoint,
274 kScaledPrintableWidthInPoint, 333 kScaledPrintableWidthInPoint,
275 kScaledPrintableHeightInPoint); 334 kScaledPrintableHeightInPoint);
276 cairo_fill(context_); 335 cairo_fill(context_);
277 336
278 // Finishing the duplication of current page. 337 // Finishes the duplication of current page.
279 cairo_show_page(context_); 338 cairo_show_page(context_);
280 cairo_surface_flush(surface_); 339 cairo_surface_flush(surface_);
281 340
282 // Destroy resoreces for current page. 341 // Destroys resources for current page.
283 CleanUpContext(&page_context_); 342 CleanUpContext(&page_context_);
284 CleanUpSurface(&page_surface_); 343 CleanUpSurface(&page_surface_);
285 current_page_.clear(); 344 current_page_.clear();
286 345
287 // Restore context's states. 346 // Restores context's states.
288 cairo_restore(context_); 347 cairo_restore(context_);
289 348
290 return true; 349 return true;
291 } 350 }
292 351
293 void PdfPsMetafile::Close() { 352 void PdfPsMetafile::Close() {
294 DCHECK(IsSurfaceValid(surface_)); 353 DCHECK(IsSurfaceValid(surface_));
295 DCHECK(IsContextValid(context_)); 354 DCHECK(IsContextValid(context_));
296 // Passing this check implies page_surface_ is NULL, and current_page_ is 355 // Passing this check implies page_surface_ is NULL, and current_page_ is
297 // empty. 356 // empty.
298 DCHECK(!page_context_); 357 DCHECK(!page_context_);
299 358
300 cairo_surface_finish(surface_); 359 cairo_surface_finish(surface_);
301 DCHECK(!all_pages_.empty()); // Make sure we did get something. 360 DCHECK(!all_pages_.empty()); // Make sure we did get something.
302 361
303 CleanUpContext(&context_); 362 CleanUpContext(&context_);
304 CleanUpSurface(&surface_); 363 CleanUpSurface(&surface_);
364 CleanUpFonts();
365 CleanUpFreeType();
366 }
367
368 // static
369 bool PdfPsMetafile::SelectFontById(cairo_t* context, uint32_t font_id) {
370 DCHECK(IsContextValid(context));
371 DCHECK(SkFontHost::ValidFontID(font_id));
372 DCHECK(g_ft_library);
373
374 // Checks if we have a cache hit.
375 MapFontId2FontInfo* g_font_cache = Singleton<MapFontId2FontInfo>::get();
376 DCHECK(g_font_cache);
377
378 MapFontId2FontInfo::iterator it = g_font_cache->find(font_id);
379 if (it != g_font_cache->end()) {
380 cairo_set_font_face(context, it->second.cairo_face);
381 if (IsContextValid(context)) {
382 return true;
383 } else {
384 NOTREACHED() << "Cannot set font face in Cairo!";
385 return false;
386 }
387 }
388
389 // Cache missed. We need to load and create the font.
390 FontInfo new_font_info = {0};
391 new_font_info.font_stream = SkFontHost::OpenStream(font_id);
392 DCHECK(new_font_info.font_stream);
393 size_t stream_size = new_font_info.font_stream->getLength();
394 DCHECK(stream_size) << "The Font stream has nothing!";
395
396 FT_Error ft_error = FT_New_Memory_Face(
397 g_ft_library,
398 static_cast<FT_Byte*>(
399 const_cast<void*>(new_font_info.font_stream->getMemoryBase())),
400 stream_size,
401 0,
402 &new_font_info.ft_face);
403
404 if (ft_error) {
405 new_font_info.font_stream->unref();
406 DLOG(ERROR) << "Cannot create FT_Face!";
407 SkASSERT(false);
408 return false;
409 }
410
411 new_font_info.cairo_face = cairo_ft_font_face_create_for_ft_face(
412 new_font_info.ft_face, 0);
413 DCHECK(new_font_info.cairo_face) << "Cannot create font in Cairo!";
414
415 // Manage |new_font_info.ft_face|'s life by Cairo.
416 cairo_status_t status = cairo_font_face_set_user_data(
417 new_font_info.cairo_face,
418 &new_font_info.data_key,
419 new_font_info.ft_face,
420 reinterpret_cast<cairo_destroy_func_t>(FT_Done_Face));
421
422 if (status != CAIRO_STATUS_SUCCESS) {
423 DLOG(ERROR) << "Cannot set font's user data in Cairo!";
424 cairo_font_face_destroy(new_font_info.cairo_face);
425 FT_Done_Face(new_font_info.ft_face);
426 new_font_info.font_stream->unref();
427 SkASSERT(false);
428 return false;
429 }
430
431 // Inserts |new_font_info| info |g_font_cache|.
432 (*g_font_cache)[font_id] = new_font_info;
433
434 cairo_set_font_face(context, new_font_info.cairo_face);
435 if (IsContextValid(context)) {
436 return true;
437 }
438
439 DLOG(ERROR) << "Connot set font face in Cairo!";
440 return false;
305 } 441 }
306 442
307 unsigned int PdfPsMetafile::GetDataSize() const { 443 unsigned int PdfPsMetafile::GetDataSize() const {
308 // We need to check at least these two members to ensure that either Init() 444 // We need to check at least these two members to ensure that either Init()
309 // has been called to initialize |all_pages_|, or metafile has been closed. 445 // has been called to initialize |all_pages_|, or metafile has been closed.
310 // Passing these two checks also implies that surface_, page_surface_, and 446 // Passing these two checks also implies that surface_, page_surface_, and
311 // page_context_ are NULL, and current_page_ is empty. 447 // page_context_ are NULL, and current_page_ is empty.
312 DCHECK(!context_); 448 DCHECK(!context_);
313 DCHECK(!all_pages_.empty()); 449 DCHECK(!all_pages_.empty());
314 450
315 return all_pages_.size(); 451 return all_pages_.size();
316 } 452 }
317 453
318 bool PdfPsMetafile::GetData(void* dst_buffer, size_t dst_buffer_size) const { 454 bool PdfPsMetafile::GetData(void* dst_buffer, size_t dst_buffer_size) const {
319 DCHECK(dst_buffer); 455 DCHECK(dst_buffer);
320 DCHECK(dst_buffer_size > 0); 456 DCHECK_GT(dst_buffer_size, 0u);
321 // We need to check at least these two members to ensure that either Init() 457 // We need to check at least these two members to ensure that either Init()
322 // has been called to initialize |all_pages_|, or metafile has been closed. 458 // has been called to initialize |all_pages_|, or metafile has been closed.
323 // Passing these two checks also implies that surface_, page_surface_, and 459 // Passing these two checks also implies that surface_, page_surface_, and
324 // page_context_ are NULL, and current_page_ is empty. 460 // page_context_ are NULL, and current_page_ is empty.
325 DCHECK(!context_); 461 DCHECK(!context_);
326 DCHECK(!all_pages_.empty()); 462 DCHECK(!all_pages_.empty());
327 463
328 size_t data_size = GetDataSize(); 464 size_t data_size = GetDataSize();
329 if (dst_buffer_size > data_size) { 465 if (dst_buffer_size > data_size) {
330 return false; 466 return false;
(...skipping 16 matching lines...) Expand all
347 const unsigned int bytes_written = 483 const unsigned int bytes_written =
348 file_util::WriteFile(filename, all_pages_.data(), data_size); 484 file_util::WriteFile(filename, all_pages_.data(), data_size);
349 if (bytes_written != data_size) { 485 if (bytes_written != data_size) {
350 DLOG(ERROR) << "Failed to save file: " << filename.value(); 486 DLOG(ERROR) << "Failed to save file: " << filename.value();
351 return false; 487 return false;
352 } 488 }
353 489
354 return true; 490 return true;
355 } 491 }
356 492
357 void PdfPsMetafile::CleanUp() { 493 void PdfPsMetafile::CleanUpAll() {
358 CleanUpContext(&context_); 494 CleanUpContext(&context_);
359 CleanUpSurface(&surface_); 495 CleanUpSurface(&surface_);
360 CleanUpContext(&page_context_); 496 CleanUpContext(&page_context_);
361 CleanUpSurface(&page_surface_); 497 CleanUpSurface(&page_surface_);
362 current_page_.clear(); 498 current_page_.clear();
363 all_pages_.clear(); 499 all_pages_.clear();
500 CleanUpFonts();
501 CleanUpFreeType();
364 } 502 }
365 503
366 } // namespace printing 504 } // namespace printing
367 505
OLDNEW
« no previous file with comments | « printing/pdf_ps_metafile_linux.h ('k') | skia/ext/vector_platform_device_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698