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

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: Style changes as per Kausalya and Demetrios' comments 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
vandebo (ex-Chrome) 2011/08/01 21:07:37 // USE_SKIA
Aayush Kumar 2011/08/02 00:18:13 Done.
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 +
vandebo (ex-Chrome) 2011/08/01 21:07:37 I'm actually not sure of the indent here... should
Aayush Kumar 2011/08/02 00:18:13 Done.
128 page_layout.margin_right -
129 (printing::kSettingHeaderFooterHorizontalRegions + 1) *
130 printing::kSettingHeaderFooterInterstice) /
vandebo (ex-Chrome) 2011/08/01 21:07:37 nit: extra space. Sorry if I mislead you here bef
Aayush Kumar 2011/08/02 00:18:13 Done.
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,
vandebo (ex-Chrome) 2011/08/01 21:07:37 const SkPaint& paint
Aayush Kumar 2011/08/02 00:18:13 I don't want to pass a reference here, since, I am
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,
vandebo (ex-Chrome) 2011/08/01 21:07:37 const gfx::Font& font
Aayush Kumar 2011/08/02 00:18:13 Done.
146 SkScalar height_to_baseline) {
vandebo (ex-Chrome) 2011/08/01 21:07:37 nit: this might be better named space_for_descende
Aayush Kumar 2011/08/02 00:18:13 Done.
147 text = ui::ElideText(text, font, ConvertPointsToPixelDouble(max_text_width),
148 false);
149
150 SkPoint text_location;
vandebo (ex-Chrome) 2011/08/01 21:07:37 I don't think you need both this and x & y; use on
Aayush Kumar 2011/08/02 00:18:13 Done.
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;
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 -
vandebo (ex-Chrome) 2011/08/01 21:07:37 This is putting the text just above the content ar
Aayush Kumar 2011/08/02 00:18:13 No, this actually doesn't do that. It places it r
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
202
104 } // namespace 203 } // namespace
105 204
205 #if defined(USE_SKIA)
206 // static - Not anonymous so that platform implementations can use it.
207 void PrintWebViewHelper::PrintHeaderAndFooter(
208 SkDevice* device,
209 skia::VectorCanvas& canvas,
210 int page_number,
211 int total_pages,
212 float webkit_scale_factor,
213 const PageSizeMargins& page_layout,
214 const DictionaryValue& header_footer_info) {
215 // Set the drawing area to draw in the margins.
vandebo (ex-Chrome) 2011/08/01 21:07:37 nit: comment isn't needed.
Aayush Kumar 2011/08/02 00:18:13 Done.
vandebo (ex-Chrome) 2011/08/03 19:00:05 Done in spirit only ;-)
Aayush Kumar 2011/08/04 18:25:04 Done this time - sorry :)
216 static_cast<skia::VectorPlatformDeviceSkia*>(device)->setDrawingArea(
217 SkPDFDevice::kMargin_DrawingArea);
218
219 // Setting up styles for the headers and footers text.
vandebo (ex-Chrome) 2011/08/01 21:07:37 nit: comment isn't needed
Aayush Kumar 2011/08/02 00:18:13 Can I leave this comment? I found it a lot easier
vandebo (ex-Chrome) 2011/08/03 19:00:05 Meta comment - it's harder to see replies when you
Aayush Kumar 2011/08/04 18:25:04 Ahh okay :) It's weird though because when I clic
220 SkPaint paint;
221 paint.setColor(SK_ColorBLACK);
222 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
223 paint.setTextSize(printing::kSettingHeaderFooterFontSize);
224 gfx::Font font(UTF8ToUTF16(printing::kSettingHeaderFooterFontName),
225 ceil(ConvertPointsToPixelDouble(
226 printing::kSettingHeaderFooterFontSize)));
227 paint.setTypeface(SkTypeface::CreateFromName(
228 UTF16ToUTF8(font.GetFontName()).c_str(), SkTypeface::kNormal));
229
230 // Ensure we have enough space to print above and below the page to print
231 // headers.
vandebo (ex-Chrome) 2011/08/01 21:07:37 I think this comment and the one on 250 should go
Aayush Kumar 2011/08/02 00:18:13 This is actually checked for on line 244. On 201
vandebo (ex-Chrome) 2011/08/03 19:00:05 Why don't we do this... move the conditionals abou
Aayush Kumar 2011/08/04 18:25:04 Done.
232 string16 date = base::TimeFormatShortDateNumeric(Time::Now());
233 string16 title;
234 if (!header_footer_info.GetString(printing::kSettingHeaderFooterTitle,
235 &title)) {
236 NOTREACHED();
237 }
238
239 SkRect header_bounds;
240 string16 header_text = date + title;
241 paint.measureText(header_text.c_str(), header_text.length() * sizeof(char16),
242 &header_bounds, 0);
243
244 SkScalar text_height =
245 printing::kSettingHeaderFooterInterstice + header_bounds.height();
246
247 if (text_height > page_layout.margin_top)
248 return;
vandebo (ex-Chrome) 2011/08/01 21:07:37 What if there is room for the footers, but not the
Aayush Kumar 2011/08/02 00:18:13 I am going for all or nothing. Just want to be co
vandebo (ex-Chrome) 2011/08/03 19:00:05 It seems to me that if there's still room for the
Aayush Kumar 2011/08/04 18:25:04 Done.
249
250 // Ensure we have enough space to print above and below the page to print
251 // footers.
252 string16 page_of_total_pages = base::IntToString16(page_number) +
253 UTF8ToUTF16("/") +
254 base::IntToString16(total_pages);
255 std::string url;
256 if (!header_footer_info.GetString(printing::kSettingHeaderFooterURL,
257 &url)) {
258 NOTREACHED();
259 }
260
261 SkRect footer_bounds;
262 string16 footer_text = page_of_total_pages + UTF8ToUTF16(url);
263 paint.measureText(footer_text.c_str(), footer_text.length() * sizeof(char16),
264 &footer_bounds, 0);
265
266 text_height =
267 printing::kSettingHeaderFooterInterstice + footer_bounds.height();
268
269 if (text_height > page_layout.margin_bottom)
270 return;
271
272 SkScalar segment_width = GetSegmentWidth(page_layout);
273 // Print the Date.
274 PrintHeaderFooterText(date, paint, canvas, printing::LEFT, printing::TOP,
275 webkit_scale_factor, page_layout, segment_width, font,
276 header_bounds.top());
277
278 // Print the title.
279 SkScalar date_width = paint.measureText(date.c_str(),
280 date.length() * sizeof(char16));
281 // Calculate the available title width. If the date string is not long
282 // enough, then, we increase the available space we have for the title.
283 // Assumes there is no header text to RIGHT of title.
284 SkScalar max_title_width = std::min(2 * segment_width,
285 2 * (segment_width - date_width) +
286 segment_width);
287 PrintHeaderFooterText(title, paint, canvas, printing::CENTER,
288 printing::TOP, webkit_scale_factor, page_layout,
289 max_title_width, font, header_bounds.top());
290
291 // Print the page numbers at the bottom right corner of page.
292 PrintHeaderFooterText(page_of_total_pages, paint, canvas, printing::RIGHT,
293 printing::BOTTOM, webkit_scale_factor, page_layout,
294 segment_width, font, 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, page_layout,
315 max_url_width, font, footer_bounds.bottom());
316
317 // Restore the drawing area to draw in the content area.
318 static_cast<skia::VectorPlatformDeviceSkia*>(device)->setDrawingArea(
319 SkPDFDevice::kContent_DrawingArea);
320 }
321 #endif // USE_SKIA
322
106 PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint( 323 PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint(
107 const PrintMsg_Print_Params& print_params, 324 const PrintMsg_Print_Params& print_params,
108 WebFrame* frame, 325 WebFrame* frame,
109 WebNode* node) 326 WebNode* node)
110 : frame_(frame), 327 : frame_(frame),
111 web_view_(frame->view()), 328 web_view_(frame->view()),
112 dpi_(static_cast<int>(print_params.dpi)), 329 dpi_(static_cast<int>(print_params.dpi)),
113 expected_pages_count_(0), 330 expected_pages_count_(0),
114 use_browser_overlays_(true), 331 use_browser_overlays_(true),
115 finished_(false) { 332 finished_(false) {
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 Send(new PrintHostMsg_UpdatePrintSettings(routing_id(), 986 Send(new PrintHostMsg_UpdatePrintSettings(routing_id(),
770 print_pages_params_->params.document_cookie, job_settings, &settings)); 987 print_pages_params_->params.document_cookie, job_settings, &settings));
771 988
772 if (settings.params.dpi < kMinDpi || !settings.params.document_cookie) 989 if (settings.params.dpi < kMinDpi || !settings.params.document_cookie)
773 return false; 990 return false;
774 991
775 if (!UpdatePrintSettingsRequestId(job_settings, &(settings.params))) 992 if (!UpdatePrintSettingsRequestId(job_settings, &(settings.params)))
776 return false; 993 return false;
777 994
778 print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings)); 995 print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings));
996 // Getting Header and Footer settings.
997 bool display_header_footer;
998 string16 title;
999 std::string url;
1000 if (!job_settings.GetBoolean(printing::kSettingHeaderFooter,
kmadhusu 2011/08/01 17:17:08 (repeating our in-person conversation): Remove the
Aayush Kumar 2011/08/02 00:18:13 Done.
1001 &display_header_footer) ||
1002 !job_settings.GetString(printing::kSettingHeaderFooterTitle, &title) ||
1003 !job_settings.GetString(printing::kSettingHeaderFooterURL, &url)) {
1004 NOTREACHED();
1005 }
1006 print_pages_params_->params.display_header_footer = display_header_footer;
1007 header_footer_info_.reset(new DictionaryValue());
1008 header_footer_info_->SetString(printing::kSettingHeaderFooterURL, url);
kmadhusu 2011/08/01 17:17:08 Populate the header_footer_info_ only if |display_
Aayush Kumar 2011/08/02 00:18:13 Done.
1009 header_footer_info_->SetString(printing::kSettingHeaderFooterTitle, title);
1010
779 Send(new PrintHostMsg_DidGetDocumentCookie(routing_id(), 1011 Send(new PrintHostMsg_DidGetDocumentCookie(routing_id(),
780 settings.params.document_cookie)); 1012 settings.params.document_cookie));
781 return true; 1013 return true;
782 } 1014 }
783 1015
784 bool PrintWebViewHelper::GetPrintSettingsFromUser(WebKit::WebFrame* frame, 1016 bool PrintWebViewHelper::GetPrintSettingsFromUser(WebKit::WebFrame* frame,
785 int expected_pages_count, 1017 int expected_pages_count,
786 bool use_browser_overlays) { 1018 bool use_browser_overlays) {
787 PrintHostMsg_ScriptedPrint_Params params; 1019 PrintHostMsg_ScriptedPrint_Params params;
788 PrintMsg_PrintPages_Params print_settings; 1020 PrintMsg_PrintPages_Params print_settings;
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 const gfx::Size& 1356 const gfx::Size&
1125 PrintWebViewHelper::PrintPreviewContext::GetPrintCanvasSize() const { 1357 PrintWebViewHelper::PrintPreviewContext::GetPrintCanvasSize() const {
1126 return prep_frame_view_->GetPrintCanvasSize(); 1358 return prep_frame_view_->GetPrintCanvasSize();
1127 } 1359 }
1128 1360
1129 void PrintWebViewHelper::PrintPreviewContext::ClearContext() { 1361 void PrintWebViewHelper::PrintPreviewContext::ClearContext() {
1130 prep_frame_view_.reset(); 1362 prep_frame_view_.reset();
1131 metafile_.reset(); 1363 metafile_.reset();
1132 rendered_pages_.clear(); 1364 rendered_pages_.clear();
1133 } 1365 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698