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

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

Issue 7348010: Added Header and Footer support using Skia (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Removed use of webkit_scale_factor in print_web_view_helper_mac Created 9 years, 4 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 #if defined(USE_SKIA)
8 #include <algorithm>
9 #include <cmath>
10 #endif
7 #include <string> 11 #include <string>
8 12
9 #include "base/command_line.h" 13 #include "base/command_line.h"
10 #include "base/logging.h" 14 #include "base/logging.h"
11 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
12 #include "base/process_util.h" 16 #include "base/process_util.h"
13 #include "base/utf_string_conversions.h" 17 #include "base/utf_string_conversions.h"
14 #include "chrome/common/chrome_switches.h" 18 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/print_messages.h" 19 #include "chrome/common/print_messages.h"
16 #include "chrome/common/render_messages.h" 20 #include "chrome/common/render_messages.h"
(...skipping 12 matching lines...) Expand all
29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" 33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" 34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h"
31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h" 35 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h"
32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 36 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
33 #include "ui/base/l10n/l10n_util.h" 37 #include "ui/base/l10n/l10n_util.h"
34 38
35 #if defined(OS_POSIX) 39 #if defined(OS_POSIX)
36 #include "content/common/view_messages.h" 40 #include "content/common/view_messages.h"
37 #endif 41 #endif
38 42
43 #if defined(USE_SKIA)
44 #include "base/i18n/time_formatting.h"
45 #include "base/string_number_conversions.h"
46 #include "base/time.h"
47 #include "skia/ext/vector_canvas.h"
48 #include "skia/ext/vector_platform_device_skia.h"
49 #include "third_party/skia/include/core/SkTypeface.h"
50 #include "ui/base/text/text_elider.h"
51 #endif // USE_SKIA
52
53 using base::Time;
39 using printing::ConvertPixelsToPoint; 54 using printing::ConvertPixelsToPoint;
40 using printing::ConvertPixelsToPointDouble; 55 using printing::ConvertPixelsToPointDouble;
56 using printing::ConvertPointsToPixelDouble;
41 using printing::ConvertUnit; 57 using printing::ConvertUnit;
42 using printing::ConvertUnitDouble; 58 using printing::ConvertUnitDouble;
43 using WebKit::WebConsoleMessage; 59 using WebKit::WebConsoleMessage;
44 using WebKit::WebDocument; 60 using WebKit::WebDocument;
45 using WebKit::WebElement; 61 using WebKit::WebElement;
46 using WebKit::WebFrame; 62 using WebKit::WebFrame;
47 using WebKit::WebNode; 63 using WebKit::WebNode;
48 using WebKit::WebSize; 64 using WebKit::WebSize;
49 using WebKit::WebString; 65 using WebKit::WebString;
50 using WebKit::WebURLRequest; 66 using WebKit::WebURLRequest;
(...skipping 29 matching lines...) Expand all
80 oldParams.params.min_shrink == newParams.params.min_shrink && 96 oldParams.params.min_shrink == newParams.params.min_shrink &&
81 oldParams.params.dpi == newParams.params.dpi && 97 oldParams.params.dpi == newParams.params.dpi &&
82 oldParams.params.printable_size == newParams.params.printable_size && 98 oldParams.params.printable_size == newParams.params.printable_size &&
83 oldParams.params.selection_only == newParams.params.selection_only && 99 oldParams.params.selection_only == newParams.params.selection_only &&
84 oldParams.params.page_size == newParams.params.page_size && 100 oldParams.params.page_size == newParams.params.page_size &&
85 oldParams.params.margin_top == newParams.params.margin_top && 101 oldParams.params.margin_top == newParams.params.margin_top &&
86 oldParams.params.margin_left == newParams.params.margin_left && 102 oldParams.params.margin_left == newParams.params.margin_left &&
87 oldParams.params.supports_alpha_blend == 103 oldParams.params.supports_alpha_blend ==
88 newParams.params.supports_alpha_blend && 104 newParams.params.supports_alpha_blend &&
89 oldParams.pages.size() == newParams.pages.size() && 105 oldParams.pages.size() == newParams.pages.size() &&
106 oldParams.params.display_header_footer ==
107 newParams.params.display_header_footer &&
90 std::equal(oldParams.pages.begin(), oldParams.pages.end(), 108 std::equal(oldParams.pages.begin(), oldParams.pages.end(),
91 newParams.pages.begin()); 109 newParams.pages.begin());
92 } 110 }
93 111
94 void CalculatePrintCanvasSize(const PrintMsg_Print_Params& print_params, 112 void CalculatePrintCanvasSize(const PrintMsg_Print_Params& print_params,
95 gfx::Size* result) { 113 gfx::Size* result) {
96 int dpi = GetDPI(&print_params); 114 int dpi = GetDPI(&print_params);
97 result->set_width(ConvertUnit(print_params.printable_size.width(), dpi, 115 result->set_width(ConvertUnit(print_params.printable_size.width(), dpi,
98 print_params.desired_dpi)); 116 print_params.desired_dpi));
99 117
100 result->set_height(ConvertUnit(print_params.printable_size.height(), dpi, 118 result->set_height(ConvertUnit(print_params.printable_size.height(), dpi,
101 print_params.desired_dpi)); 119 print_params.desired_dpi));
102 } 120 }
103 121
122 #if defined(USE_SKIA)
123 // Splits the horizontal width equally into segments with an interstice
124 // between each segment. Returns the width of a segment.
125 SkScalar GetSegmentWidth(const PageSizeMargins& page_layout) {
126 SkScalar page_width = page_layout.margin_left +
127 page_layout.content_width +
128 page_layout.margin_right;
129 // Interstice is left at both ends of the page as well as between
130 // each region, so 1 is added.
131 SkScalar total_interstice_width =
132 (printing::kSettingHeaderFooterHorizontalRegions + 1) *
133 printing::kSettingHeaderFooterInterstice;
134 return (page_width - total_interstice_width) /
135 printing::kSettingHeaderFooterHorizontalRegions;
136 }
137
138 // Given a text, the positions, and the paint object, this method gets the
139 // coordinates and prints the text at those coordinates on the canvas.
140 void PrintHeaderFooterText(
Lei Zhang 2011/08/05 18:58:21 nit: PrintHeaderFooterText() and PrintHeaders() ha
Aayush Kumar 2011/08/08 03:19:22 Reordered function params. As discussed in person,
141 string16 text,
142 SkPaint paint,
143 skia::VectorCanvas* canvas,
144 printing::HorizontalHeaderFooterPosition horizontal_position,
145 printing::VerticalHeaderFooterPosition vertical_position,
146 float webkit_scale_factor,
147 const PageSizeMargins& page_layout,
148 SkScalar max_text_width,
149 const gfx::Font& font,
150 SkScalar offset_to_baseline) {
151 text = ui::ElideText(text, font, ConvertPointsToPixelDouble(max_text_width),
152 false);
153
154 size_t text_byte_length = text.length() * sizeof(char16);
155 // Get the (x, y) coordinate from where printing of the current text should
156 // start depending on the horizontal alignment (LEFT, RIGHT, CENTER) and
157 // vertical alignment (TOP, BOTTOM).
158 SkScalar text_width_in_points = paint.measureText(text.c_str(),
159 text_byte_length);
160 SkScalar x = 0;
161 switch (horizontal_position) {
162 case printing::LEFT:
163 x = printing::kSettingHeaderFooterInterstice - page_layout.margin_left;
164 break;
165 case printing::RIGHT:
166 x = page_layout.content_width + page_layout.margin_right -
167 printing::kSettingHeaderFooterInterstice - text_width_in_points;
168 break;
169 case printing::CENTER: {
170 SkScalar available_width = GetSegmentWidth(page_layout);
171 x = available_width - page_layout.margin_left +
172 (available_width - text_width_in_points) / 2;
173 break;
174 }
175 default:
176 NOTREACHED();
177 }
178
179 SkScalar y = 0;
180 switch (vertical_position) {
181 case printing::TOP:
182 y = printing::kSettingHeaderFooterInterstice -
183 page_layout.margin_top - offset_to_baseline;
184 break;
185 case printing::BOTTOM:
186 y = page_layout.margin_bottom + page_layout.content_height -
187 printing::kSettingHeaderFooterInterstice - offset_to_baseline;
188 break;
189 default:
190 NOTREACHED();
191 }
192
193 x = x / webkit_scale_factor;
194 y = y / webkit_scale_factor;
195 paint.setTextSize(paint.getTextSize() / webkit_scale_factor);
196 canvas->drawText(text.c_str(), text_byte_length, x, y, paint);
197 }
198
199 // Prints the headers onto the |canvas| if there is enough space to print them.
200 void PrintHeaders(skia::VectorCanvas* canvas,
201 const DictionaryValue& header_footer_info,
202 SkPaint paint,
203 const PageSizeMargins& page_layout,
204 float webkit_scale_factor,
205 const gfx::Font& font) {
206 string16 date = base::TimeFormatShortDateNumeric(Time::Now());
207 string16 title;
208 if (!header_footer_info.GetString(printing::kSettingHeaderFooterTitle,
209 &title)) {
210 NOTREACHED();
211 }
212 string16 header_text = date + title;
213
214 SkRect header_bounds;
215 paint.measureText(header_text.c_str(), header_text.length() * sizeof(char16),
216 &header_bounds, 0);
217 SkScalar text_height =
218 printing::kSettingHeaderFooterInterstice + header_bounds.height();
219 if (text_height > page_layout.margin_top)
220 return;
221
222 SkScalar segment_width = GetSegmentWidth(page_layout);
223 PrintHeaderFooterText(date, paint, canvas, printing::LEFT, printing::TOP,
224 webkit_scale_factor, page_layout, segment_width, font,
225 header_bounds.top());
226
227 // Calculate the available title width. If the date string is not long
228 // enough, increase the available space for the title.
229 // Assumes there is no header text to RIGHT of title.
230 SkScalar date_width = paint.measureText(date.c_str(),
231 date.length() * sizeof(char16));
232 SkScalar max_title_width = std::min(2 * segment_width,
233 2 * (segment_width - date_width) +
234 segment_width);
235 PrintHeaderFooterText(title, paint, canvas, printing::CENTER,
236 printing::TOP, webkit_scale_factor, page_layout,
237 max_title_width, font, header_bounds.top());
238 }
239
240 // Prints the footers onto the |canvas| if there is enough space to print them.
241 void PrintFooters(skia::VectorCanvas* canvas,
242 const DictionaryValue& header_footer_info,
243 SkPaint paint,
244 const PageSizeMargins& page_layout,
245 float webkit_scale_factor,
246 const gfx::Font& font,
247 int page_number,
248 int total_pages) {
249 string16 page_of_total_pages = base::IntToString16(page_number) +
250 UTF8ToUTF16("/") +
251 base::IntToString16(total_pages);
252 std::string url;
253 if (!header_footer_info.GetString(printing::kSettingHeaderFooterURL,
254 &url)) {
255 NOTREACHED();
256 }
257 string16 footer_text = page_of_total_pages + UTF8ToUTF16(url);
258
259 SkRect footer_bounds;
260 paint.measureText(footer_text.c_str(), footer_text.length() * sizeof(char16),
261 &footer_bounds, 0);
262 SkScalar text_height =
263 printing::kSettingHeaderFooterInterstice + footer_bounds.height();
264 if (text_height > page_layout.margin_bottom)
265 return;
266
267 SkScalar segment_width = GetSegmentWidth(page_layout);
268 PrintHeaderFooterText(page_of_total_pages, paint, canvas, printing::RIGHT,
269 printing::BOTTOM, webkit_scale_factor, page_layout,
270 segment_width, font, footer_bounds.bottom());
271
272 // Calculate the available URL width. Increase the available URL width
273 // if the |page_of_total_pages| string isn't long enough.
274 // Assumes no footer text being printed in the CENTER.
275 SkScalar page_width = paint.measureText(
276 page_of_total_pages.c_str(),
277 page_of_total_pages.length() * sizeof(char16));
278 SkScalar max_url_width =
279 (page_layout.content_width + page_layout.margin_left +
280 page_layout.margin_right) * 3 / 4;
281 max_url_width = std::min(max_url_width,
282 2 * (segment_width - page_width) + segment_width);
283 GURL gurl(url);
284 string16 url_elided = ui::ElideUrl(gurl, font,
285 ConvertPointsToPixelDouble(max_url_width),
286 std::string());
287 PrintHeaderFooterText(url_elided, paint, canvas, printing::LEFT,
288 printing::BOTTOM, webkit_scale_factor, page_layout,
289 max_url_width, font, footer_bounds.bottom());
290 }
291 #endif // USE_SKIA
292
104 } // namespace 293 } // namespace
105 294
295 #if defined(USE_SKIA)
296 // static - Not anonymous so that platform implementations can use it.
297 void PrintWebViewHelper::PrintHeaderAndFooter(
298 SkDevice* device,
299 skia::VectorCanvas* canvas,
300 int page_number,
301 int total_pages,
302 float webkit_scale_factor,
303 const PageSizeMargins& page_layout,
304 const DictionaryValue& header_footer_info) {
305 static_cast<skia::VectorPlatformDeviceSkia*>(device)->setDrawingArea(
306 SkPDFDevice::kMargin_DrawingArea);
307
308 SkPaint paint;
309 paint.setColor(SK_ColorBLACK);
310 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
311 paint.setTextSize(printing::kSettingHeaderFooterFontSize);
312 gfx::Font font(UTF8ToUTF16(printing::kSettingHeaderFooterFontName),
313 ceil(ConvertPointsToPixelDouble(
314 printing::kSettingHeaderFooterFontSize)));
315 paint.setTypeface(SkTypeface::CreateFromName(
316 UTF16ToUTF8(font.GetFontName()).c_str(), SkTypeface::kNormal));
317
318 PrintHeaders(canvas, header_footer_info, paint, page_layout,
319 webkit_scale_factor, font);
320 PrintFooters(canvas, header_footer_info, paint, page_layout,
321 webkit_scale_factor, font, page_number, total_pages);
322
323 static_cast<skia::VectorPlatformDeviceSkia*>(device)->setDrawingArea(
324 SkPDFDevice::kContent_DrawingArea);
325 }
326 #endif // USE_SKIA
327
106 PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint( 328 PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint(
107 const PrintMsg_Print_Params& print_params, 329 const PrintMsg_Print_Params& print_params,
108 WebFrame* frame, 330 WebFrame* frame,
109 WebNode* node) 331 WebNode* node)
110 : frame_(frame), 332 : frame_(frame),
111 web_view_(frame->view()), 333 web_view_(frame->view()),
112 dpi_(static_cast<int>(print_params.dpi)), 334 dpi_(static_cast<int>(print_params.dpi)),
113 expected_pages_count_(0), 335 expected_pages_count_(0),
114 use_browser_overlays_(true), 336 use_browser_overlays_(true),
115 finished_(false) { 337 finished_(false) {
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 return false; 980 return false;
759 } 981 }
760 return true; 982 return true;
761 } 983 }
762 984
763 bool PrintWebViewHelper::UpdatePrintSettings( 985 bool PrintWebViewHelper::UpdatePrintSettings(
764 const DictionaryValue& job_settings) { 986 const DictionaryValue& job_settings) {
765 PrintMsg_PrintPages_Params settings; 987 PrintMsg_PrintPages_Params settings;
766 988
767 Send(new PrintHostMsg_UpdatePrintSettings(routing_id(), 989 Send(new PrintHostMsg_UpdatePrintSettings(routing_id(),
768 print_pages_params_->params.document_cookie, job_settings, &settings)); 990 print_pages_params_->params.document_cookie, job_settings, &settings));
769 991
770 if (settings.params.dpi < kMinDpi || !settings.params.document_cookie) 992 if (settings.params.dpi < kMinDpi || !settings.params.document_cookie)
771 return false; 993 return false;
772 994
773 if (!UpdatePrintSettingsRequestId(job_settings, &(settings.params))) 995 if (!UpdatePrintSettingsRequestId(job_settings, &(settings.params)))
774 return false; 996 return false;
775 997
776 print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings)); 998 print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings));
999 // Getting Header and Footer settings.
1000 bool display_header_footer = false;
1001 if (!job_settings.GetBoolean(printing::kSettingHeaderFooterEnabled,
1002 &display_header_footer)) {
1003 NOTREACHED();
1004 }
1005 print_pages_params_->params.display_header_footer = display_header_footer;
1006
1007 if (display_header_footer) {
1008 string16 title;
1009 std::string url;
1010 if (!job_settings.GetString(printing::kSettingHeaderFooterTitle, &title) ||
1011 !job_settings.GetString(printing::kSettingHeaderFooterURL, &url)) {
1012 NOTREACHED();
1013 }
1014 header_footer_info_.reset(new DictionaryValue());
1015 header_footer_info_->SetString(printing::kSettingHeaderFooterURL, url);
1016 header_footer_info_->SetString(printing::kSettingHeaderFooterTitle, title);
1017 }
1018
777 Send(new PrintHostMsg_DidGetDocumentCookie(routing_id(), 1019 Send(new PrintHostMsg_DidGetDocumentCookie(routing_id(),
778 settings.params.document_cookie)); 1020 settings.params.document_cookie));
779 return true; 1021 return true;
780 } 1022 }
781 1023
782 bool PrintWebViewHelper::GetPrintSettingsFromUser(WebKit::WebFrame* frame, 1024 bool PrintWebViewHelper::GetPrintSettingsFromUser(WebKit::WebFrame* frame,
783 int expected_pages_count, 1025 int expected_pages_count,
784 bool use_browser_overlays) { 1026 bool use_browser_overlays) {
785 PrintHostMsg_ScriptedPrint_Params params; 1027 PrintHostMsg_ScriptedPrint_Params params;
786 PrintMsg_PrintPages_Params print_settings; 1028 PrintMsg_PrintPages_Params print_settings;
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 const gfx::Size& 1358 const gfx::Size&
1117 PrintWebViewHelper::PrintPreviewContext::GetPrintCanvasSize() const { 1359 PrintWebViewHelper::PrintPreviewContext::GetPrintCanvasSize() const {
1118 return prep_frame_view_->GetPrintCanvasSize(); 1360 return prep_frame_view_->GetPrintCanvasSize();
1119 } 1361 }
1120 1362
1121 void PrintWebViewHelper::PrintPreviewContext::ClearContext() { 1363 void PrintWebViewHelper::PrintPreviewContext::ClearContext() {
1122 prep_frame_view_.reset(); 1364 prep_frame_view_.reset();
1123 metafile_.reset(); 1365 metafile_.reset();
1124 rendered_pages_.clear(); 1366 rendered_pages_.clear();
1125 } 1367 }
OLDNEW
« no previous file with comments | « chrome/renderer/print_web_view_helper.h ('k') | chrome/renderer/print_web_view_helper_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698