| 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 3aff7532eb6c8b3bec82fe0c6c102b54834f6db0..d5685baa76d2dac0a89937eb32a02b7179ad9d29 100644
|
| --- a/chrome/renderer/print_web_view_helper.cc
|
| +++ b/chrome/renderer/print_web_view_helper.cc
|
| @@ -8,67 +8,59 @@
|
|
|
| #include "base/auto_reset.h"
|
| #include "base/command_line.h"
|
| +#include "base/json/json_writer.h"
|
| #include "base/logging.h"
|
| #include "base/metrics/histogram.h"
|
| +#include "base/process_util.h"
|
| +#include "base/stringprintf.h"
|
| #include "base/string_number_conversions.h"
|
| #include "base/utf_string_conversions.h"
|
| #include "chrome/common/chrome_switches.h"
|
| #include "chrome/common/print_messages.h"
|
| #include "chrome/common/render_messages.h"
|
| -#include "chrome/common/url_constants.h"
|
| #include "chrome/renderer/prerender/prerender_helper.h"
|
| #include "content/public/renderer/render_thread.h"
|
| #include "content/public/renderer/render_view.h"
|
| +#include "grit/browser_resources.h"
|
| #include "grit/generated_resources.h"
|
| +#include "printing/metafile.h"
|
| #include "printing/metafile_impl.h"
|
| -#include "printing/page_size_margins.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/SkRect.h"
|
| -#include "third_party/skia/include/core/SkTypeface.h"
|
| -#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCanvas.h"
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLRequest.h"
|
| -#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLResponse.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"
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebPlugin.h"
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginDocument.h"
|
| +#include "third_party/WebKit/Source/WebKit/chromium/public/WebPrintParams.h"
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebPrintScalingOption.h"
|
| +#include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h"
|
| +#include "third_party/WebKit/Source/WebKit/chromium/public/WebSettings.h"
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
|
| #include "ui/base/l10n/l10n_util.h"
|
| -#include "ui/base/layout.h"
|
| -#include "ui/gfx/rect.h"
|
| -#include "ui/gfx/skia_util.h"
|
| +#include "ui/base/resource/resource_bundle.h"
|
| #include "webkit/glue/webpreferences.h"
|
|
|
| -#if defined(OS_POSIX)
|
| -#include "base/process_util.h"
|
| -#endif
|
| -
|
| -#if defined(OS_WIN) || defined(OS_MACOSX)
|
| -#define USE_RENDER_TEXT
|
| -#endif
|
| +namespace {
|
|
|
| -#if defined(USE_RENDER_TEXT)
|
| -#include "ui/gfx/canvas.h"
|
| -#include "ui/gfx/render_text.h"
|
| -#endif
|
| +const double kMinDpi = 1.0;
|
|
|
| -namespace {
|
| +const char kPageLoadScriptFormat[] =
|
| + "document.open(); document.write(%s); document.close();";
|
|
|
| -#if defined(USE_RENDER_TEXT)
|
| -typedef gfx::RenderText* HeaderFooterPaint;
|
| -#else
|
| -typedef SkPaint HeaderFooterPaint;
|
| -#endif
|
| +const char kPageSetupScriptFormat[] = "setup(%s);";
|
|
|
| -const double kMinDpi = 1.0;
|
| +void ExecuteScript(WebKit::WebFrame* frame,
|
| + const char* script_format,
|
| + const base::Value& parameters) {
|
| + std::string json;
|
| + base::JSONWriter::Write(¶meters, &json);
|
| + std::string script = StringPrintf(script_format, json.c_str());
|
| + frame->executeScript(WebKit::WebString(UTF8ToUTF16(script)));
|
| +}
|
|
|
| int GetDPI(const PrintMsg_Print_Params* print_params) {
|
| #if defined(OS_MACOSX)
|
| @@ -351,114 +343,6 @@ bool FitToPageEnabled(const DictionaryValue& job_settings) {
|
| return fit_to_paper_size;
|
| }
|
|
|
| -// 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).
|
| -SkPoint GetHeaderFooterPosition(
|
| - float webkit_scale_factor,
|
| - const printing::PageSizeMargins& page_layout,
|
| - printing::HorizontalHeaderFooterPosition horizontal_position,
|
| - printing::VerticalHeaderFooterPosition vertical_position,
|
| - double offset_to_baseline,
|
| - double text_width_in_points) {
|
| - 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 = printing::GetHeaderFooterSegmentWidth(
|
| - page_layout.margin_left + page_layout.margin_right +
|
| - page_layout.content_width);
|
| - 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 -
|
| - page_layout.margin_top - offset_to_baseline;
|
| - break;
|
| - case printing::BOTTOM:
|
| - y = page_layout.margin_bottom + page_layout.content_height -
|
| - printing::kSettingHeaderFooterInterstice - offset_to_baseline;
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - }
|
| -
|
| - SkPoint point = SkPoint::Make(x / webkit_scale_factor,
|
| - y / webkit_scale_factor);
|
| - return point;
|
| -}
|
| -
|
| -// 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(
|
| - const string16& text,
|
| - WebKit::WebCanvas* canvas,
|
| - HeaderFooterPaint paint,
|
| - float webkit_scale_factor,
|
| - const printing::PageSizeMargins& page_layout,
|
| - printing::HorizontalHeaderFooterPosition horizontal_position,
|
| - printing::VerticalHeaderFooterPosition vertical_position,
|
| - double offset_to_baseline) {
|
| -#if defined(USE_RENDER_TEXT)
|
| - paint->SetText(text);
|
| - paint->SetFontSize(printing::kSettingHeaderFooterFontSize);
|
| - double text_width_in_points = paint->GetStringSize().width();
|
| - SkPoint point = GetHeaderFooterPosition(webkit_scale_factor, page_layout,
|
| - horizontal_position,
|
| - vertical_position, offset_to_baseline,
|
| - text_width_in_points);
|
| - // Set the scaled font size before drawing the text.
|
| - // This creates a new font instead of calling |paint->SetFontSize()| to work
|
| - // around a Windows 8 bug. See: http://crbug.com/139206
|
| - gfx::FontList font_list(
|
| - gfx::Font(printing::kSettingHeaderFooterFontFamilyName,
|
| - printing::kSettingHeaderFooterFontSize / webkit_scale_factor));
|
| - paint->SetFontList(font_list);
|
| - gfx::Size size(paint->GetStringSize());
|
| - gfx::Rect rect(point.x(), point.y() - paint->GetBaseline(),
|
| - size.width(), size.height());
|
| - paint->SetDisplayRect(rect);
|
| - {
|
| - SkMatrix m = canvas->getTotalMatrix();
|
| - ui::ScaleFactor device_scale_factor = ui::GetScaleFactorFromScale(
|
| - SkScalarAbs(m.getScaleX()));
|
| - scoped_ptr<gfx::Canvas> gfx_canvas(gfx::Canvas::CreateCanvasWithoutScaling(
|
| - canvas, device_scale_factor));
|
| - paint->Draw(gfx_canvas.get());
|
| - }
|
| -#else
|
| - // TODO(arthurhsu): following code has issues with i18n BiDi, see
|
| - // crbug.com/108599.
|
| - size_t text_byte_length = text.length() * sizeof(char16);
|
| - double text_width_in_points = SkScalarToDouble(paint.measureText(
|
| - text.c_str(), text_byte_length));
|
| - SkPoint point = GetHeaderFooterPosition(webkit_scale_factor, page_layout,
|
| - horizontal_position,
|
| - vertical_position, offset_to_baseline,
|
| - text_width_in_points);
|
| - paint.setTextSize(SkDoubleToScalar(
|
| - paint.getTextSize() / webkit_scale_factor));
|
| - canvas->drawText(text.c_str(), text_byte_length, point.x(), point.y(),
|
| - paint);
|
| -#endif
|
| -}
|
| -
|
| PrintMsg_Print_Params CalculatePrintParamsForCss(
|
| WebKit::WebFrame* frame,
|
| int page_index,
|
| @@ -527,102 +411,72 @@ void PrintWebViewHelper::PrintHeaderAndFooter(
|
| static_cast<skia::VectorPlatformDeviceSkia*>(canvas->getTopDevice());
|
| device->setDrawingArea(SkPDFDevice::kMargin_DrawingArea);
|
|
|
| -#if defined(USE_RENDER_TEXT)
|
| - scoped_ptr<gfx::RenderText> render_text(gfx::RenderText::CreateInstance());
|
| - // TODO(asvitkine): The below line is to workaround http://crbug.com/133548.
|
| - // Remove it when the underlying Skia bug has been fixed.
|
| - render_text->set_clip_to_display_rect(false);
|
| - gfx::FontList font_list(
|
| - gfx::Font(printing::kSettingHeaderFooterFontFamilyName,
|
| - printing::kSettingHeaderFooterFontSize));
|
| - gfx::RenderText* paint = render_text.get();
|
| -#else
|
| - SkPaint paint;
|
| - paint.setColor(SK_ColorBLACK);
|
| - paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
|
| - paint.setTextSize(SkDoubleToScalar(printing::kSettingHeaderFooterFontSize));
|
| - paint.setTypeface(SkTypeface::CreateFromName(
|
| - printing::kSettingHeaderFooterFontFamilyName, SkTypeface::kNormal));
|
| -#endif
|
| -
|
| - // Print the headers onto the |canvas| if there is enough space to print
|
| - // them.
|
| - string16 date;
|
| - string16 title;
|
| - if (!header_footer_info.GetString(printing::kSettingHeaderFooterTitle,
|
| - &title) ||
|
| - !header_footer_info.GetString(printing::kSettingHeaderFooterDate,
|
| - &date)) {
|
| - NOTREACHED();
|
| - }
|
| - string16 header_text = date + title;
|
| -
|
| - // Used for height calculations. Note that the width may be undefined.
|
| - SkRect header_vertical_bounds;
|
| -#if defined(USE_RENDER_TEXT)
|
| - paint->SetFontList(font_list);
|
| - paint->SetText(header_text);
|
| - {
|
| - gfx::Rect rect(gfx::Point(), paint->GetStringSize());
|
| - header_vertical_bounds = gfx::RectToSkRect(rect);
|
| - header_vertical_bounds.offset(0, -render_text->GetBaseline());
|
| - }
|
| -#else
|
| - paint.measureText(header_text.c_str(), header_text.length() * sizeof(char16),
|
| - &header_vertical_bounds, 0);
|
| -#endif
|
| -
|
| - double text_height = printing::kSettingHeaderFooterInterstice +
|
| - header_vertical_bounds.height();
|
| - if (text_height <= page_layout.margin_top) {
|
| - PrintHeaderFooterText(date, canvas, paint, webkit_scale_factor, page_layout,
|
| - printing::LEFT, printing::TOP,
|
| - header_vertical_bounds.top());
|
| - PrintHeaderFooterText(title, canvas, paint, webkit_scale_factor,
|
| - page_layout, printing::CENTER, printing::TOP,
|
| - header_vertical_bounds.top());
|
| - }
|
| + SkAutoCanvasRestore auto_restore(canvas, true);
|
| + canvas->scale(1 / webkit_scale_factor, 1 / webkit_scale_factor);
|
|
|
| - // Prints the footers onto the |canvas| if there is enough space to print
|
| - // them.
|
| - string16 page_of_total_pages = base::IntToString16(page_number) +
|
| - UTF8ToUTF16("/") +
|
| - base::IntToString16(total_pages);
|
| - string16 url;
|
| - if (!header_footer_info.GetString(printing::kSettingHeaderFooterURL, &url)) {
|
| - NOTREACHED();
|
| - }
|
| - string16 footer_text = page_of_total_pages + url;
|
| -
|
| - // Used for height calculations. Note that the width may be undefined.
|
| - SkRect footer_vertical_bounds;
|
| -#if defined(USE_RENDER_TEXT)
|
| - paint->SetFontList(font_list);
|
| - paint->SetText(footer_text);
|
| - {
|
| - gfx::Rect rect(gfx::Point(), paint->GetStringSize());
|
| - footer_vertical_bounds = gfx::RectToSkRect(rect);
|
| - footer_vertical_bounds.offset(0, -paint->GetBaseline());
|
| - }
|
| -#else
|
| - paint.measureText(footer_text.c_str(), footer_text.length() * sizeof(char16),
|
| - &footer_vertical_bounds, 0);
|
| -#endif
|
| -
|
| - text_height = printing::kSettingHeaderFooterInterstice +
|
| - footer_vertical_bounds.height();
|
| - if (text_height <= page_layout.margin_bottom) {
|
| - PrintHeaderFooterText(page_of_total_pages, canvas, paint,
|
| - webkit_scale_factor, page_layout, printing::RIGHT,
|
| - printing::BOTTOM, footer_vertical_bounds.bottom());
|
| - PrintHeaderFooterText(url, canvas, paint, webkit_scale_factor, page_layout,
|
| - printing::LEFT, printing::BOTTOM,
|
| - footer_vertical_bounds.bottom());
|
| - }
|
| + WebKit::WebSize page_size(page_layout.margin_left + page_layout.margin_right +
|
| + page_layout.content_width,
|
| + page_layout.margin_top + page_layout.margin_bottom +
|
| + page_layout.content_height);
|
| +
|
| + WebKit::WebView* web_view = WebKit::WebView::create(NULL);
|
| + web_view->settings()->setJavaScriptEnabled(true);
|
| + web_view->initializeMainFrame(NULL);
|
| +
|
| + WebKit::WebFrame* frame = web_view->mainFrame();
|
| +
|
| + base::StringValue html(
|
| + ResourceBundle::GetSharedInstance().GetLocalizedString(
|
| + IDR_PRINT_PREVIEW_PAGE));
|
| + // Load page with script to avoid async operations.
|
| + ExecuteScript(frame, kPageLoadScriptFormat, html);
|
| +
|
| + scoped_ptr<base::DictionaryValue> options(header_footer_info.DeepCopy());
|
| + options->SetDouble("width", page_size.width);
|
| + options->SetDouble("height", page_size.height);
|
| + options->SetDouble("topMargin", page_layout.margin_top);
|
| + options->SetDouble("bottomMargin", page_layout.margin_bottom);
|
| + options->SetString("pageNumber",
|
| + StringPrintf("%d/%d", page_number, total_pages));
|
| +
|
| + ExecuteScript(frame, kPageSetupScriptFormat, *options);
|
| +
|
| + WebKit::WebPrintParams webkit_params(page_size);
|
| + webkit_params.printerDPI = GetDPI(¶ms);
|
| +
|
| + frame->printBegin(webkit_params, WebKit::WebNode(), NULL);
|
| + frame->printPage(0, canvas);
|
| + frame->printEnd();
|
| +
|
| + web_view->close();
|
|
|
| device->setDrawingArea(SkPDFDevice::kContent_DrawingArea);
|
| }
|
|
|
| +// static - Not anonymous so that platform implementations can use it.
|
| +float PrintWebViewHelper::RenderPageContent(WebKit::WebFrame* frame,
|
| + int page_number,
|
| + const gfx::Rect& canvas_area,
|
| + const gfx::Rect& content_area,
|
| + double scale_factor,
|
| + WebKit::WebCanvas* canvas) {
|
| + SkAutoCanvasRestore auto_restore(canvas, true);
|
| + if (content_area != canvas_area) {
|
| + canvas->translate((content_area.x() - canvas_area.x()) / scale_factor,
|
| + (content_area.y() - canvas_area.y()) / scale_factor);
|
| + SkRect clip_rect(
|
| + SkRect::MakeXYWH(content_area.origin().x() / scale_factor,
|
| + content_area.origin().y() / scale_factor,
|
| + content_area.size().width() / scale_factor,
|
| + content_area.size().height() / scale_factor));
|
| + SkIRect clip_int_rect;
|
| + clip_rect.roundOut(&clip_int_rect);
|
| + SkRegion clip_region(clip_int_rect);
|
| + canvas->setClipRegion(clip_region);
|
| + }
|
| + return frame->printPage(page_number, canvas);
|
| +}
|
| +
|
| PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint(
|
| const PrintMsg_Print_Params& print_params,
|
| WebKit::WebFrame* frame,
|
|
|