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

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

Powered by Google App Engine
This is Rietveld 408576698