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

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: Making virtual methods not virtual (for clang bots) 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
« no previous file with comments | « printing/pdf_ps_metafile_cairo.h ('k') | printing/pdf_ps_metafile_cairo_unittest.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) 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 cairo_t* PdfPsMetafile::context() const {
212 return context_;
213 }
214
215 bool PdfPsMetafile::SaveTo(const FilePath& file_path) const {
221 // We need to check at least these two members to ensure that either Init() 216 // 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. 217 // has been called to initialize |data_|, or metafile has been closed.
223 DCHECK(!context_); 218 DCHECK(!context_);
219 DCHECK(!data_.empty());
220
221 bool success = true;
222 if (file_util::WriteFile(file_path, data_.data(), GetDataSize())
223 != static_cast<int>(GetDataSize())) {
224 DLOG(ERROR) << "Failed to save file " << file_path.value().c_str();
225 success = false;
226 }
227 return success;
228 }
229
230 gfx::Rect PdfPsMetafile::GetPageBounds(unsigned int page_number) const {
231 NOTIMPLEMENTED();
232 return gfx::Rect();
233 }
234
235 unsigned int PdfPsMetafile::GetPageCount() const {
236 NOTIMPLEMENTED();
237 return 1;
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 } // namespace printing 282 } // namespace printing
OLDNEW
« no previous file with comments | « printing/pdf_ps_metafile_cairo.h ('k') | printing/pdf_ps_metafile_cairo_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698