| 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 c24e5830fa37b736a1bfc0426302c2fcb97326f7..90eceaa66a8b312a5b592fa9ac66e4b1f5293a0b 100644
|
| --- a/chrome/renderer/print_web_view_helper.cc
|
| +++ b/chrome/renderer/print_web_view_helper.cc
|
| @@ -4,12 +4,17 @@
|
|
|
| #include "chrome/renderer/print_web_view_helper.h"
|
|
|
| +#include <algorithm>
|
| +#include <cmath>
|
| #include <string>
|
|
|
| #include "base/command_line.h"
|
| +#include "base/i18n/time_formatting.h"
|
| #include "base/logging.h"
|
| #include "base/metrics/histogram.h"
|
| #include "base/process_util.h"
|
| +#include "base/string_number_conversions.h"
|
| +#include "base/time.h"
|
| #include "base/utf_string_conversions.h"
|
| #include "chrome/common/chrome_switches.h"
|
| #include "chrome/common/print_messages.h"
|
| @@ -21,6 +26,9 @@
|
| #include "printing/metafile_impl.h"
|
| #include "printing/print_job_constants.h"
|
| #include "printing/units.h"
|
| +#include "skia/ext/vector_canvas.h"
|
| +#include "skia/ext/vector_platform_device_skia.h"
|
| +#include "third_party/skia/include/core/SkTypeface.h"
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h"
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
|
| @@ -32,13 +40,16 @@
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h"
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
|
| #include "ui/base/l10n/l10n_util.h"
|
| +#include "ui/base/text/text_elider.h"
|
|
|
| #if defined(OS_POSIX)
|
| #include "content/common/view_messages.h"
|
| #endif
|
|
|
| +using base::Time;
|
| using printing::ConvertPixelsToPoint;
|
| using printing::ConvertPixelsToPointDouble;
|
| +using printing::ConvertPointsToPixelDouble;
|
| using printing::ConvertUnit;
|
| using printing::ConvertUnitDouble;
|
| using WebKit::WebConsoleMessage;
|
| @@ -88,12 +99,209 @@ 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());
|
| }
|
|
|
| +// Splits the horizontal width equally into three segments with an interstice
|
| +// between each segment. Returns the width of this segment.
|
| +SkScalar GetSegmentWidth(PageSizeMargins& page_layout) {
|
| + return (page_layout.margin_left +
|
| + page_layout.content_width +
|
| + page_layout.margin_right -
|
| + (printing::kSettingHeaderFooterHorizontalRegions + 1) *
|
| + printing::kSettingHeaderFooterInterstice) /
|
| + printing::kSettingHeaderFooterHorizontalRegions;
|
| +}
|
| +
|
| +// Given a text, the positions and the paint object, this method gets the
|
| +// coordinates and prints the text at those co-ordinates on the canvas.
|
| +void PrintHeaderFooterText(
|
| + string16 text,
|
| + SkPaint paint,
|
| + const SkRefPtr<skia::VectorCanvas>& canvas,
|
| + printing::HorizontalHeaderFooterPosition hor_pos,
|
| + printing::VerticalHeaderFooterPosition ver_pos,
|
| + float webkit_scale_factor,
|
| + PageSizeMargins& page_layout,
|
| + SkScalar max_text_width,
|
| + gfx::Font font,
|
| + SkScalar height_to_baseline) {
|
| + text = ui::ElideText(text, font, ConvertPointsToPixelDouble(max_text_width),
|
| + false);
|
| +
|
| + SkPoint text_location;
|
| + size_t text_byte_length = text.length() * sizeof(char16);
|
| + // Gets the (x, y) coordinate from where we want to start printing the current
|
| + // text depending on the alignment 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 (hor_pos) {
|
| + case printing::LEFT: {
|
| + x = page_layout.margin_left * (-1) +
|
| + printing::kSettingHeaderFooterInterstice;
|
| + 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 (ver_pos) {
|
| + case printing::TOP: {
|
| + y = page_layout.margin_top * (-1) +
|
| + printing::kSettingHeaderFooterInterstice - 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);
|
| +}
|
| +
|
| } // namespace
|
|
|
| +void PrintHeaderAndFooter(skia::VectorPlatformDeviceSkia* device,
|
| + const SkRefPtr<skia::VectorCanvas>& canvas,
|
| + int page_number, int total_pages,
|
| + float webkit_scale_factor,
|
| + PageSizeMargins& page_layout,
|
| + const DictionaryValue* header_footer_info) {
|
| + // Set the drawing area to draw in the margins.
|
| + device->setDrawingArea(SkPDFDevice::kMargin_DrawingArea);
|
| +
|
| + // Setting up styles for the headers and footers text.
|
| + 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));
|
| +
|
| + // Ensuring we have enough space to print above and below the page to print
|
| + // headers.
|
| + 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;
|
| +
|
| + // Ensuring we have enough space to print above and below the page to print
|
| + // footers.
|
| + string16 page_on_page_total = 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_on_page_total + 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);
|
| + // Printing the Date.
|
| + PrintHeaderFooterText(date, paint, canvas, printing::LEFT, printing::TOP,
|
| + webkit_scale_factor, page_layout, segment_width,
|
| + font, header_bounds.top());
|
| +
|
| + // Printing the title.
|
| + SkScalar date_width = paint.measureText(date.c_str(),
|
| + date.length() * sizeof(char16));
|
| + // Calculating 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());
|
| +
|
| + // Printing the page numbers at the bottom right corner of page.
|
| + PrintHeaderFooterText(page_on_page_total, paint, canvas, printing::RIGHT,
|
| + printing::BOTTOM, webkit_scale_factor,
|
| + page_layout, segment_width, font,
|
| + footer_bounds.bottom());
|
| +
|
| + // Printing the URL.
|
| + GURL gurl(url);
|
| + SkScalar page_width = paint.measureText(
|
| + page_on_page_total.c_str(),
|
| + page_on_page_total.length() * sizeof(char16));
|
| +
|
| + // Calculating the available URL width. We increase the available URL width
|
| + // if the |page_on_page_total| string isn't long enough.
|
| + // Assumes no footer text being printed in the CENTER.
|
| + SkScalar max_url_width = 3 * (page_layout.content_width +
|
| + page_layout.margin_left + page_layout.margin_right) / 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.
|
| + device->setDrawingArea(SkPDFDevice::kContent_DrawingArea);
|
| +}
|
| +
|
| PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint(
|
| const PrintMsg_Print_Params& print_params,
|
| WebFrame* frame,
|
| @@ -280,9 +488,12 @@ void PrintWebViewHelper::OnPrintForSystemDialog() {
|
| }
|
| }
|
|
|
| -void PrintWebViewHelper::OnPrintPreview(const DictionaryValue& settings) {
|
| +void PrintWebViewHelper::OnPrintPreview(
|
| + const DictionaryValue& settings,
|
| + const DictionaryValue& header_footer_info) {
|
| DCHECK(is_preview_);
|
| print_preview_context_.OnPrintPreview();
|
| + header_footer_info_ = header_footer_info.DeepCopy();
|
|
|
| if (!InitPrintSettings(print_preview_context_.frame(),
|
| print_preview_context_.node())) {
|
| @@ -738,6 +949,7 @@ bool PrintWebViewHelper::UpdatePrintSettingsCloud(
|
| return false;
|
| // TODO(abodenha@chromium.org) Parse page ranges from the job_settings.
|
| print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings));
|
| + print_pages_params_->params.display_header_footer = false;
|
| return true;
|
| }
|
|
|
| @@ -755,6 +967,11 @@ bool PrintWebViewHelper::UpdatePrintSettingsLocal(
|
| return false;
|
|
|
| print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings));
|
| + bool header_footer;
|
| + if (!job_settings.GetBoolean(printing::kSettingHeaderFooter, &header_footer))
|
| + NOTREACHED();
|
| + print_pages_params_->params.display_header_footer = header_footer;
|
| +
|
| Send(new PrintHostMsg_DidGetDocumentCookie(routing_id(),
|
| settings.params.document_cookie));
|
| return true;
|
|
|