OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // 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 | 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 "chrome/renderer/print_web_view_helper.h" | 5 #include "chrome/renderer/print_web_view_helper.h" |
6 | 6 |
7 #include "base/file_descriptor_posix.h" | 7 #include "base/file_descriptor_posix.h" |
8 #include "base/i18n/time_formatting.h" | |
8 #include "base/logging.h" | 9 #include "base/logging.h" |
9 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
10 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
12 #include "base/string_number_conversions.h" | |
13 #include "base/time.h" | |
14 #include "base/utf_string_conversions.h" | |
11 #include "chrome/common/print_messages.h" | 15 #include "chrome/common/print_messages.h" |
12 #include "content/common/view_messages.h" | 16 #include "content/common/view_messages.h" |
13 #include "printing/metafile.h" | 17 #include "printing/metafile.h" |
14 #include "printing/metafile_impl.h" | 18 #include "printing/metafile_impl.h" |
15 #include "printing/metafile_skia_wrapper.h" | 19 #include "printing/metafile_skia_wrapper.h" |
16 #include "skia/ext/vector_canvas.h" | 20 #include "skia/ext/vector_canvas.h" |
21 #include "skia/ext/vector_platform_device_skia.h" | |
22 #include "third_party/skia/include/core/SkColor.h" | |
23 #include "third_party/skia/include/core/SkDraw.h" | |
17 #include "third_party/skia/include/core/SkRefCnt.h" | 24 #include "third_party/skia/include/core/SkRefCnt.h" |
25 #include "third_party/skia/include/core/SkTypeface.h" | |
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
27 #include "ui/base/text/text_elider.h" | |
19 #include "ui/gfx/point.h" | 28 #include "ui/gfx/point.h" |
20 | 29 |
21 #if !defined(OS_CHROMEOS) | 30 #if !defined(OS_CHROMEOS) |
22 #include "base/process_util.h" | 31 #include "base/process_util.h" |
23 #endif // !defined(OS_CHROMEOS) | 32 #endif // !defined(OS_CHROMEOS) |
24 | 33 |
34 using base::Time; | |
25 using WebKit::WebFrame; | 35 using WebKit::WebFrame; |
26 using WebKit::WebNode; | 36 using WebKit::WebNode; |
27 | 37 |
28 bool PrintWebViewHelper::CreatePreviewDocument( | 38 bool PrintWebViewHelper::CreatePreviewDocument( |
29 const PrintMsg_PrintPages_Params& params, WebKit::WebFrame* frame, | 39 const PrintMsg_PrintPages_Params& params, WebKit::WebFrame* frame, |
30 WebKit::WebNode* node) { | 40 WebKit::WebNode* node) { |
31 if (!PreviewPageRendered(-1)) | 41 if (!PreviewPageRendered(-1)) |
32 return false; | 42 return false; |
33 | 43 |
34 printing::PreviewMetafile metafile; | 44 printing::PreviewMetafile metafile; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
157 return false; | 167 return false; |
158 if (is_preview) { | 168 if (is_preview) { |
159 Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(), *page_count)); | 169 Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(), *page_count)); |
160 } else { | 170 } else { |
161 #if !defined(OS_CHROMEOS) | 171 #if !defined(OS_CHROMEOS) |
162 Send(new PrintHostMsg_DidGetPrintedPagesCount(routing_id(), | 172 Send(new PrintHostMsg_DidGetPrintedPagesCount(routing_id(), |
163 printParams.document_cookie, | 173 printParams.document_cookie, |
164 *page_count)); | 174 *page_count)); |
165 #endif | 175 #endif |
166 } | 176 } |
177 int total_pages = *page_count; | |
167 | 178 |
168 base::TimeTicks begin_time = base::TimeTicks::Now(); | 179 base::TimeTicks begin_time = base::TimeTicks::Now(); |
169 base::TimeTicks page_begin_time = begin_time; | 180 base::TimeTicks page_begin_time = begin_time; |
170 | 181 |
171 PrintMsg_PrintPage_Params page_params; | 182 PrintMsg_PrintPage_Params page_params; |
172 page_params.params = printParams; | 183 page_params.params = printParams; |
173 const gfx::Size& canvas_size = prep_frame_view.GetPrintCanvasSize(); | 184 const gfx::Size& canvas_size = prep_frame_view.GetPrintCanvasSize(); |
174 if (params.pages.empty()) { | 185 if (params.pages.empty()) { |
175 for (int i = 0; i < *page_count; ++i) { | 186 for (int i = 0; i < *page_count; ++i) { |
176 page_params.page_number = i; | 187 page_params.page_number = i; |
177 PrintPageInternal(page_params, canvas_size, frame, metafile); | 188 PrintPageInternal(page_params, canvas_size, frame, metafile, is_preview, |
189 total_pages); | |
178 if (is_preview) { | 190 if (is_preview) { |
179 page_begin_time = ReportPreviewPageRenderTime(page_begin_time); | 191 page_begin_time = ReportPreviewPageRenderTime(page_begin_time); |
180 if (!PreviewPageRendered(i)) | 192 if (!PreviewPageRendered(i)) |
181 return false; | 193 return false; |
182 } | 194 } |
183 } | 195 } |
184 } else { | 196 } else { |
185 for (size_t i = 0; i < params.pages.size(); ++i) { | 197 for (size_t i = 0; i < params.pages.size(); ++i) { |
186 page_params.page_number = params.pages[i]; | 198 page_params.page_number = params.pages[i]; |
187 PrintPageInternal(page_params, canvas_size, frame, metafile); | 199 PrintPageInternal(page_params, canvas_size, frame, metafile, is_preview, |
200 total_pages); | |
188 if (is_preview) { | 201 if (is_preview) { |
189 page_begin_time = ReportPreviewPageRenderTime(page_begin_time); | 202 page_begin_time = ReportPreviewPageRenderTime(page_begin_time); |
190 if (!PreviewPageRendered(params.pages[i])) | 203 if (!PreviewPageRendered(params.pages[i])) |
191 return false; | 204 return false; |
192 } | 205 } |
193 } | 206 } |
194 } | 207 } |
195 | 208 |
196 base::TimeDelta render_time = base::TimeTicks::Now() - begin_time; | 209 base::TimeDelta render_time = base::TimeTicks::Now() - begin_time; |
197 | 210 |
198 prep_frame_view.FinishPrinting(); | 211 prep_frame_view.FinishPrinting(); |
199 metafile->FinishDocument(); | 212 metafile->FinishDocument(); |
200 | 213 |
201 if (is_preview) { | 214 if (is_preview) { |
202 ReportTotalPreviewGenerationTime(params.pages.size(), *page_count, | 215 ReportTotalPreviewGenerationTime(params.pages.size(), *page_count, |
203 render_time, | 216 render_time, |
204 base::TimeTicks::Now() - begin_time); | 217 base::TimeTicks::Now() - begin_time); |
205 } | 218 } |
206 return true; | 219 return true; |
207 } | 220 } |
208 | 221 |
222 | |
223 size_t GetString16ByteLength(string16 text) { | |
224 return text.length()*sizeof(char16); | |
225 } | |
226 | |
227 SkScalar PrintWebViewHelper::GetHorizontalCoordinate( | |
228 string16 text, | |
229 SkPaint paint, | |
230 HorizontalHeaderFooterPosition pos, | |
231 SkScalar margin_left_in_points, | |
232 SkScalar margin_right_in_points, | |
233 SkScalar content_width_in_points) { | |
234 SkScalar text_width_in_points = paint.measureText(text.c_str(), | |
235 GetString16ByteLength(text)); | |
236 | |
237 switch (pos) { | |
238 case LEFT: | |
239 return margin_left_in_points*(-1) + header_footer_interstice; | |
240 case RIGHT: | |
241 return ((content_width_in_points+margin_right_in_points) - | |
242 (header_footer_interstice + text_width_in_points)); | |
243 case CENTER: | |
244 SkScalar available_width = (margin_left_in_points + | |
245 margin_right_in_points + | |
246 content_width_in_points - | |
247 4*header_footer_interstice)/3; | |
248 return (available_width - margin_left_in_points + | |
249 (available_width - text_width_in_points)/2); | |
250 } | |
251 NOTREACHED(); | |
252 return 0; | |
253 } | |
254 | |
255 SkScalar PrintWebViewHelper::GetVerticalCoordinate( | |
256 SkPaint paint, | |
257 VerticalHeaderFooterPosition pos, | |
258 SkScalar margin_top_in_points, | |
259 SkScalar margin_bottom_in_points, | |
260 SkScalar content_height_in_points) { | |
261 if (pos == TOP) { | |
262 return margin_top_in_points*(-0.5); | |
263 } else if (pos == BOTTOM) { | |
264 return margin_top_in_points+content_height_in_points; | |
265 } else { | |
266 NOTREACHED(); | |
267 return 0; | |
268 } | |
269 } | |
270 | |
271 void PrintWebViewHelper::PrintHeaderFooterText( | |
272 string16 text, | |
273 SkPaint paint, | |
274 const SkRefPtr<skia::VectorCanvas>& canvas, | |
275 SkScalar margin_left_in_points, | |
276 SkScalar margin_right_in_points, | |
277 SkScalar content_width_in_points, | |
278 SkScalar margin_top_in_points, | |
279 SkScalar margin_bottom_in_points, | |
280 SkScalar content_height_in_points, | |
281 HorizontalHeaderFooterPosition hor_pos, | |
282 VerticalHeaderFooterPosition ver_pos) { | |
283 SkScalar x_cord = GetHorizontalCoordinate(text, paint, hor_pos, | |
284 margin_left_in_points, | |
285 margin_right_in_points, | |
286 content_width_in_points); | |
287 SkScalar y_cord = GetVerticalCoordinate(paint, ver_pos, margin_top_in_points, | |
288 margin_bottom_in_points, | |
289 content_height_in_points); | |
290 size_t byte_length = GetString16ByteLength(text); | |
291 | |
292 canvas->drawText(text.c_str(), byte_length, x_cord, y_cord, paint); | |
293 } | |
294 | |
209 void PrintWebViewHelper::PrintPageInternal( | 295 void PrintWebViewHelper::PrintPageInternal( |
210 const PrintMsg_PrintPage_Params& params, | 296 const PrintMsg_PrintPage_Params& params, |
211 const gfx::Size& canvas_size, | 297 const gfx::Size& canvas_size, |
212 WebFrame* frame, | 298 WebFrame* frame, |
213 printing::Metafile* metafile) { | 299 printing::Metafile* metafile, |
300 bool is_preview, | |
301 int total_pages) { | |
302 // TODO(aayushkumar): Make these variables private variables of the class. | |
214 double content_width_in_points; | 303 double content_width_in_points; |
215 double content_height_in_points; | 304 double content_height_in_points; |
216 double margin_top_in_points; | 305 double margin_top_in_points; |
217 double margin_right_in_points; | 306 double margin_right_in_points; |
218 double margin_bottom_in_points; | 307 double margin_bottom_in_points; |
219 double margin_left_in_points; | 308 double margin_left_in_points; |
220 GetPageSizeAndMarginsInPoints(frame, | 309 GetPageSizeAndMarginsInPoints(frame, |
221 params.page_number, | 310 params.page_number, |
222 params.params, | 311 params.params, |
223 &content_width_in_points, | 312 &content_width_in_points, |
(...skipping 14 matching lines...) Expand all Loading... | |
238 SkDevice* device = metafile->StartPageForVectorCanvas( | 327 SkDevice* device = metafile->StartPageForVectorCanvas( |
239 page_size, content_area, 1.0f); | 328 page_size, content_area, 1.0f); |
240 if (!device) | 329 if (!device) |
241 return; | 330 return; |
242 | 331 |
243 // The printPage method take a reference to the canvas we pass down, so it | 332 // The printPage method take a reference to the canvas we pass down, so it |
244 // can't be a stack object. | 333 // can't be a stack object. |
245 SkRefPtr<skia::VectorCanvas> canvas = new skia::VectorCanvas(device); | 334 SkRefPtr<skia::VectorCanvas> canvas = new skia::VectorCanvas(device); |
246 canvas->unref(); // SkRefPtr and new both took a reference. | 335 canvas->unref(); // SkRefPtr and new both took a reference. |
247 printing::MetafileSkiaWrapper::SetMetafileOnCanvas(canvas.get(), metafile); | 336 printing::MetafileSkiaWrapper::SetMetafileOnCanvas(canvas.get(), metafile); |
337 | |
338 // TODO(aayushkumar): Have a seperate function for printing Headers and Footer | |
kmadhusu
2011/07/13 18:47:53
Implement this TODO.
Aayush Kumar
2011/07/13 21:52:16
Done.
| |
339 // that will hopefully be in common for all platforms. | |
340 if (is_preview && params.params.header_footer) { | |
341 // Set the drawing area to draw in the margins. | |
342 ((skia::VectorPlatformDeviceSkia* )device)-> | |
343 setDrawingArea(SkPDFDevice::kMargin_DrawingArea); | |
344 | |
345 // Setting up styles for the headers and footers text. | |
346 SkPaint paint; | |
347 paint.setColor(SK_ColorBLACK); | |
348 paint.setTextSize(SkIntToScalar(8)); | |
349 paint.setTypeface(SkTypeface::CreateFromName(NULL, SkTypeface::kNormal)); | |
350 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); | |
351 | |
352 // Printing the Date | |
353 Time now = Time::Now(); | |
354 string16 date = base::TimeFormatShortDateNumeric(now); | |
355 PrintHeaderFooterText(date, paint, canvas, margin_left_in_points, | |
356 margin_right_in_points, content_width_in_points, | |
357 margin_top_in_points, margin_bottom_in_points, | |
358 content_height_in_points, LEFT, TOP); | |
359 | |
360 // Printing the title | |
361 string16 title; | |
362 if (!header_footer_info_->GetString("title", &title)) | |
363 NOTREACHED(); | |
364 | |
365 SkScalar maxTitleSize = (margin_left_in_points + | |
366 content_width_in_points + | |
367 margin_right_in_points)/3; | |
368 title = ui::ElideText(title, paint, maxTitleSize, false); | |
369 PrintHeaderFooterText(title, paint, canvas, margin_left_in_points, | |
370 margin_right_in_points, content_width_in_points, | |
371 margin_top_in_points, margin_bottom_in_points, | |
372 content_height_in_points, CENTER, TOP); | |
373 | |
374 // Printing the URL | |
375 std::string url; | |
376 if (!header_footer_info_->GetString("url", &url)) | |
377 NOTREACHED(); | |
378 GURL gurl(url); | |
379 string16 url_elided = ui::ElideUrl(gurl, paint, maxTitleSize, | |
380 std::string()); | |
381 PrintHeaderFooterText(url_elided, paint, canvas, margin_left_in_points, | |
382 margin_right_in_points, content_width_in_points, | |
383 margin_top_in_points, margin_bottom_in_points, | |
384 content_height_in_points, LEFT, BOTTOM); | |
385 | |
386 // Printing the page numbers at the bottom right corner of page. | |
387 string16 page_on_page_total = base::IntToString16(params.page_number+1) + | |
388 UTF8ToUTF16("/") + | |
kmadhusu
2011/07/13 18:47:53
nit: Fix indentation.
Aayush Kumar
2011/07/13 21:52:16
Done.
| |
389 base::IntToString16(total_pages); | |
390 PrintHeaderFooterText(page_on_page_total, paint, canvas, | |
391 margin_left_in_points, margin_right_in_points, | |
392 content_width_in_points, margin_top_in_points, | |
393 margin_bottom_in_points, content_height_in_points, | |
394 RIGHT, BOTTOM); | |
395 | |
396 // Restore the drawing area to draw in the content area. | |
397 ((skia::VectorPlatformDeviceSkia* )device)-> | |
398 setDrawingArea(SkPDFDevice::kContent_DrawingArea); | |
399 } | |
400 | |
248 frame->printPage(params.page_number, canvas.get()); | 401 frame->printPage(params.page_number, canvas.get()); |
249 | 402 |
250 // TODO(myhuang): We should render the header and the footer. | 403 // TODO(myhuang): We should render the header and the footer. |
251 | 404 |
252 // Done printing. Close the device context to retrieve the compiled metafile. | 405 // Done printing. Close the device context to retrieve the compiled metafile. |
253 if (!metafile->FinishPage()) | 406 if (!metafile->FinishPage()) |
254 NOTREACHED() << "metafile failed"; | 407 NOTREACHED() << "metafile failed"; |
255 } | 408 } |
OLD | NEW |