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

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: Fixes for CHROMEOS 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 122
121 if (src_buffer == NULL || src_buffer_size == 0) 123 if (src_buffer == NULL || src_buffer_size == 0)
122 return false; 124 return false;
123 125
124 data_ = std::string(reinterpret_cast<const char*>(src_buffer), 126 data_ = std::string(reinterpret_cast<const char*>(src_buffer),
125 src_buffer_size); 127 src_buffer_size);
126 128
127 return true; 129 return true;
128 } 130 }
129 131
130 bool PdfPsMetafile::SetRawData(const void* src_buffer, 132 uint32 PdfPsMetafile::GetDataSize() const {
131 uint32 src_buffer_size) { 133 // We need to check at least these two members to ensure that either Init()
132 if (!context_) { 134 // has been called to initialize |data_|, or metafile has been closed.
133 // If Init has not already been called, just call Init() 135 DCHECK(!context_);
134 return Init(src_buffer, src_buffer_size); 136 DCHECK(!data_.empty());
135 }
136 // If a context has already been created, remember this data in
137 // raw_override_data_
138 if (src_buffer == NULL || src_buffer_size == 0)
139 return false;
140 137
141 raw_override_data_ = std::string(reinterpret_cast<const char*>(src_buffer), 138 return data_.size();
142 src_buffer_size); 139 }
140
141 bool PdfPsMetafile::GetData(void* dst_buffer, uint32 dst_buffer_size) const {
142 DCHECK(dst_buffer);
143 DCHECK_GT(dst_buffer_size, 0u);
144 memcpy(dst_buffer, data_.data(), dst_buffer_size);
143 145
144 return true; 146 return true;
145 } 147 }
146 148
147 cairo_t* PdfPsMetafile::StartPage(double width_in_points,
148 double height_in_points,
149 double margin_top_in_points,
150 double margin_right_in_points,
151 double margin_bottom_in_points,
152 double margin_left_in_points) {
153 DCHECK(IsSurfaceValid(surface_));
154 DCHECK(IsContextValid(context_));
155 // Passing this check implies page_surface_ is NULL, and current_page_ is
156 // empty.
157 DCHECK_GT(width_in_points, 0.);
158 DCHECK_GT(height_in_points, 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
167 // Don't let WebKit draw over the margins.
168 cairo_surface_set_device_offset(surface_,
169 margin_left_in_points,
170 margin_top_in_points);
171
172 cairo_pdf_surface_set_size(surface_, width, height);
173 return context_;
174 }
175
176 bool PdfPsMetafile::FinishPage() { 149 bool PdfPsMetafile::FinishPage() {
177 DCHECK(IsSurfaceValid(surface_)); 150 DCHECK(IsSurfaceValid(surface_));
178 DCHECK(IsContextValid(context_)); 151 DCHECK(IsContextValid(context_));
179 152
180 // Flushes all rendering for current page. 153 // Flushes all rendering for current page.
181 cairo_surface_flush(surface_); 154 cairo_surface_flush(surface_);
182 cairo_show_page(context_); 155 cairo_show_page(context_);
183 return true; 156 return true;
184 } 157 }
185 158
186 void PdfPsMetafile::Close() { 159 void PdfPsMetafile::Close() {
187 DCHECK(IsSurfaceValid(surface_)); 160 DCHECK(IsSurfaceValid(surface_));
188 DCHECK(IsContextValid(context_)); 161 DCHECK(IsContextValid(context_));
189 162
190 cairo_surface_finish(surface_); 163 cairo_surface_finish(surface_);
191 164
192 // If we have raw PDF data set use that instead of what was drawn. 165 // If we have raw PDF data set use that instead of what was drawn.
193 if (!raw_override_data_.empty()) { 166 if (!raw_override_data_.empty()) {
194 data_ = raw_override_data_; 167 data_ = raw_override_data_;
195 raw_override_data_.clear(); 168 raw_override_data_.clear();
196 } 169 }
197 DCHECK(!data_.empty()); // Make sure we did get something. 170 DCHECK(!data_.empty()); // Make sure we did get something.
198 171
199 CleanUpContext(&context_); 172 CleanUpContext(&context_);
200 CleanUpSurface(&surface_); 173 CleanUpSurface(&surface_);
201 } 174 }
202 175
203 uint32 PdfPsMetafile::GetDataSize() const { 176 bool PdfPsMetafile::SaveTo(const FilePath& file_path) const {
204 // We need to check at least these two members to ensure that either Init() 177 // 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. 178 // has been called to initialize |data_|, or metafile has been closed.
206 DCHECK(!context_); 179 DCHECK(!context_);
207 DCHECK(!data_.empty()); 180 DCHECK(!data_.empty());
208 181
209 return data_.size(); 182 bool success = true;
183 if (file_util::WriteFile(file_path, data_.data(), GetDataSize()) < 0) {
184 DLOG(ERROR) << "Failed to save file " << file_path.value().c_str();
185 success = false;
186 }
187 return success;
210 } 188 }
211 189
212 bool PdfPsMetafile::GetData(void* dst_buffer, uint32 dst_buffer_size) const { 190 gfx::Rect PdfPsMetafile::GetPageBounds(unsigned int page_number) const {
213 DCHECK(dst_buffer); 191 NOTIMPLEMENTED();
214 DCHECK_GT(dst_buffer_size, 0u); 192 return gfx::Rect();
215 memcpy(dst_buffer, data_.data(), dst_buffer_size); 193 }
194
195 cairo_t* PdfPsMetafile::StartPage(const gfx::Size& page_size,
196 double margin_top_in_points,
197 double margin_right_in_points,
198 double margin_bottom_in_points,
199 double margin_left_in_points) {
200 DCHECK(IsSurfaceValid(surface_));
201 DCHECK(IsContextValid(context_));
202 // Passing this check implies page_surface_ is NULL, and current_page_ is
203 // empty.
204 DCHECK_GT(page_size.width(), 0.);
205 DCHECK_GT(page_size.height(), 0.);
206
207 // We build in extra room for the margins. The Cairo PDF backend will scale
208 // the output to fit a page.
209 double width =
210 page_size.width() + margin_left_in_points + margin_right_in_points;
211 double height =
212 page_size.height() + margin_top_in_points + margin_bottom_in_points;
213
214 // Don't let WebKit draw over the margins.
215 cairo_surface_set_device_offset(surface_,
216 margin_left_in_points,
217 margin_top_in_points);
218
219 cairo_pdf_surface_set_size(surface_, width, height);
220 return context_;
221 }
222
223 bool PdfPsMetafile::SetRawData(const void* src_buffer,
224 uint32 src_buffer_size) {
225 if (!context_) {
226 // If Init has not already been called, just call Init()
227 return Init(src_buffer, src_buffer_size);
228 }
229 // If a context has already been created, remember this data in
230 // raw_override_data_
231 if (src_buffer == NULL || src_buffer_size == 0)
232 return false;
233
234 raw_override_data_ = std::string(reinterpret_cast<const char*>(src_buffer),
235 src_buffer_size);
216 236
217 return true; 237 return true;
218 } 238 }
219 239
220 bool PdfPsMetafile::SaveTo(const base::FileDescriptor& fd) const { 240 #if defined(OS_CHROMEOS)
241 bool PdfPsMetafile::SaveToFD(const base::FileDescriptor& fd) const {
221 // We need to check at least these two members to ensure that either Init() 242 // 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. 243 // has been called to initialize |data_|, or metafile has been closed.
223 DCHECK(!context_); 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