| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/files/file.h" | 12 #include "base/files/file.h" |
| 13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
| 14 #include "base/time/time.h" | 14 #include "base/time/time.h" |
| 15 #include "cc/paint/paint_canvas.h" |
| 16 #include "cc/paint/paint_record.h" |
| 17 #include "cc/paint/paint_recorder.h" |
| 15 #include "printing/print_settings.h" | 18 #include "printing/print_settings.h" |
| 16 #include "third_party/skia/include/core/SkDocument.h" | 19 #include "third_party/skia/include/core/SkDocument.h" |
| 17 #include "third_party/skia/include/core/SkPictureRecorder.h" | |
| 18 #include "third_party/skia/include/core/SkStream.h" | 20 #include "third_party/skia/include/core/SkStream.h" |
| 19 // Note that headers in third_party/skia/src are fragile. This is | 21 // Note that headers in third_party/skia/src are fragile. This is |
| 20 // an experimental, fragile, and diagnostic-only document type. | 22 // an experimental, fragile, and diagnostic-only document type. |
| 21 #include "third_party/skia/src/utils/SkMultiPictureDocument.h" | 23 #include "third_party/skia/src/utils/SkMultiPictureDocument.h" |
| 22 #include "ui/gfx/geometry/safe_integer_conversions.h" | 24 #include "ui/gfx/geometry/safe_integer_conversions.h" |
| 23 #include "ui/gfx/skia_util.h" | 25 #include "ui/gfx/skia_util.h" |
| 24 | 26 |
| 25 #if defined(OS_MACOSX) | 27 #if defined(OS_MACOSX) |
| 26 #include "printing/pdf_metafile_cg_mac.h" | 28 #include "printing/pdf_metafile_cg_mac.h" |
| 27 #endif | 29 #endif |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 : SkString(agent.c_str(), agent.size()); | 72 : SkString(agent.c_str(), agent.size()); |
| 71 return SkDocument::MakePDF(wStream, SK_ScalarDefaultRasterDPI, metadata, | 73 return SkDocument::MakePDF(wStream, SK_ScalarDefaultRasterDPI, metadata, |
| 72 nullptr, false); | 74 nullptr, false); |
| 73 } | 75 } |
| 74 | 76 |
| 75 } // namespace | 77 } // namespace |
| 76 | 78 |
| 77 namespace printing { | 79 namespace printing { |
| 78 | 80 |
| 79 struct Page { | 81 struct Page { |
| 80 Page(SkSize s, sk_sp<SkPicture> c) : size_(s), content_(std::move(c)) {} | 82 Page(SkSize s, sk_sp<cc::PaintRecord> c) : size_(s), content_(std::move(c)) {} |
| 81 Page(Page&& that) : size_(that.size_), content_(std::move(that.content_)) {} | 83 Page(Page&& that) : size_(that.size_), content_(std::move(that.content_)) {} |
| 82 Page(const Page&) = default; | 84 Page(const Page&) = default; |
| 83 Page& operator=(const Page&) = default; | 85 Page& operator=(const Page&) = default; |
| 84 Page& operator=(Page&& that) { | 86 Page& operator=(Page&& that) { |
| 85 size_ = that.size_; | 87 size_ = that.size_; |
| 86 content_ = std::move(that.content_); | 88 content_ = std::move(that.content_); |
| 87 return *this; | 89 return *this; |
| 88 } | 90 } |
| 89 SkSize size_; | 91 SkSize size_; |
| 90 sk_sp<SkPicture> content_; | 92 sk_sp<cc::PaintRecord> content_; |
| 91 }; | 93 }; |
| 92 | 94 |
| 93 struct PdfMetafileSkiaData { | 95 struct PdfMetafileSkiaData { |
| 94 SkPictureRecorder recorder_; // Current recording | 96 cc::PaintRecorder recorder_; // Current recording |
| 95 | 97 |
| 96 std::vector<Page> pages_; | 98 std::vector<Page> pages_; |
| 97 std::unique_ptr<SkStreamAsset> pdf_data_; | 99 std::unique_ptr<SkStreamAsset> pdf_data_; |
| 98 | 100 |
| 99 // The scale factor is used because Blink occasionally calls | 101 // The scale factor is used because Blink occasionally calls |
| 100 // SkCanvas::getTotalMatrix() even though the total matrix is not as | 102 // PaintCanvas::getTotalMatrix() even though the total matrix is not as |
| 101 // meaningful for a vector canvas as for a raster canvas. | 103 // meaningful for a vector canvas as for a raster canvas. |
| 102 float scale_factor_; | 104 float scale_factor_; |
| 103 SkSize size_; | 105 SkSize size_; |
| 104 SkiaDocumentType type_; | 106 SkiaDocumentType type_; |
| 105 | 107 |
| 106 #if defined(OS_MACOSX) | 108 #if defined(OS_MACOSX) |
| 107 PdfMetafileCg pdf_cg_; | 109 PdfMetafileCg pdf_cg_; |
| 108 #endif | 110 #endif |
| 109 }; | 111 }; |
| 110 | 112 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 128 const gfx::Rect& content_area, | 130 const gfx::Rect& content_area, |
| 129 const float& scale_factor) { | 131 const float& scale_factor) { |
| 130 DCHECK_GT(page_size.width(), 0); | 132 DCHECK_GT(page_size.width(), 0); |
| 131 DCHECK_GT(page_size.height(), 0); | 133 DCHECK_GT(page_size.height(), 0); |
| 132 DCHECK_GT(scale_factor, 0.0f); | 134 DCHECK_GT(scale_factor, 0.0f); |
| 133 if (data_->recorder_.getRecordingCanvas()) | 135 if (data_->recorder_.getRecordingCanvas()) |
| 134 FinishPage(); | 136 FinishPage(); |
| 135 DCHECK(!data_->recorder_.getRecordingCanvas()); | 137 DCHECK(!data_->recorder_.getRecordingCanvas()); |
| 136 | 138 |
| 137 float inverse_scale = 1.0 / scale_factor; | 139 float inverse_scale = 1.0 / scale_factor; |
| 138 SkCanvas* canvas = data_->recorder_.beginRecording( | 140 cc::PaintCanvas* canvas = data_->recorder_.beginRecording( |
| 139 inverse_scale * page_size.width(), inverse_scale * page_size.height()); | 141 inverse_scale * page_size.width(), inverse_scale * page_size.height()); |
| 140 // Recording canvas is owned by the data_->recorder_. No ref() necessary. | 142 // Recording canvas is owned by the data_->recorder_. No ref() necessary. |
| 141 if (content_area != gfx::Rect(page_size)) { | 143 if (content_area != gfx::Rect(page_size)) { |
| 142 canvas->scale(inverse_scale, inverse_scale); | 144 canvas->scale(inverse_scale, inverse_scale); |
| 143 SkRect sk_content_area = gfx::RectToSkRect(content_area); | 145 SkRect sk_content_area = gfx::RectToSkRect(content_area); |
| 144 canvas->clipRect(sk_content_area); | 146 canvas->clipRect(sk_content_area); |
| 145 canvas->translate(sk_content_area.x(), sk_content_area.y()); | 147 canvas->translate(sk_content_area.x(), sk_content_area.y()); |
| 146 canvas->scale(scale_factor, scale_factor); | 148 canvas->scale(scale_factor, scale_factor); |
| 147 } | 149 } |
| 148 | 150 |
| 149 data_->size_ = gfx::SizeFToSkSize(gfx::SizeF(page_size)); | 151 data_->size_ = gfx::SizeFToSkSize(gfx::SizeF(page_size)); |
| 150 data_->scale_factor_ = scale_factor; | 152 data_->scale_factor_ = scale_factor; |
| 151 // We scale the recording canvas's size so that | 153 // We scale the recording canvas's size so that |
| 152 // canvas->getTotalMatrix() returns a value that ignores the scale | 154 // canvas->getTotalMatrix() returns a value that ignores the scale |
| 153 // factor. We store the scale factor and re-apply it later. | 155 // factor. We store the scale factor and re-apply it later. |
| 154 // http://crbug.com/469656 | 156 // http://crbug.com/469656 |
| 155 } | 157 } |
| 156 | 158 |
| 157 SkCanvas* PdfMetafileSkia::GetVectorCanvasForNewPage( | 159 cc::PaintCanvas* PdfMetafileSkia::GetVectorCanvasForNewPage( |
| 158 const gfx::Size& page_size, | 160 const gfx::Size& page_size, |
| 159 const gfx::Rect& content_area, | 161 const gfx::Rect& content_area, |
| 160 const float& scale_factor) { | 162 const float& scale_factor) { |
| 161 StartPage(page_size, content_area, scale_factor); | 163 StartPage(page_size, content_area, scale_factor); |
| 162 return data_->recorder_.getRecordingCanvas(); | 164 return data_->recorder_.getRecordingCanvas(); |
| 163 } | 165 } |
| 164 | 166 |
| 165 bool PdfMetafileSkia::FinishPage() { | 167 bool PdfMetafileSkia::FinishPage() { |
| 166 if (!data_->recorder_.getRecordingCanvas()) | 168 if (!data_->recorder_.getRecordingCanvas()) |
| 167 return false; | 169 return false; |
| 168 | 170 |
| 169 sk_sp<SkPicture> pic = data_->recorder_.finishRecordingAsPicture(); | 171 sk_sp<cc::PaintRecord> pic = data_->recorder_.finishRecordingAsPicture(); |
| 170 if (data_->scale_factor_ != 1.0f) { | 172 if (data_->scale_factor_ != 1.0f) { |
| 171 SkCanvas* canvas = data_->recorder_.beginRecording(data_->size_.width(), | 173 cc::PaintCanvas* canvas = data_->recorder_.beginRecording( |
| 172 data_->size_.height()); | 174 data_->size_.width(), data_->size_.height()); |
| 173 canvas->scale(data_->scale_factor_, data_->scale_factor_); | 175 canvas->scale(data_->scale_factor_, data_->scale_factor_); |
| 174 canvas->drawPicture(pic); | 176 canvas->drawPicture(pic); |
| 175 pic = data_->recorder_.finishRecordingAsPicture(); | 177 pic = data_->recorder_.finishRecordingAsPicture(); |
| 176 } | 178 } |
| 177 data_->pages_.emplace_back(data_->size_, std::move(pic)); | 179 data_->pages_.emplace_back(data_->size_, std::move(pic)); |
| 178 return true; | 180 return true; |
| 179 } | 181 } |
| 180 | 182 |
| 181 bool PdfMetafileSkia::FinishDocument() { | 183 bool PdfMetafileSkia::FinishDocument() { |
| 182 // If we've already set the data in InitFromData, leave it be. | 184 // If we've already set the data in InitFromData, leave it be. |
| 183 if (data_->pdf_data_) | 185 if (data_->pdf_data_) |
| 184 return false; | 186 return false; |
| 185 | 187 |
| 186 if (data_->recorder_.getRecordingCanvas()) | 188 if (data_->recorder_.getRecordingCanvas()) |
| 187 FinishPage(); | 189 FinishPage(); |
| 188 | 190 |
| 189 SkDynamicMemoryWStream stream; | 191 SkDynamicMemoryWStream stream; |
| 190 sk_sp<SkDocument> doc; | 192 sk_sp<SkDocument> doc; |
| 191 switch (data_->type_) { | 193 switch (data_->type_) { |
| 192 case PDF_SKIA_DOCUMENT_TYPE: | 194 case PDF_SKIA_DOCUMENT_TYPE: |
| 193 doc = MakePdfDocument(&stream); | 195 doc = MakePdfDocument(&stream); |
| 194 break; | 196 break; |
| 195 case MSKP_SKIA_DOCUMENT_TYPE: | 197 case MSKP_SKIA_DOCUMENT_TYPE: |
| 196 doc = SkMakeMultiPictureDocument(&stream); | 198 doc = SkMakeMultiPictureDocument(&stream); |
| 197 break; | 199 break; |
| 198 } | 200 } |
| 199 | 201 |
| 200 for (const Page& page : data_->pages_) { | 202 for (const Page& page : data_->pages_) { |
| 201 SkCanvas* canvas = doc->beginPage(page.size_.width(), page.size_.height()); | 203 cc::PaintCanvas* canvas( |
| 204 doc->beginPage(page.size_.width(), page.size_.height())); |
| 202 canvas->drawPicture(page.content_); | 205 canvas->drawPicture(page.content_); |
| 203 doc->endPage(); | 206 doc->endPage(); |
| 204 } | 207 } |
| 205 doc->close(); | 208 doc->close(); |
| 206 | 209 |
| 207 data_->pdf_data_.reset(stream.detachAsStream()); | 210 data_->pdf_data_.reset(stream.detachAsStream()); |
| 208 return true; | 211 return true; |
| 209 } | 212 } |
| 210 | 213 |
| 211 uint32_t PdfMetafileSkia::GetDataSize() const { | 214 uint32_t PdfMetafileSkia::GetDataSize() const { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 } | 305 } |
| 303 | 306 |
| 304 PdfMetafileSkia::PdfMetafileSkia(SkiaDocumentType type) | 307 PdfMetafileSkia::PdfMetafileSkia(SkiaDocumentType type) |
| 305 : data_(new PdfMetafileSkiaData) { | 308 : data_(new PdfMetafileSkiaData) { |
| 306 data_->type_ = type; | 309 data_->type_ = type; |
| 307 } | 310 } |
| 308 | 311 |
| 309 std::unique_ptr<PdfMetafileSkia> PdfMetafileSkia::GetMetafileForCurrentPage( | 312 std::unique_ptr<PdfMetafileSkia> PdfMetafileSkia::GetMetafileForCurrentPage( |
| 310 SkiaDocumentType type) { | 313 SkiaDocumentType type) { |
| 311 // If we only ever need the metafile for the last page, should we | 314 // If we only ever need the metafile for the last page, should we |
| 312 // only keep a handle on one SkPicture? | 315 // only keep a handle on one PaintRecord? |
| 313 std::unique_ptr<PdfMetafileSkia> metafile(new PdfMetafileSkia(type)); | 316 std::unique_ptr<PdfMetafileSkia> metafile(new PdfMetafileSkia(type)); |
| 314 | 317 |
| 315 if (data_->pages_.size() == 0) | 318 if (data_->pages_.size() == 0) |
| 316 return metafile; | 319 return metafile; |
| 317 | 320 |
| 318 if (data_->recorder_.getRecordingCanvas()) // page outstanding | 321 if (data_->recorder_.getRecordingCanvas()) // page outstanding |
| 319 return metafile; | 322 return metafile; |
| 320 | 323 |
| 321 metafile->data_->pages_.push_back(data_->pages_.back()); | 324 metafile->data_->pages_.push_back(data_->pages_.back()); |
| 322 | 325 |
| 323 if (!metafile->FinishDocument()) // Generate PDF. | 326 if (!metafile->FinishDocument()) // Generate PDF. |
| 324 metafile.reset(); | 327 metafile.reset(); |
| 325 | 328 |
| 326 return metafile; | 329 return metafile; |
| 327 } | 330 } |
| 328 | 331 |
| 329 } // namespace printing | 332 } // namespace printing |
| OLD | NEW |