blob: 72d89082c750822c220a2c9f8f8b2df45ba335f6 [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"
12#include "third_party/skia/include/core/SkStream.h"
13#include "third_party/skia/include/pdf/SkPDFDevice.h"
14#include "third_party/skia/include/pdf/SkPDFDocument.h"
15#include "third_party/skia/include/pdf/SkPDFPage.h"
16#include "ui/gfx/point.h"
17#include "ui/gfx/rect.h"
18#include "ui/gfx/size.h"
19
20namespace printing {
21
22struct PdfMetafileSkiaData {
23 SkRefPtr<SkPDFDevice> current_page_;
24 SkPDFDocument pdf_doc_;
25 SkDynamicMemoryWStream pdf_stream_;
26};
27
28PdfMetafileSkia::~PdfMetafileSkia() {}
29
30bool PdfMetafileSkia::Init() {
31 return true;
32}
33bool PdfMetafileSkia::InitFromData(const void* src_buffer,
34 uint32 src_buffer_size) {
35 return data_->pdf_stream_.write(src_buffer, src_buffer_size);
36}
37
38skia::PlatformDevice* PdfMetafileSkia::StartPageForVectorCanvas(
39 const gfx::Size& page_size, const gfx::Point& content_origin,
40 const float& scale_factor) {
41 DCHECK(data_->current_page_.get() == NULL);
42
43 skia::VectorPlatformDeviceSkia* device =
44 new skia::VectorPlatformDeviceSkia(page_size.width(), page_size.height(),
45 SkPDFDevice::kFlip_OriginTransform);
46 device->setInitialTransform(content_origin.x(), content_origin.y(),
47 scale_factor);
48 data_->current_page_ = device->PdfDevice();
49 return device;
50}
51
52bool PdfMetafileSkia::StartPage(const gfx::Size& page_size,
53 const gfx::Point& content_origin,
54 const float& scale_factor) {
55 NOTREACHED();
56 return NULL;
57}
58
59bool PdfMetafileSkia::FinishPage() {
60 DCHECK(data_->current_page_.get());
61
62 data_->pdf_doc_.appendPage(data_->current_page_);
63 data_->current_page_ = NULL;
64 return true;
65}
66
67bool PdfMetafileSkia::FinishDocument() {
68 // Don't do anything if we've already set the data in InitFromData.
69 if (data_->pdf_stream_.getOffset())
70 return true;
71
72 if (data_->current_page_.get())
73 FinishPage();
74 return data_->pdf_doc_.emitPDF(&data_->pdf_stream_);
75}
76
77uint32 PdfMetafileSkia::GetDataSize() const {
78 return data_->pdf_stream_.getOffset();
79}
80
81bool PdfMetafileSkia::GetData(void* dst_buffer,
82 uint32 dst_buffer_size) const {
83 if (dst_buffer_size < GetDataSize())
84 return false;
85
86 memcpy(dst_buffer, data_->pdf_stream_.getStream(), dst_buffer_size);
87 return true;
88}
89
90bool PdfMetafileSkia::SaveTo(const FilePath& file_path) const {
91 DCHECK_GT(data_->pdf_stream_.getOffset(), 0U);
92 if (file_util::WriteFile(file_path, data_->pdf_stream_.getStream(),
93 GetDataSize()) != static_cast<int>(GetDataSize())) {
94 DLOG(ERROR) << "Failed to save file " << file_path.value().c_str();
95 return false;
96 }
97 return true;
98}
99
100gfx::Rect PdfMetafileSkia::GetPageBounds(unsigned int page_number) const {
101 // TODO(vandebo) add a method to get the page size for a given page to
102 // SkPDFDocument.
103 NOTIMPLEMENTED();
104 return gfx::Rect();
105}
106
107unsigned int PdfMetafileSkia::GetPageCount() const {
108 // TODO(vandebo) add a method to get the number of pages to SkPDFDocument.
109 NOTIMPLEMENTED();
110 return 0;
111}
112
113gfx::NativeDrawingContext PdfMetafileSkia::context() const {
114 NOTREACHED();
115 return NULL;
116}
117
118#if defined(OS_WIN)
119bool PdfMetafileSkia::Playback(gfx::NativeDrawingContext hdc,
120 const RECT* rect) const {
121 NOTREACHED();
122 return false;
123}
124
125bool PdfMetafileSkia::SafePlayback(gfx::NativeDrawingContext hdc) const {
126 NOTREACHED();
127 return false;
128}
129
130HENHMETAFILE PdfMetafileSkia::emf() const {
131 NOTREACHED();
132 return NULL;
133}
134#endif // if defined(OS_WIN)
135
136#if defined(OS_CHROMEOS)
137bool PdfMetafileSkia::SaveToFD(const base::FileDescriptor& fd) const {
138 DCHECK_GT(data_->pdf_stream_.getOffset(), 0U);
139
140 if (fd.fd < 0) {
141 DLOG(ERROR) << "Invalid file descriptor!";
142 return false;
143 }
144
145 bool result = true;
146 if (file_util::WriteFileDescriptor(fd.fd, data_->pdf_stream_.getStream(),
147 GetDataSize()) !=
148 static_cast<int>(GetDataSize())) {
149 DLOG(ERROR) << "Failed to save file with fd " << fd.fd;
150 result = false;
151 }
152
153 if (fd.auto_close) {
154 if (HANDLE_EINTR(close(fd.fd)) < 0) {
155 DPLOG(WARNING) << "close";
156 result = false;
157 }
158 }
159 return result;
160}
161#endif
162
163PdfMetafileSkia::PdfMetafileSkia() : data_(new PdfMetafileSkiaData) {}
164
165} // namespace printing