| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_metafile_skia.h" | 5 #include "printing/pdf_metafile_skia.h" |
| 6 | 6 |
| 7 #include "base/files/file.h" | 7 #include "base/files/file.h" |
| 8 #include "base/time/time.h" | 8 #include "base/time/time.h" |
| 9 #include "printing/print_settings.h" | 9 #include "printing/print_settings.h" |
| 10 #include "third_party/skia/include/core/SkDocument.h" | 10 #include "third_party/skia/include/core/SkDocument.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 metadata.fCreator = agent.empty() ? SkString("Chromium") | 60 metadata.fCreator = agent.empty() ? SkString("Chromium") |
| 61 : SkString(agent.c_str(), agent.size()); | 61 : SkString(agent.c_str(), agent.size()); |
| 62 return SkDocument::MakePDF(wStream, SK_ScalarDefaultRasterDPI, metadata, | 62 return SkDocument::MakePDF(wStream, SK_ScalarDefaultRasterDPI, metadata, |
| 63 nullptr, false); | 63 nullptr, false); |
| 64 } | 64 } |
| 65 | 65 |
| 66 } // namespace | 66 } // namespace |
| 67 | 67 |
| 68 namespace printing { | 68 namespace printing { |
| 69 | 69 |
| 70 struct Page { |
| 71 Page(SkSize s, sk_sp<SkPicture> c) : size_(s), content_(std::move(c)) {} |
| 72 Page(Page&& that) : size_(that.size_), content_(std::move(that.content_)) {} |
| 73 Page(const Page&) = default; |
| 74 Page& operator=(const Page&) = default; |
| 75 Page& operator=(Page&& that) { |
| 76 size_ = that.size_; |
| 77 content_ = std::move(that.content_); |
| 78 return *this; |
| 79 } |
| 80 SkSize size_; |
| 81 sk_sp<SkPicture> content_; |
| 82 }; |
| 83 |
| 70 struct PdfMetafileSkiaData { | 84 struct PdfMetafileSkiaData { |
| 71 SkPictureRecorder recorder_; // Current recording | 85 SkPictureRecorder recorder_; // Current recording |
| 72 | 86 |
| 73 std::vector<sk_sp<SkPicture>> pages_; | 87 std::vector<Page> pages_; |
| 74 std::unique_ptr<SkStreamAsset> pdf_data_; | 88 std::unique_ptr<SkStreamAsset> pdf_data_; |
| 75 | 89 |
| 76 // The scale factor is used because Blink occasionally calls | 90 // The scale factor is used because Blink occasionally calls |
| 77 // SkCanvas::getTotalMatrix() even though the total matrix is not as | 91 // SkCanvas::getTotalMatrix() even though the total matrix is not as |
| 78 // meaningful for a vector canvas as for a raster canvas. | 92 // meaningful for a vector canvas as for a raster canvas. |
| 79 float scale_factor_; | 93 float scale_factor_; |
| 94 SkSize size_; |
| 80 | 95 |
| 81 #if defined(OS_MACOSX) | 96 #if defined(OS_MACOSX) |
| 82 PdfMetafileCg pdf_cg_; | 97 PdfMetafileCg pdf_cg_; |
| 83 #endif | 98 #endif |
| 84 }; | 99 }; |
| 85 | 100 |
| 86 PdfMetafileSkia::~PdfMetafileSkia() {} | 101 PdfMetafileSkia::~PdfMetafileSkia() {} |
| 87 | 102 |
| 88 bool PdfMetafileSkia::Init() { | 103 bool PdfMetafileSkia::Init() { |
| 89 return true; | 104 return true; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 112 SkCanvas* canvas = data_->recorder_.beginRecording( | 127 SkCanvas* canvas = data_->recorder_.beginRecording( |
| 113 inverse_scale * page_size.width(), inverse_scale * page_size.height()); | 128 inverse_scale * page_size.width(), inverse_scale * page_size.height()); |
| 114 if (content_area != gfx::Rect(page_size)) { | 129 if (content_area != gfx::Rect(page_size)) { |
| 115 canvas->scale(inverse_scale, inverse_scale); | 130 canvas->scale(inverse_scale, inverse_scale); |
| 116 SkRect sk_content_area = gfx::RectToSkRect(content_area); | 131 SkRect sk_content_area = gfx::RectToSkRect(content_area); |
| 117 canvas->clipRect(sk_content_area); | 132 canvas->clipRect(sk_content_area); |
| 118 canvas->translate(sk_content_area.x(), sk_content_area.y()); | 133 canvas->translate(sk_content_area.x(), sk_content_area.y()); |
| 119 canvas->scale(scale_factor, scale_factor); | 134 canvas->scale(scale_factor, scale_factor); |
| 120 } | 135 } |
| 121 | 136 |
| 137 data_->size_ = gfx::SizeFToSkSize(gfx::SizeF(page_size)); |
| 122 data_->scale_factor_ = scale_factor; | 138 data_->scale_factor_ = scale_factor; |
| 123 // We scale the recording canvas's size so that | 139 // We scale the recording canvas's size so that |
| 124 // canvas->getTotalMatrix() returns a value that ignores the scale | 140 // canvas->getTotalMatrix() returns a value that ignores the scale |
| 125 // factor. We store the scale factor and re-apply it later. | 141 // factor. We store the scale factor and re-apply it later. |
| 126 // http://crbug.com/469656 | 142 // http://crbug.com/469656 |
| 127 // Recording canvas is owned by the data_->recorder_. No ref() necessary. | 143 // Recording canvas is owned by the data_->recorder_. No ref() necessary. |
| 128 } | 144 } |
| 129 | 145 |
| 130 SkCanvas* PdfMetafileSkia::GetVectorCanvasForNewPage( | 146 SkCanvas* PdfMetafileSkia::GetVectorCanvasForNewPage( |
| 131 const gfx::Size& page_size, | 147 const gfx::Size& page_size, |
| 132 const gfx::Rect& content_area, | 148 const gfx::Rect& content_area, |
| 133 const float& scale_factor) { | 149 const float& scale_factor) { |
| 134 StartPage(page_size, content_area, scale_factor); | 150 StartPage(page_size, content_area, scale_factor); |
| 135 return data_->recorder_.getRecordingCanvas(); | 151 return data_->recorder_.getRecordingCanvas(); |
| 136 } | 152 } |
| 137 | 153 |
| 138 bool PdfMetafileSkia::FinishPage() { | 154 bool PdfMetafileSkia::FinishPage() { |
| 139 if (!data_->recorder_.getRecordingCanvas()) | 155 if (!data_->recorder_.getRecordingCanvas()) |
| 140 return false; | 156 return false; |
| 141 | 157 |
| 142 sk_sp<SkPicture> pic = data_->recorder_.finishRecordingAsPicture(); | 158 sk_sp<SkPicture> pic = data_->recorder_.finishRecordingAsPicture(); |
| 143 if (data_->scale_factor_ != 1.0f) { | 159 if (data_->scale_factor_ != 1.0f) { |
| 144 SkRect rect = pic->cullRect(); | |
| 145 DCHECK_EQ(rect.x(), 0); | |
| 146 DCHECK_EQ(rect.y(), 0); | |
| 147 DCHECK_GT(rect.right(), 0); | |
| 148 DCHECK_GT(rect.bottom(), 0); | |
| 149 SkCanvas* canvas = | 160 SkCanvas* canvas = |
| 150 data_->recorder_.beginRecording(data_->scale_factor_ * rect.right(), | 161 data_->recorder_.beginRecording(data_->size_.width(), |
| 151 data_->scale_factor_ * rect.bottom()); | 162 data_->size_.height()); |
| 152 canvas->scale(data_->scale_factor_, data_->scale_factor_); | 163 canvas->scale(data_->scale_factor_, data_->scale_factor_); |
| 153 canvas->drawPicture(pic); | 164 canvas->drawPicture(pic); |
| 154 pic = data_->recorder_.finishRecordingAsPicture(); | 165 pic = data_->recorder_.finishRecordingAsPicture(); |
| 155 } | 166 } |
| 156 data_->pages_.push_back(std::move(pic)); | 167 data_->pages_.emplace_back(data_->size_, std::move(pic)); |
| 157 return true; | 168 return true; |
| 158 } | 169 } |
| 159 | 170 |
| 160 bool PdfMetafileSkia::FinishDocument() { | 171 bool PdfMetafileSkia::FinishDocument() { |
| 161 // If we've already set the data in InitFromData, leave it be. | 172 // If we've already set the data in InitFromData, leave it be. |
| 162 if (data_->pdf_data_) | 173 if (data_->pdf_data_) |
| 163 return false; | 174 return false; |
| 164 | 175 |
| 165 if (data_->recorder_.getRecordingCanvas()) | 176 if (data_->recorder_.getRecordingCanvas()) |
| 166 FinishPage(); | 177 FinishPage(); |
| 167 | 178 |
| 168 SkDynamicMemoryWStream stream; | 179 SkDynamicMemoryWStream stream; |
| 169 // TODO(halcanary): support more document types (XPS, a sequence of display | 180 // TODO(halcanary): support more document types (XPS, a sequence of display |
| 170 // lists). | 181 // lists). |
| 171 sk_sp<SkDocument> doc = MakePdfDocument(&stream); | 182 sk_sp<SkDocument> doc = MakePdfDocument(&stream); |
| 172 | 183 |
| 173 for (const sk_sp<SkPicture>& page : data_->pages_) { | 184 for (const Page& page : data_->pages_) { |
| 174 SkRect rect = page->cullRect(); | 185 SkCanvas* canvas = doc->beginPage(page.size_.width(), page.size_.height()); |
| 175 DCHECK_EQ(rect.x(), 0); | 186 canvas->drawPicture(page.content_); |
| 176 DCHECK_EQ(rect.y(), 0); | |
| 177 DCHECK_GT(rect.right(), 0); | |
| 178 DCHECK_GT(rect.bottom(), 0); | |
| 179 SkCanvas* canvas = doc->beginPage(rect.right(), rect.bottom()); | |
| 180 canvas->drawPicture(page); | |
| 181 doc->endPage(); | 187 doc->endPage(); |
| 182 } | 188 } |
| 183 if (!doc->close()) | 189 if (!doc->close()) |
| 184 return false; | 190 return false; |
| 185 | 191 |
| 186 data_->pdf_data_.reset(stream.detachAsStream()); | 192 data_->pdf_data_.reset(stream.detachAsStream()); |
| 187 return true; | 193 return true; |
| 188 } | 194 } |
| 189 | 195 |
| 190 uint32_t PdfMetafileSkia::GetDataSize() const { | 196 uint32_t PdfMetafileSkia::GetDataSize() const { |
| 191 if (!data_->pdf_data_) | 197 if (!data_->pdf_data_) |
| 192 return 0; | 198 return 0; |
| 193 return base::checked_cast<uint32_t>(data_->pdf_data_->getLength()); | 199 return base::checked_cast<uint32_t>(data_->pdf_data_->getLength()); |
| 194 } | 200 } |
| 195 | 201 |
| 196 bool PdfMetafileSkia::GetData(void* dst_buffer, | 202 bool PdfMetafileSkia::GetData(void* dst_buffer, |
| 197 uint32_t dst_buffer_size) const { | 203 uint32_t dst_buffer_size) const { |
| 198 if (!data_->pdf_data_) | 204 if (!data_->pdf_data_) |
| 199 return false; | 205 return false; |
| 200 return WriteAssetToBuffer(data_->pdf_data_.get(), dst_buffer, | 206 return WriteAssetToBuffer(data_->pdf_data_.get(), dst_buffer, |
| 201 base::checked_cast<size_t>(dst_buffer_size)); | 207 base::checked_cast<size_t>(dst_buffer_size)); |
| 202 } | 208 } |
| 203 | 209 |
| 204 gfx::Rect PdfMetafileSkia::GetPageBounds(unsigned int page_number) const { | 210 gfx::Rect PdfMetafileSkia::GetPageBounds(unsigned int page_number) const { |
| 205 if (page_number < data_->pages_.size()) { | 211 if (page_number < data_->pages_.size()) { |
| 206 const sk_sp<SkPicture>& page = data_->pages_[page_number]; | 212 SkSize size = data_->pages_[page_number].size_; |
| 207 SkRect rect = page->cullRect(); | 213 return gfx::Rect(gfx::ToRoundedInt(size.width()), |
| 208 DCHECK_EQ(rect.x(), 0); | 214 gfx::ToRoundedInt(size.height())); |
| 209 DCHECK_EQ(rect.y(), 0); | |
| 210 DCHECK_GT(rect.right(), 0); | |
| 211 DCHECK_GT(rect.bottom(), 0); | |
| 212 return gfx::Rect(gfx::ToRoundedInt(rect.right()), | |
| 213 gfx::ToRoundedInt(rect.bottom())); | |
| 214 } | 215 } |
| 215 return gfx::Rect(); | 216 return gfx::Rect(); |
| 216 } | 217 } |
| 217 | 218 |
| 218 unsigned int PdfMetafileSkia::GetPageCount() const { | 219 unsigned int PdfMetafileSkia::GetPageCount() const { |
| 219 return base::checked_cast<unsigned int>(data_->pages_.size()); | 220 return base::checked_cast<unsigned int>(data_->pages_.size()); |
| 220 } | 221 } |
| 221 | 222 |
| 222 gfx::NativeDrawingContext PdfMetafileSkia::context() const { | 223 gfx::NativeDrawingContext PdfMetafileSkia::context() const { |
| 223 NOTREACHED(); | 224 NOTREACHED(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 | 303 |
| 303 metafile->data_->pages_.push_back(data_->pages_.back()); | 304 metafile->data_->pages_.push_back(data_->pages_.back()); |
| 304 | 305 |
| 305 if (!metafile->FinishDocument()) // Generate PDF. | 306 if (!metafile->FinishDocument()) // Generate PDF. |
| 306 metafile.reset(); | 307 metafile.reset(); |
| 307 | 308 |
| 308 return metafile; | 309 return metafile; |
| 309 } | 310 } |
| 310 | 311 |
| 311 } // namespace printing | 312 } // namespace printing |
| OLD | NEW |