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

Unified Diff: chrome/renderer/print_web_view_helper.cc

Issue 11359020: Print headers and footers with WebKit. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 1 month 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 side-by-side diff with in-line comments
Download patch
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 b33808822271e6649e0ed28bd5db581c3d488144..8ca786bd366da38aa6df6223518fb7c5cc8f348b 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
+namespace {
-#if defined(OS_WIN) || defined(OS_MACOSX)
-#define USE_RENDER_TEXT
-#endif
+const double kMinDpi = 1.0;
-#if defined(USE_RENDER_TEXT)
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/render_text.h"
-#endif
+const char kPageLoadScriptFormat[] =
+ "document.open(); document.write(%s); document.close();";
-namespace {
+const char kPageSetupScriptFormat[] = "setup(%s);";
-#if defined(USE_RENDER_TEXT)
-typedef gfx::RenderText* HeaderFooterPaint;
-#else
-typedef SkPaint HeaderFooterPaint;
-#endif
-
-const double kMinDpi = 1.0;
+void ExecuteScript(WebKit::WebFrame* frame,
+ const char* script_format,
+ const base::Value& parameters) {
+ std::string json;
+ base::JSONWriter::Write(&parameters, &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.
msw 2012/11/02 19:09:50 Please make sure to close/update this bug.
- 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,98 +411,47 @@ 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.
msw 2012/11/02 19:09:50 Please make sure to close/update this bug.
- // 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());
- }
-
- // 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());
- }
+ int dpi = GetDPI(&params);
+ using printing::ConvertUnit;
+ WebKit::WebSize page_size(
+ ConvertUnit(params.page_size.width(), dpi, params.desired_dpi),
+ ConvertUnit(params.page_size.height(), dpi, params.desired_dpi));
+
+ 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 / webkit_scale_factor);
+ options->SetDouble("height", page_size.height / webkit_scale_factor);
+ options->SetDouble("topMargin", page_layout.margin_top / webkit_scale_factor);
+ options->SetDouble("bottomMargin",
+ page_layout.margin_bottom / webkit_scale_factor);
+ options->SetDouble(
+ "fontSize", printing::kSettingHeaderFooterFontSize / webkit_scale_factor);
+ options->SetString("pageNumber",
+ StringPrintf("%d/%d", page_number, total_pages));
+
+ ExecuteScript(frame, kPageSetupScriptFormat, *options);
+
+ SkAutoCanvasRestore auto_restore(canvas, true);
+ WebKit::WebPrintParams webkit_params(page_size);
+ webkit_params.printerDPI = dpi;
+
+ frame->printBegin(webkit_params, WebKit::WebNode(), NULL);
+ frame->printPage(0, canvas);
+ frame->printEnd();
+
+ if (web_view)
+ web_view->close();
device->setDrawingArea(SkPDFDevice::kContent_DrawingArea);
}

Powered by Google App Engine
This is Rietveld 408576698