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 <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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |