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

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: Fixed win unittests, style changes, cleaned up StartPage parameters for cairo. 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);
127 return true;
128 }
126 129
127 return true; 130 unsigned int PdfPsMetafile::GetPageCount() const {
vandebo (ex-Chrome) 2011/03/14 22:55:05 Since you are adding this method, you should be it
dpapad 2011/03/15 16:11:06 Done.
131 NOTIMPLEMENTED();
132 return 1;
128 } 133 }
129 134
130 bool PdfPsMetafile::SetRawData(const void* src_buffer, 135 bool PdfPsMetafile::SetRawData(const void* src_buffer,
131 uint32 src_buffer_size) { 136 uint32 src_buffer_size) {
132 if (!context_) { 137 if (!context_) {
133 // If Init has not already been called, just call Init() 138 // If Init has not already been called, just call Init()
134 return Init(src_buffer, src_buffer_size); 139 return Init(src_buffer, src_buffer_size);
135 } 140 }
136 // If a context has already been created, remember this data in 141 // If a context has already been created, remember this data in
137 // raw_override_data_ 142 // raw_override_data_
138 if (src_buffer == NULL || src_buffer_size == 0) 143 if (src_buffer == NULL || src_buffer_size == 0)
139 return false; 144 return false;
140 145
141 raw_override_data_ = std::string(reinterpret_cast<const char*>(src_buffer), 146 raw_override_data_ = std::string(reinterpret_cast<const char*>(src_buffer),
142 src_buffer_size); 147 src_buffer_size);
143 148
144 return true; 149 return true;
145 } 150 }
146 151
147 cairo_t* PdfPsMetafile::StartPage(double width_in_points, 152 cairo_t* PdfPsMetafile::StartPage(const gfx::Size& page_size,
148 double height_in_points,
149 double margin_top_in_points, 153 double margin_top_in_points,
150 double margin_right_in_points,
151 double margin_bottom_in_points,
152 double margin_left_in_points) { 154 double margin_left_in_points) {
153 DCHECK(IsSurfaceValid(surface_)); 155 DCHECK(IsSurfaceValid(surface_));
154 DCHECK(IsContextValid(context_)); 156 DCHECK(IsContextValid(context_));
155 // Passing this check implies page_surface_ is NULL, and current_page_ is 157 // Passing this check implies page_surface_ is NULL, and current_page_ is
156 // empty. 158 // empty.
157 DCHECK_GT(width_in_points, 0.); 159 DCHECK_GT(page_size.width(), 0.);
158 DCHECK_GT(height_in_points, 0.); 160 DCHECK_GT(page_size.height(), 0.);
159 161
160 // We build in extra room for the margins. The Cairo PDF backend will scale 162 // We build in extra room for the margins. The Cairo PDF backend will scale
vandebo (ex-Chrome) 2011/03/14 22:55:05 This comment doesn't make sense any more.
dpapad 2011/03/15 16:11:06 Done.
161 // the output to fit a page. 163 // the output to fit a page.
162 double width = 164 double width = page_size.width();
vandebo (ex-Chrome) 2011/03/14 22:55:05 Doesn't look like we need these variables any more
dpapad 2011/03/15 16:11:06 Done. That's correct. I just kept them because pdf
163 width_in_points + margin_left_in_points + margin_right_in_points; 165 double height = page_size.height();
164 double height =
165 height_in_points + margin_top_in_points + margin_bottom_in_points;
166 166
167 // Don't let WebKit draw over the margins. 167 // Don't let WebKit draw over the margins.
168 cairo_surface_set_device_offset(surface_, 168 cairo_surface_set_device_offset(surface_,
169 margin_left_in_points, 169 margin_left_in_points,
170 margin_top_in_points); 170 margin_top_in_points);
171 171
172 cairo_pdf_surface_set_size(surface_, width, height); 172 cairo_pdf_surface_set_size(surface_, width, height);
173 return context_; 173 return context_;
174 } 174 }
175 175
176 bool PdfPsMetafile::FinishPage() { 176 bool PdfPsMetafile::FinishPage() {
177 DCHECK(IsSurfaceValid(surface_)); 177 DCHECK(IsSurfaceValid(surface_));
178 DCHECK(IsContextValid(context_)); 178 DCHECK(IsContextValid(context_));
179 179
180 // Flushes all rendering for current page. 180 // Flushes all rendering for current page.
181 cairo_surface_flush(surface_); 181 cairo_surface_flush(surface_);
182 cairo_show_page(context_); 182 cairo_show_page(context_);
183 return true; 183 return true;
184 } 184 }
185 185
186 void PdfPsMetafile::Close() { 186 bool PdfPsMetafile::Close() {
187 DCHECK(IsSurfaceValid(surface_)); 187 DCHECK(IsSurfaceValid(surface_));
188 DCHECK(IsContextValid(context_)); 188 DCHECK(IsContextValid(context_));
189 189
190 cairo_surface_finish(surface_); 190 cairo_surface_finish(surface_);
191 191
192 // If we have raw PDF data set use that instead of what was drawn. 192 // If we have raw PDF data set use that instead of what was drawn.
193 if (!raw_override_data_.empty()) { 193 if (!raw_override_data_.empty()) {
194 data_ = raw_override_data_; 194 data_ = raw_override_data_;
195 raw_override_data_.clear(); 195 raw_override_data_.clear();
196 } 196 }
197 DCHECK(!data_.empty()); // Make sure we did get something. 197 DCHECK(!data_.empty()); // Make sure we did get something.
198 198
199 CleanUpContext(&context_); 199 CleanUpContext(&context_);
200 CleanUpSurface(&surface_); 200 CleanUpSurface(&surface_);
201 return true;
201 } 202 }
202 203
203 uint32 PdfPsMetafile::GetDataSize() const { 204 uint32 PdfPsMetafile::GetDataSize() const {
204 // We need to check at least these two members to ensure that either Init() 205 // 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. 206 // has been called to initialize |data_|, or metafile has been closed.
206 DCHECK(!context_); 207 DCHECK(!context_);
207 DCHECK(!data_.empty()); 208 DCHECK(!data_.empty());
208 209
209 return data_.size(); 210 return data_.size();
210 } 211 }
211 212
212 bool PdfPsMetafile::GetData(void* dst_buffer, uint32 dst_buffer_size) const { 213 bool PdfPsMetafile::GetData(void* dst_buffer, uint32 dst_buffer_size) const {
213 DCHECK(dst_buffer); 214 DCHECK(dst_buffer);
214 DCHECK_GT(dst_buffer_size, 0u); 215 DCHECK_GT(dst_buffer_size, 0u);
215 memcpy(dst_buffer, data_.data(), dst_buffer_size); 216 memcpy(dst_buffer, data_.data(), dst_buffer_size);
216 217
217 return true; 218 return true;
218 } 219 }
219 220
220 bool PdfPsMetafile::SaveTo(const base::FileDescriptor& fd) const { 221 bool PdfPsMetafile::SaveTo(const FilePath& file_path) const {
221 // We need to check at least these two members to ensure that either Init() 222 // 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. 223 // has been called to initialize |data_|, or metafile has been closed.
223 DCHECK(!context_); 224 DCHECK(!context_);
225 DCHECK(!data_.empty());
226
227 bool success = true;
228 if (file_util::WriteFile(file_path, data_.data(), GetDataSize()) < 0) {
229 DLOG(ERROR) << "Failed to save file " << file_path.value().c_str();
230 success = false;
231 }
232 return success;
233 }
234
235 gfx::Rect PdfPsMetafile::GetPageBounds(unsigned int page_number) const {
236 NOTIMPLEMENTED();
237 return gfx::Rect();
238 }
239
240 #if defined(OS_CHROMEOS)
241 bool PdfPsMetafile::SaveToFD(const base::FileDescriptor& fd) const {
242 // We need to check at least these two members to ensure that either Init()
243 // has been called to initialize |data_|, or metafile has been closed.
244 DCHECK(!context_);
224 DCHECK(!data_.empty()); 245 DCHECK(!data_.empty());
225 246
226 if (fd.fd < 0) { 247 if (fd.fd < 0) {
227 DLOG(ERROR) << "Invalid file descriptor!"; 248 DLOG(ERROR) << "Invalid file descriptor!";
228 return false; 249 return false;
229 } 250 }
230 251
231 bool success = true; 252 bool success = true;
232 if (file_util::WriteFileDescriptor(fd.fd, data_.data(), 253 if (file_util::WriteFileDescriptor(fd.fd, data_.data(),
233 GetDataSize()) < 0) { 254 GetDataSize()) < 0) {
234 DLOG(ERROR) << "Failed to save file with fd " << fd.fd; 255 DLOG(ERROR) << "Failed to save file with fd " << fd.fd;
235 success = false; 256 success = false;
236 } 257 }
237 258
238 if (fd.auto_close) { 259 if (fd.auto_close) {
239 if (HANDLE_EINTR(close(fd.fd)) < 0) { 260 if (HANDLE_EINTR(close(fd.fd)) < 0) {
240 DPLOG(WARNING) << "close"; 261 DPLOG(WARNING) << "close";
241 success = false; 262 success = false;
242 } 263 }
243 } 264 }
244 265
245 return success; 266 return success;
246 } 267 }
268 #endif // if defined(OS_CHROMEOS)
247 269
248 PdfPsMetafile* PdfPsMetafile::FromCairoContext(cairo_t* context) { 270 PdfPsMetafile* PdfPsMetafile::FromCairoContext(cairo_t* context) {
249 return reinterpret_cast<PdfPsMetafile*>( 271 return reinterpret_cast<PdfPsMetafile*>(
250 cairo_get_user_data(context, &kPdfMetafileKey)); 272 cairo_get_user_data(context, &kPdfMetafileKey));
251 } 273 }
252 274
253 void PdfPsMetafile::CleanUpAll() { 275 void PdfPsMetafile::CleanUpAll() {
254 CleanUpContext(&context_); 276 CleanUpContext(&context_);
255 CleanUpSurface(&surface_); 277 CleanUpSurface(&surface_);
256 data_.clear(); 278 data_.clear();
257 skia::VectorPlatformDevice::ClearFontCache(); 279 skia::VectorPlatformDevice::ClearFontCache();
258 } 280 }
259 281
260 const double PdfPsMetafile::kTopMarginInInch = 0.25; 282 const double PdfPsMetafile::kTopMarginInInch = 0.25;
261 const double PdfPsMetafile::kBottomMarginInInch = 0.56; 283 const double PdfPsMetafile::kBottomMarginInInch = 0.56;
262 const double PdfPsMetafile::kLeftMarginInInch = 0.25; 284 const double PdfPsMetafile::kLeftMarginInInch = 0.25;
263 const double PdfPsMetafile::kRightMarginInInch = 0.25; 285 const double PdfPsMetafile::kRightMarginInInch = 0.25;
264 286
265 } // namespace printing 287 } // namespace printing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698