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..f2d9dfa168e0267f967ac10a9431f57ab2ad9fcb 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, |
@@ -523,104 +407,71 @@ void PrintWebViewHelper::PrintHeaderAndFooter( |
const printing::PageSizeMargins& page_layout, |
const DictionaryValue& header_footer_info, |
const PrintMsg_Print_Params& params) { |
- skia::VectorPlatformDeviceSkia* device = |
- 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()); |
- } |
+ int dpi = GetDPI(¶ms); |
+ 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)); |
- // 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::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); |
- device->setDrawingArea(SkPDFDevice::kContent_DrawingArea); |
+ 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) |
Lei Zhang
2012/11/06 23:55:13
always true?
Vitaly Buka (NO REVIEWS)
2012/11/07 01:20:51
Done.
On 2012/11/06 23:55:13, Lei Zhang wrote:
|
+ web_view->close(); |
+} |
+ |
+// 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( |