Chromium Code Reviews| Index: chrome/renderer/print_web_view_helper.cc |
| diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc |
| index 7ad456ff47cbbfc7acd57c6b0aca0fa3404d0e73..9e198b2680a6fc4035086170016b423fbe80b611 100644 |
| --- a/chrome/renderer/print_web_view_helper.cc |
| +++ b/chrome/renderer/print_web_view_helper.cc |
| @@ -36,8 +36,22 @@ |
| #include "content/common/view_messages.h" |
| #endif |
| +#if defined(USE_SKIA) |
| +#include <algorithm> |
| +#include <cmath> |
| +#include "base/i18n/time_formatting.h" |
| +#include "base/string_number_conversions.h" |
| +#include "base/time.h" |
| +#include "skia/ext/vector_canvas.h" |
| +#include "skia/ext/vector_platform_device_skia.h" |
| +#include "third_party/skia/include/core/SkTypeface.h" |
| +#include "ui/base/text/text_elider.h" |
| +#endif |
|
vandebo (ex-Chrome)
2011/08/01 21:07:37
// USE_SKIA
Aayush Kumar
2011/08/02 00:18:13
Done.
|
| + |
| +using base::Time; |
| using printing::ConvertPixelsToPoint; |
| using printing::ConvertPixelsToPointDouble; |
| +using printing::ConvertPointsToPixelDouble; |
| using printing::ConvertUnit; |
| using printing::ConvertUnitDouble; |
| using WebKit::WebConsoleMessage; |
| @@ -87,6 +101,8 @@ bool PrintMsg_Print_Params_IsEqual( |
| oldParams.params.supports_alpha_blend == |
| newParams.params.supports_alpha_blend && |
| oldParams.pages.size() == newParams.pages.size() && |
| + oldParams.params.display_header_footer == |
| + newParams.params.display_header_footer && |
| std::equal(oldParams.pages.begin(), oldParams.pages.end(), |
| newParams.pages.begin()); |
| } |
| @@ -101,8 +117,209 @@ void CalculatePrintCanvasSize(const PrintMsg_Print_Params& print_params, |
| print_params.desired_dpi)); |
| } |
| +#if defined(USE_SKIA) |
| +// Splits the horizontal width equally into segments with an interstice |
| +// between each segment. Returns the width of this segment. |
| +SkScalar GetSegmentWidth(const PageSizeMargins& page_layout) { |
| + // Interstice is left at both ends of the page as well as between |
| + // each region, so 1 is added. |
| + return (page_layout.margin_left + |
| + 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.
|
| + page_layout.margin_right - |
| + (printing::kSettingHeaderFooterHorizontalRegions + 1) * |
| + 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.
|
| + printing::kSettingHeaderFooterHorizontalRegions; |
| +} |
| + |
| +// Given a text, the positions, and the paint object, this method gets the |
| +// coordinates and prints the text at those coordinates on the canvas. |
| +void PrintHeaderFooterText( |
| + string16 text, |
| + 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
|
| + skia::VectorCanvas& canvas, |
| + printing::HorizontalHeaderFooterPosition horizontal_position, |
| + printing::VerticalHeaderFooterPosition vertical_position, |
| + float webkit_scale_factor, |
| + const PageSizeMargins& page_layout, |
| + SkScalar max_text_width, |
| + 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.
|
| + 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.
|
| + text = ui::ElideText(text, font, ConvertPointsToPixelDouble(max_text_width), |
| + false); |
| + |
| + 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.
|
| + size_t text_byte_length = text.length() * sizeof(char16); |
| + // Get the (x, y) coordinate from where printing of the current text should |
| + // start depending on the horizontal alignment (LEFT, RIGHT, CENTER) and |
| + // vertical alignment (TOP, BOTTOM). |
| + SkScalar text_width_in_points = paint.measureText(text.c_str(), |
| + text_byte_length); |
| + SkScalar x = 0; |
| + switch (horizontal_position) { |
| + case printing::LEFT: { |
| + x = printing::kSettingHeaderFooterInterstice - page_layout.margin_left; |
| + break; |
| + } |
| + case printing::RIGHT: { |
| + x = page_layout.content_width + page_layout.margin_right - |
| + printing::kSettingHeaderFooterInterstice - text_width_in_points; |
| + break; |
| + } |
| + case printing::CENTER: { |
| + SkScalar available_width = GetSegmentWidth(page_layout); |
| + x = available_width - page_layout.margin_left + |
| + (available_width - text_width_in_points) / 2; |
| + break; |
| + } |
| + default: { |
| + NOTREACHED(); |
| + } |
| + } |
| + |
| + SkScalar y = 0; |
| + switch (vertical_position) { |
| + case printing::TOP: { |
| + 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
|
| + page_layout.margin_top - height_to_baseline; |
| + break; |
| + } |
| + case printing::BOTTOM: { |
| + y = page_layout.margin_bottom + page_layout.content_height - |
| + printing::kSettingHeaderFooterInterstice - height_to_baseline; |
| + break; |
| + } |
| + default: { |
| + NOTREACHED(); |
| + } |
| + } |
| + |
| + text_location.set(x / webkit_scale_factor, y / webkit_scale_factor); |
| + paint.setTextSize(paint.getTextSize() / webkit_scale_factor); |
| + canvas.drawText(text.c_str(), text_byte_length, text_location.x(), |
| + text_location.y(), paint); |
| +} |
| +#endif // USE_SKIA |
| + |
| } // namespace |
| +#if defined(USE_SKIA) |
| +// static - Not anonymous so that platform implementations can use it. |
| +void PrintWebViewHelper::PrintHeaderAndFooter( |
| + SkDevice* device, |
| + skia::VectorCanvas& canvas, |
| + int page_number, |
| + int total_pages, |
| + float webkit_scale_factor, |
| + const PageSizeMargins& page_layout, |
| + const DictionaryValue& header_footer_info) { |
| + // 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 :)
|
| + static_cast<skia::VectorPlatformDeviceSkia*>(device)->setDrawingArea( |
| + SkPDFDevice::kMargin_DrawingArea); |
| + |
| + // 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
|
| + SkPaint paint; |
| + paint.setColor(SK_ColorBLACK); |
| + paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); |
| + paint.setTextSize(printing::kSettingHeaderFooterFontSize); |
| + gfx::Font font(UTF8ToUTF16(printing::kSettingHeaderFooterFontName), |
| + ceil(ConvertPointsToPixelDouble( |
| + printing::kSettingHeaderFooterFontSize))); |
| + paint.setTypeface(SkTypeface::CreateFromName( |
| + UTF16ToUTF8(font.GetFontName()).c_str(), SkTypeface::kNormal)); |
| + |
| + // Ensure we have enough space to print above and below the page to print |
| + // 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.
|
| + string16 date = base::TimeFormatShortDateNumeric(Time::Now()); |
| + string16 title; |
| + if (!header_footer_info.GetString(printing::kSettingHeaderFooterTitle, |
| + &title)) { |
| + NOTREACHED(); |
| + } |
| + |
| + SkRect header_bounds; |
| + string16 header_text = date + title; |
| + paint.measureText(header_text.c_str(), header_text.length() * sizeof(char16), |
| + &header_bounds, 0); |
| + |
| + SkScalar text_height = |
| + printing::kSettingHeaderFooterInterstice + header_bounds.height(); |
| + |
| + if (text_height > page_layout.margin_top) |
| + 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.
|
| + |
| + // Ensure we have enough space to print above and below the page to print |
| + // footers. |
| + string16 page_of_total_pages = base::IntToString16(page_number) + |
| + UTF8ToUTF16("/") + |
| + base::IntToString16(total_pages); |
| + std::string url; |
| + if (!header_footer_info.GetString(printing::kSettingHeaderFooterURL, |
| + &url)) { |
| + NOTREACHED(); |
| + } |
| + |
| + SkRect footer_bounds; |
| + string16 footer_text = page_of_total_pages + UTF8ToUTF16(url); |
| + paint.measureText(footer_text.c_str(), footer_text.length() * sizeof(char16), |
| + &footer_bounds, 0); |
| + |
| + text_height = |
| + printing::kSettingHeaderFooterInterstice + footer_bounds.height(); |
| + |
| + if (text_height > page_layout.margin_bottom) |
| + return; |
| + |
| + SkScalar segment_width = GetSegmentWidth(page_layout); |
| + // Print the Date. |
| + PrintHeaderFooterText(date, paint, canvas, printing::LEFT, printing::TOP, |
| + webkit_scale_factor, page_layout, segment_width, font, |
| + header_bounds.top()); |
| + |
| + // Print the title. |
| + SkScalar date_width = paint.measureText(date.c_str(), |
| + date.length() * sizeof(char16)); |
| + // Calculate the available title width. If the date string is not long |
| + // enough, then, we increase the available space we have for the title. |
| + // Assumes there is no header text to RIGHT of title. |
| + SkScalar max_title_width = std::min(2 * segment_width, |
| + 2 * (segment_width - date_width) + |
| + segment_width); |
| + PrintHeaderFooterText(title, paint, canvas, printing::CENTER, |
| + printing::TOP, webkit_scale_factor, page_layout, |
| + max_title_width, font, header_bounds.top()); |
| + |
| + // Print the page numbers at the bottom right corner of page. |
| + PrintHeaderFooterText(page_of_total_pages, paint, canvas, printing::RIGHT, |
| + printing::BOTTOM, webkit_scale_factor, page_layout, |
| + segment_width, font, footer_bounds.bottom()); |
| + |
| + // Print the URL. |
| + GURL gurl(url); |
| + SkScalar page_width = paint.measureText( |
| + page_of_total_pages.c_str(), |
| + page_of_total_pages.length() * sizeof(char16)); |
| + |
| + // Calculate the available URL width. We increase the available URL width |
| + // if the |page_of_total_pages| string isn't long enough. |
| + // Assumes no footer text being printed in the CENTER. |
| + SkScalar max_url_width = |
| + (page_layout.content_width + page_layout.margin_left + |
| + page_layout.margin_right) * 3 / 4; |
| + max_url_width = std::min(max_url_width, |
| + 2 * (segment_width - page_width) + segment_width); |
| + string16 url_elided = ui::ElideUrl(gurl, font, |
| + ConvertPointsToPixelDouble(max_url_width), |
| + std::string()); |
| + PrintHeaderFooterText(url_elided, paint, canvas, printing::LEFT, |
| + printing::BOTTOM, webkit_scale_factor, page_layout, |
| + max_url_width, font, footer_bounds.bottom()); |
| + |
| + // Restore the drawing area to draw in the content area. |
| + static_cast<skia::VectorPlatformDeviceSkia*>(device)->setDrawingArea( |
| + SkPDFDevice::kContent_DrawingArea); |
| +} |
| +#endif // USE_SKIA |
| + |
| PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint( |
| const PrintMsg_Print_Params& print_params, |
| WebFrame* frame, |
| @@ -776,6 +993,21 @@ bool PrintWebViewHelper::UpdatePrintSettings( |
| return false; |
| print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings)); |
| + // Getting Header and Footer settings. |
| + bool display_header_footer; |
| + string16 title; |
| + std::string url; |
| + 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.
|
| + &display_header_footer) || |
| + !job_settings.GetString(printing::kSettingHeaderFooterTitle, &title) || |
| + !job_settings.GetString(printing::kSettingHeaderFooterURL, &url)) { |
| + NOTREACHED(); |
| + } |
| + print_pages_params_->params.display_header_footer = display_header_footer; |
| + header_footer_info_.reset(new DictionaryValue()); |
| + 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.
|
| + header_footer_info_->SetString(printing::kSettingHeaderFooterTitle, title); |
| + |
| Send(new PrintHostMsg_DidGetDocumentCookie(routing_id(), |
| settings.params.document_cookie)); |
| return true; |