summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/renderer')
-rw-r--r--chrome/renderer/mock_printer.cc92
-rw-r--r--chrome/renderer/mock_printer.h58
-rw-r--r--chrome/renderer/print_web_view_helper.cc166
-rw-r--r--chrome/renderer/print_web_view_helper.h22
-rw-r--r--chrome/renderer/print_web_view_helper_browsertest.cc1
-rw-r--r--chrome/renderer/print_web_view_helper_linux.cc8
-rw-r--r--chrome/renderer/print_web_view_helper_mac.mm14
-rw-r--r--chrome/renderer/print_web_view_helper_win.cc9
8 files changed, 364 insertions, 6 deletions
diff --git a/chrome/renderer/mock_printer.cc b/chrome/renderer/mock_printer.cc
index ac2c779..0f82115 100644
--- a/chrome/renderer/mock_printer.cc
+++ b/chrome/renderer/mock_printer.cc
@@ -4,14 +4,78 @@
#include "chrome/renderer/mock_printer.h"
+#include "base/basictypes.h"
#include "base/file_util.h"
#include "base/shared_memory.h"
+#include "base/string16.h"
+#include "base/utf_string_conversions.h"
#include "chrome/common/print_messages.h"
#include "ipc/ipc_message_utils.h"
#include "printing/metafile_impl.h"
#include "printing/units.h"
#include "testing/gtest/include/gtest/gtest.h"
+PrintMsg_Print_Params_Clone::PrintMsg_Print_Params_Clone()
+ : page_size_(),
+ printable_size_(),
+ margin_top_(0),
+ margin_left_(0),
+ dpi_(0),
+ min_shrink_(0),
+ max_shrink_(0),
+ desired_dpi_(0),
+ document_cookie_(0),
+ selection_only_(0),
+ supports_alpha_blend_(0),
+ preview_request_id_(0),
+ is_first_request_(0),
+ display_header_footer_(0),
+ date_(),
+ title_(),
+ url_() {
+}
+
+PrintMsg_Print_Params_Clone::~PrintMsg_Print_Params_Clone(){}
+
+void PrintMsg_Print_Params_Clone::ResetParams(PrintMsg_Print_Params* params) {
+ params->dpi = dpi_;
+ params->max_shrink = max_shrink_;
+ params->min_shrink = min_shrink_;
+ params->desired_dpi = desired_dpi_;
+ params->selection_only = selection_only_;
+ params->document_cookie = document_cookie_;
+ params->page_size = page_size_;
+ params->printable_size = printable_size_;
+ params->margin_left = margin_left_;
+ params->margin_top = margin_top_;
+ params->is_first_request = is_first_request_;
+ params->preview_request_id = preview_request_id_;
+ params->display_header_footer = display_header_footer_;
+ params->date = date_;
+ params->title = title_;
+ params->url = url_;
+
+ COMPILE_ASSERT(sizeof(PrintMsg_Print_Params_Clone) ==
+ sizeof(PrintMsg_Print_Params),
+ PrintMsg_Print_Params);
+}
+
+PrintMsg_PrintPages_Params_Clone::PrintMsg_PrintPages_Params_Clone()
+ : pages_(0) {
+}
+
+PrintMsg_PrintPages_Params_Clone::~PrintMsg_PrintPages_Params_Clone(){}
+
+void PrintMsg_PrintPages_Params_Clone::ResetParams(
+ PrintMsg_PrintPages_Params* params) {
+ params_.ResetParams(&params->params);
+ params->pages = pages_;
+
+ COMPILE_ASSERT(sizeof(PrintMsg_PrintPages_Params_Clone) ==
+ sizeof(PrintMsg_PrintPages_Params_Clone),
+ PrintMsg_PrintPages_Params);
+}
+
MockPrinterPage::MockPrinterPage(const void* source_data,
uint32 source_size,
const printing::Image& image)
@@ -37,7 +101,11 @@ MockPrinter::MockPrinter()
number_pages_(0),
page_number_(0),
is_first_request_(true),
- preview_request_id_(0) {
+ preview_request_id_(0),
+ display_header_footer_(false),
+ date_(ASCIIToUTF16("date")),
+ title_(ASCIIToUTF16("title")),
+ url_(ASCIIToUTF16("url")) {
page_size_.SetSize(static_cast<int>(8.5 * dpi_),
static_cast<int>(11.0 * dpi_));
printable_size_.SetSize(static_cast<int>((7.5 * dpi_)),
@@ -60,7 +128,8 @@ void MockPrinter::GetDefaultPrintSettings(PrintMsg_Print_Params* params) {
// Assign a unit document cookie and set the print settings.
document_cookie_ = CreateDocumentCookie();
- memset(params, 0, sizeof(PrintMsg_Print_Params));
+ PrintMsg_Print_Params_Clone params_clone;
+ params_clone.ResetParams(params);
SetPrintParams(params);
}
@@ -74,6 +143,10 @@ void MockPrinter::SetDefaultPrintSettings(const PrintMsg_Print_Params& params) {
printable_size_ = params.printable_size;
margin_left_ = params.margin_left;
margin_top_ = params.margin_top;
+ display_header_footer_ = params.display_header_footer;
+ date_ = params.date;
+ title_ = params.title;
+ url_ = params.url;
}
void MockPrinter::ScriptedPrint(int cookie,
@@ -83,7 +156,9 @@ void MockPrinter::ScriptedPrint(int cookie,
// Verify the input parameters.
EXPECT_EQ(document_cookie_, cookie);
- memset(settings, 0, sizeof(PrintMsg_PrintPages_Params));
+ PrintMsg_PrintPages_Params_Clone params_clone;
+ params_clone.ResetParams(settings);
+
settings->params.dpi = dpi_;
settings->params.max_shrink = max_shrink_;
settings->params.min_shrink = min_shrink_;
@@ -94,6 +169,10 @@ void MockPrinter::ScriptedPrint(int cookie,
settings->params.printable_size = printable_size_;
settings->params.is_first_request = is_first_request_;
settings->params.preview_request_id = preview_request_id_;
+ settings->params.display_header_footer = display_header_footer_;
+ settings->params.date = date_;
+ settings->params.title = title_;
+ settings->params.url = url_;
printer_status_ = PRINTER_PRINTING;
}
@@ -101,7 +180,8 @@ void MockPrinter::UpdateSettings(int cookie,
PrintMsg_PrintPages_Params* params) {
EXPECT_EQ(document_cookie_, cookie);
- memset(params, 0, sizeof(PrintMsg_PrintPages_Params));
+ PrintMsg_PrintPages_Params_Clone params_clone;
+ params_clone.ResetParams(params);
SetPrintParams(&(params->params));
printer_status_ = PRINTER_PRINTING;
}
@@ -236,4 +316,8 @@ void MockPrinter::SetPrintParams(PrintMsg_Print_Params* params) {
params->margin_top = margin_top_;
params->is_first_request = is_first_request_;
params->preview_request_id = preview_request_id_;
+ params->display_header_footer = display_header_footer_;
+ params->date = date_;
+ params->title = title_;
+ params->url = url_;
}
diff --git a/chrome/renderer/mock_printer.h b/chrome/renderer/mock_printer.h
index 0ae5687..326a50d 100644
--- a/chrome/renderer/mock_printer.h
+++ b/chrome/renderer/mock_printer.h
@@ -12,6 +12,7 @@
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/string16.h"
#include "printing/image.h"
#include "ui/gfx/size.h"
@@ -134,9 +135,66 @@ class MockPrinter {
bool is_first_request_;
int preview_request_id_;
+ // Used for displaying headers and footers.
+ bool display_header_footer_;
+ string16 date_;
+ string16 title_;
+ string16 url_;
+
std::vector<scoped_refptr<MockPrinterPage> > pages_;
DISALLOW_COPY_AND_ASSIGN(MockPrinter);
};
+// A clone of PrintMsg_Print_Params struct.
+class PrintMsg_Print_Params_Clone {
+ public:
+ PrintMsg_Print_Params_Clone();
+ ~PrintMsg_Print_Params_Clone();
+
+ // Resets the members of |params| to 0. Checks to see if
+ // PrintMsg_Print_Params and PrintMsg_Print_Params_Clone have identical
+ // member variables.
+ void ResetParams(PrintMsg_Print_Params* params);
+
+ private:
+ gfx::Size page_size_;
+ gfx::Size printable_size_;
+ int margin_top_;
+ int margin_left_;
+ double dpi_;
+ double min_shrink_;
+ double max_shrink_;
+ int desired_dpi_;
+ int document_cookie_;
+ bool selection_only_;
+ bool supports_alpha_blend_;
+ int preview_request_id_;
+ bool is_first_request_;
+ bool display_header_footer_;
+ string16 date_;
+ string16 title_;
+ string16 url_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrintMsg_Print_Params_Clone);
+};
+
+// A clone of PrintMsg_PrintPages_Params struct.
+class PrintMsg_PrintPages_Params_Clone {
+ public:
+ PrintMsg_PrintPages_Params_Clone();
+ ~PrintMsg_PrintPages_Params_Clone();
+
+ // Resets the members of |params| to 0. Checks to see if
+ // PrintMsg_PrintPages_Params and PrintMsg_PrintPages_Params_Clone have
+ // identical member variables.
+ void ResetParams(PrintMsg_PrintPages_Params* params);
+
+ private:
+ PrintMsg_Print_Params_Clone params_;
+ std::vector<int> pages_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrintMsg_PrintPages_Params_Clone);
+};
+
#endif // CHROME_RENDERER_MOCK_PRINTER_H_
diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc
index dbf1ca5..8d36b70 100644
--- a/chrome/renderer/print_web_view_helper.cc
+++ b/chrome/renderer/print_web_view_helper.cc
@@ -36,10 +36,19 @@
#include "content/common/view_messages.h"
#endif
+#if defined(USE_SKIA)
+#include "base/string_number_conversions.h"
+#include "skia/ext/vector_canvas.h"
+#include "skia/ext/vector_platform_device_skia.h"
+#include "third_party/skia/include/core/SkTypeface.h"
+#endif // defined(USE_SKIA)
+
+using base::Time;
using printing::ConvertPixelsToPoint;
using printing::ConvertPixelsToPointDouble;
using printing::ConvertUnit;
using printing::ConvertUnitDouble;
+using printing::GetHeaderFooterSegmentWidth;
using WebKit::WebConsoleMessage;
using WebKit::WebDocument;
using WebKit::WebElement;
@@ -87,6 +96,11 @@ 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 &&
+ oldParams.params.date == newParams.params.date &&
+ oldParams.params.title == newParams.params.title &&
+ oldParams.params.url == newParams.params.url &&
std::equal(oldParams.pages.begin(), oldParams.pages.end(),
newParams.pages.begin());
}
@@ -101,8 +115,147 @@ void CalculatePrintCanvasSize(const PrintMsg_Print_Params& print_params,
print_params.desired_dpi));
}
+#if defined(USE_SKIA)
+// 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,
+ skia::VectorCanvas* canvas,
+ SkPaint paint,
+ float webkit_scale_factor,
+ const PageSizeMargins& page_layout,
+ printing::HorizontalHeaderFooterPosition horizontal_position,
+ printing::VerticalHeaderFooterPosition vertical_position,
+ SkScalar offset_to_baseline) {
+ 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 = 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();
+ }
+
+ x = x / webkit_scale_factor;
+ y = y / webkit_scale_factor;
+ paint.setTextSize(paint.getTextSize() / webkit_scale_factor);
+ canvas->drawText(text.c_str(), text_byte_length, x, y, paint);
+}
+#endif // defined(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) {
+ static_cast<skia::VectorPlatformDeviceSkia*>(device)->setDrawingArea(
+ SkPDFDevice::kMargin_DrawingArea);
+
+ SkPaint paint;
+ paint.setColor(SK_ColorBLACK);
+ paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
+ paint.setTextSize(printing::kSettingHeaderFooterFontSize);
+ paint.setTypeface(SkTypeface::CreateFromName(
+ printing::kSettingHeaderFooterFontFamilyName, SkTypeface::kNormal));
+
+ // 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;
+
+ SkRect header_bounds;
+ 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) {
+ PrintHeaderFooterText(date, canvas, paint, webkit_scale_factor, page_layout,
+ printing::LEFT, printing::TOP, header_bounds.top());
+ PrintHeaderFooterText(title, canvas, paint, webkit_scale_factor,
+ page_layout, printing::CENTER, printing::TOP,
+ header_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;
+
+ SkRect footer_bounds;
+ 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) {
+ PrintHeaderFooterText(page_of_total_pages, canvas, paint,
+ webkit_scale_factor, page_layout, printing::RIGHT,
+ printing::BOTTOM, footer_bounds.bottom());
+ PrintHeaderFooterText(url, canvas, paint, webkit_scale_factor, page_layout,
+ printing::LEFT, printing::BOTTOM,
+ footer_bounds.bottom());
+ }
+
+ static_cast<skia::VectorPlatformDeviceSkia*>(device)->setDrawingArea(
+ SkPDFDevice::kContent_DrawingArea);
+}
+#endif // defined(USE_SKIA)
+
PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint(
const PrintMsg_Print_Params& print_params,
WebFrame* frame,
@@ -766,7 +919,7 @@ bool PrintWebViewHelper::UpdatePrintSettings(
PrintMsg_PrintPages_Params settings;
Send(new PrintHostMsg_UpdatePrintSettings(routing_id(),
- print_pages_params_->params.document_cookie, job_settings, &settings));
+ print_pages_params_->params.document_cookie, job_settings, &settings));
if (settings.params.dpi < kMinDpi || !settings.params.document_cookie)
return false;
@@ -780,6 +933,17 @@ bool PrintWebViewHelper::UpdatePrintSettings(
}
print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings));
+
+ if (print_pages_params_->params.display_header_footer) {
+ header_footer_info_.reset(new DictionaryValue());
+ header_footer_info_->SetString(printing::kSettingHeaderFooterDate,
+ print_pages_params_->params.date);
+ header_footer_info_->SetString(printing::kSettingHeaderFooterURL,
+ print_pages_params_->params.url);
+ header_footer_info_->SetString(printing::kSettingHeaderFooterTitle,
+ print_pages_params_->params.title);
+ }
+
Send(new PrintHostMsg_DidGetDocumentCookie(routing_id(),
settings.params.document_cookie));
return true;
diff --git a/chrome/renderer/print_web_view_helper.h b/chrome/renderer/print_web_view_helper.h
index 0407c85..cc04bd3 100644
--- a/chrome/renderer/print_web_view_helper.h
+++ b/chrome/renderer/print_web_view_helper.h
@@ -28,6 +28,11 @@ struct PrintMsg_PrintPages_Params;
namespace base {
class DictionaryValue;
}
+#if defined(USE_SKIA)
+namespace skia {
+class VectorCanvas;
+}
+#endif
// Class that calls the Begin and End print functions on the frame and changes
// the size of the view temporarily to support full page printing..
@@ -266,6 +271,19 @@ class PrintWebViewHelper : public RenderViewObserver,
PrepareFrameAndViewForPrint* prepare,
PrintMsg_Print_Params* params);
+#if defined(USE_SKIA)
+ // Given the |device| and |canvas| to draw on, prints the appropriate headers
+ // and footers using strings from |header_footer_info| on to the canvas.
+ static void PrintHeaderAndFooter(
+ SkDevice* device,
+ skia::VectorCanvas* canvas,
+ int page_number,
+ int total_pages,
+ float webkit_scale_factor,
+ const PageSizeMargins& page_layout_in_points,
+ const base::DictionaryValue& header_footer_info);
+#endif // defined(USE_SKIA)
+
bool GetPrintFrame(WebKit::WebFrame** frame);
// This reports the current time - |start_time| as the time to render a page.
@@ -309,6 +327,10 @@ class PrintWebViewHelper : public RenderViewObserver,
scoped_ptr<PrintMsg_PrintPages_Params> old_print_pages_params_;
+ // Strings generated by the browser process to be printed as headers and
+ // footers if requested by the user.
+ scoped_ptr<base::DictionaryValue> header_footer_info_;
+
// Keeps track of the state of print preview between messages.
class PrintPreviewContext {
public:
diff --git a/chrome/renderer/print_web_view_helper_browsertest.cc b/chrome/renderer/print_web_view_helper_browsertest.cc
index a4e9a59..fb29845 100644
--- a/chrome/renderer/print_web_view_helper_browsertest.cc
+++ b/chrome/renderer/print_web_view_helper_browsertest.cc
@@ -43,6 +43,7 @@ void CreatePrintSettingsDictionary(DictionaryValue* dict) {
dict->SetString(printing::kSettingDeviceName, "dummy");
dict->SetInteger(printing::kPreviewRequestID, 12345);
dict->SetBoolean(printing::kIsFirstRequest, true);
+ dict->SetBoolean(printing::kSettingHeaderFooterEnabled, false);
}
} // namespace
diff --git a/chrome/renderer/print_web_view_helper_linux.cc b/chrome/renderer/print_web_view_helper_linux.cc
index 0915681..c07f76b 100644
--- a/chrome/renderer/print_web_view_helper_linux.cc
+++ b/chrome/renderer/print_web_view_helper_linux.cc
@@ -209,7 +209,13 @@ void PrintWebViewHelper::PrintPageInternal(
printing::MetafileSkiaWrapper::SetMetafileOnCanvas(canvas.get(), metafile);
frame->printPage(params.page_number, canvas.get());
- // TODO(myhuang): We should render the header and the footer.
+ if (params.params.display_header_footer) {
+ // |page_number| is 0-based, so 1 is added.
+ // The scale factor on Linux is 1.
+ PrintHeaderAndFooter(device, canvas.get(), params.page_number + 1,
+ print_preview_context_.total_page_count(), 1,
+ page_layout_in_points, *header_footer_info_);
+ }
// Done printing. Close the device context to retrieve the compiled metafile.
if (!metafile->FinishPage())
diff --git a/chrome/renderer/print_web_view_helper_mac.mm b/chrome/renderer/print_web_view_helper_mac.mm
index 95ccb7e..b6d28cb 100644
--- a/chrome/renderer/print_web_view_helper_mac.mm
+++ b/chrome/renderer/print_web_view_helper_mac.mm
@@ -148,6 +148,20 @@ void PrintWebViewHelper::RenderPage(
CGContextRef canvasPtr = cgContext;
#endif
frame->printPage(page_number, canvasPtr);
+#if defined(USE_SKIA)
+ const PrintMsg_Print_Params& printParams =
+ print_preview_context_.print_params();
+ if (printParams.display_header_footer) {
+ PageSizeMargins page_layout_in_points;
+ GetPageSizeAndMarginsInPoints(frame, page_number, printParams,
+ &page_layout_in_points);
+ // |page_number| is 0-based, so 1 is added.
+ PrintHeaderAndFooter(device, canvas.get(), page_number + 1,
+ print_preview_context_.total_page_count(),
+ scale_factor, page_layout_in_points,
+ *header_footer_info_);
+ }
+#endif // defined(USE_SKIA)
}
// Done printing. Close the device context to retrieve the compiled metafile.
diff --git a/chrome/renderer/print_web_view_helper_win.cc b/chrome/renderer/print_web_view_helper_win.cc
index b43c22f..cb70e43 100644
--- a/chrome/renderer/print_web_view_helper_win.cc
+++ b/chrome/renderer/print_web_view_helper_win.cc
@@ -187,6 +187,15 @@ Metafile* PrintWebViewHelper::RenderPage(
printing::MetafileSkiaWrapper::SetMetafileOnCanvas(canvas.get(), metafile);
float webkit_scale_factor = frame->printPage(page_number, canvas.get());
+
+ if (params.display_header_footer) {
+ // |page_number| is 0-based, so 1 is added.
+ PrintHeaderAndFooter(device, canvas.get(), page_number + 1,
+ print_preview_context_.total_page_count(),
+ webkit_scale_factor, page_layout_in_points,
+ *header_footer_info_);
+ }
+
if (*scale_factor <= 0 || webkit_scale_factor <= 0) {
NOTREACHED() << "Printing page " << page_number << " failed.";
} else {