blob: 80d4931362372bb26b571e041f9294f7d85e39d7 [file] [log] [blame]
[email protected]8f879292011-04-08 00:21:201// 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
3// found in the LICENSE file.
4
5#include "printing/pdf_metafile_skia.h"
6
7#include "base/eintr_wrapper.h"
8#include "base/file_descriptor_posix.h"
9#include "base/file_util.h"
10#include "skia/ext/vector_platform_device_skia.h"
11#include "third_party/skia/include/core/SkRefCnt.h"
[email protected]a34f0122011-04-12 17:36:3912#include "third_party/skia/include/core/SkScalar.h"
[email protected]8f879292011-04-08 00:21:2013#include "third_party/skia/include/core/SkStream.h"
14#include "third_party/skia/include/pdf/SkPDFDevice.h"
15#include "third_party/skia/include/pdf/SkPDFDocument.h"
16#include "third_party/skia/include/pdf/SkPDFPage.h"
17#include "ui/gfx/point.h"
18#include "ui/gfx/rect.h"
19#include "ui/gfx/size.h"
20
21namespace printing {
22
23struct PdfMetafileSkiaData {
24 SkRefPtr<SkPDFDevice> current_page_;
25 SkPDFDocument pdf_doc_;
26 SkDynamicMemoryWStream pdf_stream_;
27};
28
29PdfMetafileSkia::~PdfMetafileSkia() {}
30
31bool PdfMetafileSkia::Init() {
32 return true;
33}
34bool PdfMetafileSkia::InitFromData(const void* src_buffer,
35 uint32 src_buffer_size) {
36 return data_->pdf_stream_.write(src_buffer, src_buffer_size);
37}
38
39skia::PlatformDevice* PdfMetafileSkia::StartPageForVectorCanvas(
[email protected]39892b92011-04-30 02:24:4440 const gfx::Size& page_size, const gfx::Rect& content_area,
[email protected]8f879292011-04-08 00:21:2041 const float& scale_factor) {
42 DCHECK(data_->current_page_.get() == NULL);
43
[email protected]a34f0122011-04-12 17:36:3944 // Adjust for the margins and apply the scale factor.
45 SkMatrix transform;
[email protected]39892b92011-04-30 02:24:4446 transform.setTranslate(SkIntToScalar(content_area.x()),
47 SkIntToScalar(content_area.y()));
[email protected]a34f0122011-04-12 17:36:3948 transform.preScale(SkFloatToScalar(scale_factor),
49 SkFloatToScalar(scale_factor));
50
[email protected]39892b92011-04-30 02:24:4451 // TODO(ctguil): Refactor: don't create the PDF device explicitly here.
52 SkISize pdf_page_size = SkISize::Make(page_size.width(), page_size.height());
53 SkISize pdf_content_size =
54 SkISize::Make(content_area.width(), content_area.height());
55 SkRefPtr<SkPDFDevice> pdf_device =
56 new SkPDFDevice(pdf_page_size, pdf_content_size, transform);
57 pdf_device->unref(); // SkRefPtr and new both took a reference.
[email protected]8f879292011-04-08 00:21:2058 skia::VectorPlatformDeviceSkia* device =
[email protected]39892b92011-04-30 02:24:4459 new skia::VectorPlatformDeviceSkia(pdf_device.get());
[email protected]8f879292011-04-08 00:21:2060 data_->current_page_ = device->PdfDevice();
61 return device;
62}
63
64bool PdfMetafileSkia::StartPage(const gfx::Size& page_size,
[email protected]39892b92011-04-30 02:24:4465 const gfx::Rect& content_area,
[email protected]8f879292011-04-08 00:21:2066 const float& scale_factor) {
67 NOTREACHED();
68 return NULL;
69}
70
71bool PdfMetafileSkia::FinishPage() {
72 DCHECK(data_->current_page_.get());
73
74 data_->pdf_doc_.appendPage(data_->current_page_);
75 data_->current_page_ = NULL;
76 return true;
77}
78
79bool PdfMetafileSkia::FinishDocument() {
80 // Don't do anything if we've already set the data in InitFromData.
81 if (data_->pdf_stream_.getOffset())
82 return true;
83
84 if (data_->current_page_.get())
85 FinishPage();
86 return data_->pdf_doc_.emitPDF(&data_->pdf_stream_);
87}
88
89uint32 PdfMetafileSkia::GetDataSize() const {
90 return data_->pdf_stream_.getOffset();
91}
92
93bool PdfMetafileSkia::GetData(void* dst_buffer,
94 uint32 dst_buffer_size) const {
95 if (dst_buffer_size < GetDataSize())
96 return false;
97
98 memcpy(dst_buffer, data_->pdf_stream_.getStream(), dst_buffer_size);
99 return true;
100}
101
102bool PdfMetafileSkia::SaveTo(const FilePath& file_path) const {
103 DCHECK_GT(data_->pdf_stream_.getOffset(), 0U);
104 if (file_util::WriteFile(file_path, data_->pdf_stream_.getStream(),
105 GetDataSize()) != static_cast<int>(GetDataSize())) {
106 DLOG(ERROR) << "Failed to save file " << file_path.value().c_str();
107 return false;
108 }
109 return true;
110}
111
112gfx::Rect PdfMetafileSkia::GetPageBounds(unsigned int page_number) const {
113 // TODO(vandebo) add a method to get the page size for a given page to
114 // SkPDFDocument.
115 NOTIMPLEMENTED();
116 return gfx::Rect();
117}
118
119unsigned int PdfMetafileSkia::GetPageCount() const {
120 // TODO(vandebo) add a method to get the number of pages to SkPDFDocument.
121 NOTIMPLEMENTED();
122 return 0;
123}
124
125gfx::NativeDrawingContext PdfMetafileSkia::context() const {
126 NOTREACHED();
127 return NULL;
128}
129
130#if defined(OS_WIN)
131bool PdfMetafileSkia::Playback(gfx::NativeDrawingContext hdc,
132 const RECT* rect) const {
133 NOTREACHED();
134 return false;
135}
136
137bool PdfMetafileSkia::SafePlayback(gfx::NativeDrawingContext hdc) const {
138 NOTREACHED();
139 return false;
140}
141
142HENHMETAFILE PdfMetafileSkia::emf() const {
143 NOTREACHED();
144 return NULL;
145}
146#endif // if defined(OS_WIN)
147
148#if defined(OS_CHROMEOS)
149bool PdfMetafileSkia::SaveToFD(const base::FileDescriptor& fd) const {
150 DCHECK_GT(data_->pdf_stream_.getOffset(), 0U);
151
152 if (fd.fd < 0) {
153 DLOG(ERROR) << "Invalid file descriptor!";
154 return false;
155 }
156
157 bool result = true;
158 if (file_util::WriteFileDescriptor(fd.fd, data_->pdf_stream_.getStream(),
159 GetDataSize()) !=
160 static_cast<int>(GetDataSize())) {
161 DLOG(ERROR) << "Failed to save file with fd " << fd.fd;
162 result = false;
163 }
164
165 if (fd.auto_close) {
166 if (HANDLE_EINTR(close(fd.fd)) < 0) {
167 DPLOG(WARNING) << "close";
168 result = false;
169 }
170 }
171 return result;
172}
173#endif
174
175PdfMetafileSkia::PdfMetafileSkia() : data_(new PdfMetafileSkiaData) {}
176
177} // namespace printing