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

Side by Side Diff: chrome/renderer/print_web_view_helper_linux.cc

Issue 7348010: Added Header and Footer support using Skia (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Added Headers and Footers support - New Snapshot Uploaded Created 9 years, 5 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 | Annotate | Revision Log
OLDNEW
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698