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 |