OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_cairo.h" | 5 #include "printing/pdf_ps_metafile_cairo.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include <cairo.h> | 9 #include <cairo.h> |
10 #include <cairo-pdf.h> | 10 #include <cairo-pdf.h> |
11 #include <cairo-ps.h> | |
12 | 11 |
13 #include "base/eintr_wrapper.h" | 12 #include "base/eintr_wrapper.h" |
14 #include "base/file_descriptor_posix.h" | 13 #include "base/file_descriptor_posix.h" |
15 #include "base/file_util.h" | 14 #include "base/file_util.h" |
16 #include "base/logging.h" | 15 #include "base/logging.h" |
17 #include "printing/units.h" | 16 #include "printing/units.h" |
18 #include "skia/ext/vector_platform_device_linux.h" | 17 #include "skia/ext/vector_platform_device_linux.h" |
19 | 18 |
20 namespace { | 19 namespace { |
21 | 20 |
(...skipping 18 matching lines...) Expand all Loading... |
40 } | 39 } |
41 | 40 |
42 // Destroys and resets |context|. | 41 // Destroys and resets |context|. |
43 void CleanUpContext(cairo_t** context) { | 42 void CleanUpContext(cairo_t** context) { |
44 if (*context) { | 43 if (*context) { |
45 cairo_destroy(*context); | 44 cairo_destroy(*context); |
46 *context = NULL; | 45 *context = NULL; |
47 } | 46 } |
48 } | 47 } |
49 | 48 |
50 // Callback function for Cairo to write PDF/PS stream. | 49 // Callback function for Cairo to write PDF stream. |
51 // |dst_buffer| is actually a pointer of type `std::string*`. | 50 // |dst_buffer| is actually a pointer of type `std::string*`. |
52 cairo_status_t WriteCairoStream(void* dst_buffer, | 51 cairo_status_t WriteCairoStream(void* dst_buffer, |
53 const unsigned char* src_data, | 52 const unsigned char* src_data, |
54 unsigned int src_data_length) { | 53 unsigned int src_data_length) { |
55 DCHECK(dst_buffer); | 54 DCHECK(dst_buffer); |
56 DCHECK(src_data); | 55 DCHECK(src_data); |
57 DCHECK_GT(src_data_length, 0u); | 56 DCHECK_GT(src_data_length, 0u); |
58 | 57 |
59 std::string* buffer = reinterpret_cast<std::string*>(dst_buffer); | 58 std::string* buffer = reinterpret_cast<std::string*>(dst_buffer); |
60 buffer->append(reinterpret_cast<const char*>(src_data), src_data_length); | 59 buffer->append(reinterpret_cast<const char*>(src_data), src_data_length); |
61 | 60 |
62 return CAIRO_STATUS_SUCCESS; | 61 return CAIRO_STATUS_SUCCESS; |
63 } | 62 } |
64 | 63 |
65 void DestroyContextData(void* data) { | 64 void DestroyContextData(void* data) { |
66 // Nothing to be done here. | 65 // Nothing to be done here. |
67 } | 66 } |
68 | 67 |
69 } // namespace | 68 } // namespace |
70 | 69 |
71 namespace printing { | 70 namespace printing { |
72 | 71 |
73 PdfPsMetafile::PdfPsMetafile() | 72 PdfPsMetafile::PdfPsMetafile() |
74 : format_(PDF), | 73 : surface_(NULL), |
75 surface_(NULL), context_(NULL) { | 74 context_(NULL) { |
76 } | |
77 | |
78 PdfPsMetafile::PdfPsMetafile(const FileFormat& format) | |
79 : format_(format), | |
80 surface_(NULL), context_(NULL) { | |
81 } | 75 } |
82 | 76 |
83 PdfPsMetafile::~PdfPsMetafile() { | 77 PdfPsMetafile::~PdfPsMetafile() { |
84 // Releases all resources if we forgot to do so. | 78 // Releases all resources if we forgot to do so. |
85 CleanUpAll(); | 79 CleanUpAll(); |
86 } | 80 } |
87 | 81 |
88 bool PdfPsMetafile::Init() { | 82 bool PdfPsMetafile::Init() { |
89 // We need to check at least these two members to ensure Init() has not been | 83 // We need to check at least these two members to ensure Init() has not been |
90 // called before. | 84 // called before. |
91 DCHECK(!context_); | 85 DCHECK(!context_); |
92 DCHECK(data_.empty()); | 86 DCHECK(data_.empty()); |
93 | 87 |
94 // Creates an 1 by 1 Cairo surface for entire PDF/PS file. | 88 // Creates an 1 by 1 Cairo surface for the entire PDF file. |
95 // The size for each page will be overwritten later in StartPage(). | 89 // The size for each page will be overwritten later in StartPage(). |
96 switch (format_) { | 90 surface_ = cairo_pdf_surface_create_for_stream(WriteCairoStream, |
97 case PDF: | 91 &data_, 1, 1); |
98 surface_ = cairo_pdf_surface_create_for_stream(WriteCairoStream, | |
99 &data_, 1, 1); | |
100 break; | |
101 | |
102 case PS: | |
103 surface_ = cairo_ps_surface_create_for_stream(WriteCairoStream, | |
104 &data_, 1, 1); | |
105 break; | |
106 | |
107 default: | |
108 NOTREACHED(); | |
109 return false; | |
110 } | |
111 | 92 |
112 // Cairo always returns a valid pointer. | 93 // Cairo always returns a valid pointer. |
113 // Hence, we have to check if it points to a "nil" object. | 94 // Hence, we have to check if it points to a "nil" object. |
114 if (!IsSurfaceValid(surface_)) { | 95 if (!IsSurfaceValid(surface_)) { |
115 DLOG(ERROR) << "Cannot create Cairo surface for PdfPsMetafile!"; | 96 DLOG(ERROR) << "Cannot create Cairo surface for PdfPsMetafile!"; |
116 CleanUpSurface(&surface_); | 97 CleanUpSurface(&surface_); |
117 return false; | 98 return false; |
118 } | 99 } |
119 | 100 |
120 // Creates a context. | 101 // Creates a context. |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 double width = | 162 double width = |
182 width_in_points + margin_left_in_points + margin_right_in_points; | 163 width_in_points + margin_left_in_points + margin_right_in_points; |
183 double height = | 164 double height = |
184 height_in_points + margin_top_in_points + margin_bottom_in_points; | 165 height_in_points + margin_top_in_points + margin_bottom_in_points; |
185 | 166 |
186 // Don't let WebKit draw over the margins. | 167 // Don't let WebKit draw over the margins. |
187 cairo_surface_set_device_offset(surface_, | 168 cairo_surface_set_device_offset(surface_, |
188 margin_left_in_points, | 169 margin_left_in_points, |
189 margin_top_in_points); | 170 margin_top_in_points); |
190 | 171 |
191 switch (format_) { | 172 cairo_pdf_surface_set_size(surface_, width, height); |
192 case PDF: | |
193 cairo_pdf_surface_set_size(surface_, width, height); | |
194 break; | |
195 | |
196 case PS: | |
197 cairo_ps_surface_set_size(surface_, width, height); | |
198 break; | |
199 | |
200 default: | |
201 NOTREACHED(); | |
202 CleanUpAll(); | |
203 return NULL; | |
204 } | |
205 | |
206 return context_; | 173 return context_; |
207 } | 174 } |
208 | 175 |
209 bool PdfPsMetafile::FinishPage() { | 176 bool PdfPsMetafile::FinishPage() { |
210 DCHECK(IsSurfaceValid(surface_)); | 177 DCHECK(IsSurfaceValid(surface_)); |
211 DCHECK(IsContextValid(context_)); | 178 DCHECK(IsContextValid(context_)); |
212 | 179 |
213 // Flushes all rendering for current page. | 180 // Flushes all rendering for current page. |
214 cairo_surface_flush(surface_); | 181 cairo_surface_flush(surface_); |
215 cairo_show_page(context_); | 182 cairo_show_page(context_); |
216 return true; | 183 return true; |
217 } | 184 } |
218 | 185 |
219 void PdfPsMetafile::Close() { | 186 void PdfPsMetafile::Close() { |
220 DCHECK(IsSurfaceValid(surface_)); | 187 DCHECK(IsSurfaceValid(surface_)); |
221 DCHECK(IsContextValid(context_)); | 188 DCHECK(IsContextValid(context_)); |
222 | 189 |
223 cairo_surface_finish(surface_); | 190 cairo_surface_finish(surface_); |
224 | 191 |
225 // If we have raw PDF/PS data set use that instead of what was drawn. | 192 // If we have raw PDF data set use that instead of what was drawn. |
226 if (!raw_override_data_.empty()) { | 193 if (!raw_override_data_.empty()) { |
227 data_ = raw_override_data_; | 194 data_ = raw_override_data_; |
228 raw_override_data_.clear(); | 195 raw_override_data_.clear(); |
229 } | 196 } |
230 DCHECK(!data_.empty()); // Make sure we did get something. | 197 DCHECK(!data_.empty()); // Make sure we did get something. |
231 | 198 |
232 CleanUpContext(&context_); | 199 CleanUpContext(&context_); |
233 CleanUpSurface(&surface_); | 200 CleanUpSurface(&surface_); |
234 } | 201 } |
235 | 202 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 data_.clear(); | 256 data_.clear(); |
290 skia::VectorPlatformDevice::ClearFontCache(); | 257 skia::VectorPlatformDevice::ClearFontCache(); |
291 } | 258 } |
292 | 259 |
293 const double PdfPsMetafile::kTopMarginInInch = 0.25; | 260 const double PdfPsMetafile::kTopMarginInInch = 0.25; |
294 const double PdfPsMetafile::kBottomMarginInInch = 0.56; | 261 const double PdfPsMetafile::kBottomMarginInInch = 0.56; |
295 const double PdfPsMetafile::kLeftMarginInInch = 0.25; | 262 const double PdfPsMetafile::kLeftMarginInInch = 0.25; |
296 const double PdfPsMetafile::kRightMarginInInch = 0.25; | 263 const double PdfPsMetafile::kRightMarginInInch = 0.25; |
297 | 264 |
298 } // namespace printing | 265 } // namespace printing |
OLD | NEW |