Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: printing/pdf_metafile_skia.cc

Issue 2062903002: PdfMetafileSkia: don't rely on SkPicture::cullRect (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698