| 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 |