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

Side by Side Diff: printing/pdf_ps_metafile_cairo.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: Changed DCHECK to count partial writes as failures. 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
OLDNEW
1 // Copyright (c) 2011 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 11
12 #include "base/eintr_wrapper.h" 12 #include "base/eintr_wrapper.h"
13 #include "base/file_descriptor_posix.h" 13 #include "base/file_descriptor_posix.h"
14 #include "base/file_util.h" 14 #include "base/file_util.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "printing/units.h" 16 #include "printing/units.h"
17 #include "skia/ext/vector_platform_device_linux.h" 17 #include "skia/ext/vector_platform_device_linux.h"
18 #include "ui/gfx/rect.h"
19 #include "ui/gfx/size.h"
18 20
19 namespace { 21 namespace {
20 22
21 const cairo_user_data_key_t kPdfMetafileKey = {0}; 23 const cairo_user_data_key_t kPdfMetafileKey = {0};
22 24
23 // Tests if |surface| is valid. 25 // Tests if |surface| is valid.
24 bool IsSurfaceValid(cairo_surface_t* surface) { 26 bool IsSurfaceValid(cairo_surface_t* surface) {
25 return cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS; 27 return cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS;
26 } 28 }
27 29
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 // Creates a context. 103 // Creates a context.
102 context_ = cairo_create(surface_); 104 context_ = cairo_create(surface_);
103 if (!IsContextValid(context_)) { 105 if (!IsContextValid(context_)) {
104 DLOG(ERROR) << "Cannot create Cairo context for PdfPsMetafile!"; 106 DLOG(ERROR) << "Cannot create Cairo context for PdfPsMetafile!";
105 CleanUpContext(&context_); 107 CleanUpContext(&context_);
106 CleanUpSurface(&surface_); 108 CleanUpSurface(&surface_);
107 return false; 109 return false;
108 } 110 }
109 111
110 cairo_set_user_data(context_, &kPdfMetafileKey, this, DestroyContextData); 112 cairo_set_user_data(context_, &kPdfMetafileKey, this, DestroyContextData);
111
112 return true; 113 return true;
113 } 114 }
114 115
115 bool PdfPsMetafile::Init(const void* src_buffer, uint32 src_buffer_size) { 116 bool PdfPsMetafile::Init(const void* src_buffer, uint32 src_buffer_size) {
116 // We need to check at least these two members to ensure Init() has not been 117 // We need to check at least these two members to ensure Init() has not been
117 // called before 118 // called before
118 DCHECK(!context_); 119 DCHECK(!context_);
119 DCHECK(data_.empty()); 120 DCHECK(data_.empty());
120 121
121 if (src_buffer == NULL || src_buffer_size == 0) 122 if (src_buffer == NULL || src_buffer_size == 0)
122 return false; 123 return false;
123 124
124 data_ = std::string(reinterpret_cast<const char*>(src_buffer), 125 data_ = std::string(reinterpret_cast<const char*>(src_buffer),
125 src_buffer_size); 126 src_buffer_size);
126
127 return true; 127 return true;
128 } 128 }
129 129
130 bool PdfPsMetafile::SetRawData(const void* src_buffer, 130 bool PdfPsMetafile::SetRawData(const void* src_buffer,
131 uint32 src_buffer_size) { 131 uint32 src_buffer_size) {
132 if (!context_) { 132 if (!context_) {
133 // If Init has not already been called, just call Init() 133 // If Init has not already been called, just call Init()
134 return Init(src_buffer, src_buffer_size); 134 return Init(src_buffer, src_buffer_size);
135 } 135 }
136 // If a context has already been created, remember this data in 136 // If a context has already been created, remember this data in
137 // raw_override_data_ 137 // raw_override_data_
138 if (src_buffer == NULL || src_buffer_size == 0) 138 if (src_buffer == NULL || src_buffer_size == 0)
139 return false; 139 return false;
140 140
141 raw_override_data_ = std::string(reinterpret_cast<const char*>(src_buffer), 141 raw_override_data_ = std::string(reinterpret_cast<const char*>(src_buffer),
142 src_buffer_size); 142 src_buffer_size);
143 143
144 return true; 144 return true;
145 } 145 }
146 146
147 cairo_t* PdfPsMetafile::StartPage(double width_in_points, 147 cairo_t* PdfPsMetafile::StartPage(const gfx::Size& page_size,
148 double height_in_points,
149 double margin_top_in_points, 148 double margin_top_in_points,
150 double margin_right_in_points,
151 double margin_bottom_in_points,
152 double margin_left_in_points) { 149 double margin_left_in_points) {
153 DCHECK(IsSurfaceValid(surface_)); 150 DCHECK(IsSurfaceValid(surface_));
154 DCHECK(IsContextValid(context_)); 151 DCHECK(IsContextValid(context_));
155 // Passing this check implies page_surface_ is NULL, and current_page_ is 152 // Passing this check implies page_surface_ is NULL, and current_page_ is
156 // empty. 153 // empty.
157 DCHECK_GT(width_in_points, 0.); 154 DCHECK_GT(page_size.width(), 0);
158 DCHECK_GT(height_in_points, 0.); 155 DCHECK_GT(page_size.height(), 0);
159
160 // We build in extra room for the margins. The Cairo PDF backend will scale
161 // the output to fit a page.
162 double width =
163 width_in_points + margin_left_in_points + margin_right_in_points;
164 double height =
165 height_in_points + margin_top_in_points + margin_bottom_in_points;
166 156
167 // Don't let WebKit draw over the margins. 157 // Don't let WebKit draw over the margins.
168 cairo_surface_set_device_offset(surface_, 158 cairo_surface_set_device_offset(surface_,
169 margin_left_in_points, 159 margin_left_in_points,
170 margin_top_in_points); 160 margin_top_in_points);
171 161
172 cairo_pdf_surface_set_size(surface_, width, height); 162 cairo_pdf_surface_set_size(surface_, page_size.width(), page_size.height());
173 return context_; 163 return context_;
174 } 164 }
175 165
176 bool PdfPsMetafile::FinishPage() { 166 bool PdfPsMetafile::FinishPage() {
177 DCHECK(IsSurfaceValid(surface_)); 167 DCHECK(IsSurfaceValid(surface_));
178 DCHECK(IsContextValid(context_)); 168 DCHECK(IsContextValid(context_));
179 169
180 // Flushes all rendering for current page. 170 // Flushes all rendering for current page.
181 cairo_surface_flush(surface_); 171 cairo_surface_flush(surface_);
182 cairo_show_page(context_); 172 cairo_show_page(context_);
183 return true; 173 return true;
184 } 174 }
185 175
186 void PdfPsMetafile::Close() { 176 bool PdfPsMetafile::Close() {
187 DCHECK(IsSurfaceValid(surface_)); 177 DCHECK(IsSurfaceValid(surface_));
188 DCHECK(IsContextValid(context_)); 178 DCHECK(IsContextValid(context_));
189 179
190 cairo_surface_finish(surface_); 180 cairo_surface_finish(surface_);
191 181
192 // If we have raw PDF data set use that instead of what was drawn. 182 // If we have raw PDF data set use that instead of what was drawn.
193 if (!raw_override_data_.empty()) { 183 if (!raw_override_data_.empty()) {
194 data_ = raw_override_data_; 184 data_ = raw_override_data_;
195 raw_override_data_.clear(); 185 raw_override_data_.clear();
196 } 186 }
197 DCHECK(!data_.empty()); // Make sure we did get something. 187 DCHECK(!data_.empty()); // Make sure we did get something.
198 188
199 CleanUpContext(&context_); 189 CleanUpContext(&context_);
200 CleanUpSurface(&surface_); 190 CleanUpSurface(&surface_);
191 return true;
201 } 192 }
202 193
203 uint32 PdfPsMetafile::GetDataSize() const { 194 uint32 PdfPsMetafile::GetDataSize() const {
204 // We need to check at least these two members to ensure that either Init() 195 // We need to check at least these two members to ensure that either Init()
205 // has been called to initialize |data_|, or metafile has been closed. 196 // has been called to initialize |data_|, or metafile has been closed.
206 DCHECK(!context_); 197 DCHECK(!context_);
207 DCHECK(!data_.empty()); 198 DCHECK(!data_.empty());
208 199
209 return data_.size(); 200 return data_.size();
210 } 201 }
211 202
212 bool PdfPsMetafile::GetData(void* dst_buffer, uint32 dst_buffer_size) const { 203 bool PdfPsMetafile::GetData(void* dst_buffer, uint32 dst_buffer_size) const {
213 DCHECK(dst_buffer); 204 DCHECK(dst_buffer);
214 DCHECK_GT(dst_buffer_size, 0u); 205 DCHECK_GT(dst_buffer_size, 0u);
215 memcpy(dst_buffer, data_.data(), dst_buffer_size); 206 memcpy(dst_buffer, data_.data(), dst_buffer_size);
216 207
217 return true; 208 return true;
218 } 209 }
219 210
220 bool PdfPsMetafile::SaveTo(const base::FileDescriptor& fd) const { 211 bool PdfPsMetafile::SaveTo(const FilePath& file_path) const {
221 // We need to check at least these two members to ensure that either Init() 212 // We need to check at least these two members to ensure that either Init()
222 // has been called to initialize |data_|, or metafile has been closed. 213 // has been called to initialize |data_|, or metafile has been closed.
223 DCHECK(!context_); 214 DCHECK(!context_);
215 DCHECK(!data_.empty());
216
217 bool success = true;
218 if (file_util::WriteFile(file_path, data_.data(), GetDataSize())
219 != static_cast<int>(GetDataSize())) {
dpapad 2011/03/15 23:39:34 Making sure that everything was written. (static_c
220 DLOG(ERROR) << "Failed to save file " << file_path.value().c_str();
221 success = false;
222 }
223 return success;
224 }
225
226 gfx::Rect PdfPsMetafile::GetPageBounds(unsigned int page_number) const {
227 NOTIMPLEMENTED();
228 return gfx::Rect();
229 }
230
231 unsigned int PdfPsMetafile::GetPageCount() const {
232 NOTIMPLEMENTED();
233 return 1;
234 }
235
236 #if defined(OS_CHROMEOS)
237 bool PdfPsMetafile::SaveToFD(const base::FileDescriptor& fd) const {
238 // We need to check at least these two members to ensure that either Init()
239 // has been called to initialize |data_|, or metafile has been closed.
240 DCHECK(!context_);
224 DCHECK(!data_.empty()); 241 DCHECK(!data_.empty());
225 242
226 if (fd.fd < 0) { 243 if (fd.fd < 0) {
227 DLOG(ERROR) << "Invalid file descriptor!"; 244 DLOG(ERROR) << "Invalid file descriptor!";
228 return false; 245 return false;
229 } 246 }
230 247
231 bool success = true; 248 bool success = true;
232 if (file_util::WriteFileDescriptor(fd.fd, data_.data(), 249 if (file_util::WriteFileDescriptor(fd.fd, data_.data(),
233 GetDataSize()) < 0) { 250 GetDataSize()) < 0) {
234 DLOG(ERROR) << "Failed to save file with fd " << fd.fd; 251 DLOG(ERROR) << "Failed to save file with fd " << fd.fd;
235 success = false; 252 success = false;
236 } 253 }
237 254
238 if (fd.auto_close) { 255 if (fd.auto_close) {
239 if (HANDLE_EINTR(close(fd.fd)) < 0) { 256 if (HANDLE_EINTR(close(fd.fd)) < 0) {
240 DPLOG(WARNING) << "close"; 257 DPLOG(WARNING) << "close";
241 success = false; 258 success = false;
242 } 259 }
243 } 260 }
244 261
245 return success; 262 return success;
246 } 263 }
264 #endif // if defined(OS_CHROMEOS)
247 265
248 PdfPsMetafile* PdfPsMetafile::FromCairoContext(cairo_t* context) { 266 PdfPsMetafile* PdfPsMetafile::FromCairoContext(cairo_t* context) {
249 return reinterpret_cast<PdfPsMetafile*>( 267 return reinterpret_cast<PdfPsMetafile*>(
250 cairo_get_user_data(context, &kPdfMetafileKey)); 268 cairo_get_user_data(context, &kPdfMetafileKey));
251 } 269 }
252 270
253 void PdfPsMetafile::CleanUpAll() { 271 void PdfPsMetafile::CleanUpAll() {
254 CleanUpContext(&context_); 272 CleanUpContext(&context_);
255 CleanUpSurface(&surface_); 273 CleanUpSurface(&surface_);
256 data_.clear(); 274 data_.clear();
257 skia::VectorPlatformDevice::ClearFontCache(); 275 skia::VectorPlatformDevice::ClearFontCache();
258 } 276 }
259 277
260 } // namespace printing 278 } // namespace printing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698