diff options
author | aayushkumar@chromium.org <aayushkumar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-17 23:09:36 +0000 |
---|---|---|
committer | aayushkumar@chromium.org <aayushkumar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-17 23:09:36 +0000 |
commit | 55b23a0e5ac8b7e29ba56892d302286856b7f98a (patch) | |
tree | a8eafe6383ba93551cf8ca4bbd262ab2cee3c7cc | |
parent | 4e8e0d15fcc521d60b489dd829084c0507ec57bc (diff) | |
download | chromium_src-55b23a0e5ac8b7e29ba56892d302286856b7f98a.zip chromium_src-55b23a0e5ac8b7e29ba56892d302286856b7f98a.tar.gz chromium_src-55b23a0e5ac8b7e29ba56892d302286856b7f98a.tar.bz2 |
Added Header and Footer support in Linux, Windows and Mac for Skia
BUG=67514
TEST=
In the preview tab, note added options for printing headers and footers. Toggle with the checkbox and ensure that the correct headers and footers are displayed.
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=97219
Review URL: http://codereview.chromium.org/7348010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97233 0039d316-1c4b-4281-b951-d872f2087c98
36 files changed, 738 insertions, 20 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index b3e2b87..2e26ef0 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -5994,6 +5994,12 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_PRINT_PREVIEW_PRINT_PAGES_LABEL" desc="ARIA label used by screen reader to explain the purpose of the page selection textbox"> Print Specific Pages </message> + <message name="IDS_PRINT_PREVIEW_OPTIONS_LABEL" desc="Options label currently providing the choice to print headers and footers."> + Options + </message> + <message name="IDS_PRINT_PREVIEW_OPTION_HEADER_FOOTER" desc="Checkbox label that provides a choice to print the headers and footers."> + Headers and footers + </message> <!-- Load State --> <message name="IDS_LOAD_STATE_WAITING_FOR_DELEGATE"> diff --git a/chrome/browser/printing/printing_message_filter.cc b/chrome/browser/printing/printing_message_filter.cc index f74fdc0..3a1df0a 100644 --- a/chrome/browser/printing/printing_message_filter.cc +++ b/chrome/browser/printing/printing_message_filter.cc @@ -56,6 +56,13 @@ void RenderParamsFromPrintSettings(const printing::PrintSettings& settings, params->document_cookie = 0; params->selection_only = settings.selection_only; params->supports_alpha_blend = settings.supports_alpha_blend(); + + params->display_header_footer = settings.display_header_footer; + if (!settings.display_header_footer) + return; + params->date = settings.date; + params->title = settings.title; + params->url = settings.url; } } // namespace diff --git a/chrome/browser/resources/print_preview/header_footer_settings.html b/chrome/browser/resources/print_preview/header_footer_settings.html new file mode 100644 index 0000000..66c8a57 --- /dev/null +++ b/chrome/browser/resources/print_preview/header_footer_settings.html @@ -0,0 +1,7 @@ +<div id="header-footer-option" class="two-column option visible"> + <h1 i18n-content="optionsLabel"></h1> + <div> + <input id="header-footer" type="checkbox" checked> + <label for="header-footer" i18n-content="optionHeaderFooter"></label> + </div> +</div> diff --git a/chrome/browser/resources/print_preview/header_footer_settings.js b/chrome/browser/resources/print_preview/header_footer_settings.js new file mode 100644 index 0000000..80ac094 --- /dev/null +++ b/chrome/browser/resources/print_preview/header_footer_settings.js @@ -0,0 +1,68 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +cr.define('print_preview', function() { + 'use strict'; + + /** + * Creates a HeaderFooterSettings object. This object encapsulates all + * settings and logic related to the headers and footers checkbox. + * @constructor + */ + function HeaderFooterSettings() { + this.headerFooterOption_ = $('header-footer-option'); + this.headerFooterCheckbox_ = $('header-footer'); + } + + cr.addSingletonGetter(HeaderFooterSettings); + + HeaderFooterSettings.prototype = { + /** + * The checkbox corresponding to the headers and footers option. + * @type {HTMLInputElement} + */ + get headerFooterCheckbox() { + return this.headerFooterCheckbox_; + }, + + /** + * Checks whether the Headers and Footers checkbox is checked or not. + * @return {boolean} true if Headers and Footers are checked. + */ + hasHeaderFooter: function() { + return this.headerFooterCheckbox_.checked; + }, + + /** + * Adding listeners to header footer related controls. + */ + addEventListeners: function() { + this.headerFooterCheckbox_.onclick = + this.onHeaderFooterChanged_.bind(this); + document.addEventListener('PDFLoaded', this.onPDFLoaded_.bind(this)); + }, + + /** + * Listener executing when the user selects or de-selects the headers + * and footers option. + * @private + */ + onHeaderFooterChanged_: function() { + requestPrintPreview(); + }, + + /** + * Listener executing when a PDFLoaded event occurs. + * @private + */ + onPDFLoaded_: function() { + if (!previewModifiable) + fadeOutElement(this.headerFooterOption_); + }, + }; + + return { + HeaderFooterSettings: HeaderFooterSettings, + }; +}); diff --git a/chrome/browser/resources/print_preview/print_preview.css b/chrome/browser/resources/print_preview/print_preview.css index 96a0776..61a9915 100644 --- a/chrome/browser/resources/print_preview/print_preview.css +++ b/chrome/browser/resources/print_preview/print_preview.css @@ -346,6 +346,14 @@ html[os=mac] input[type='checkbox']:checked::before { top: 2px; } +html[os=mac] #options-horizontal-separator { + display: none; +} + +html[os=mac] #options-option { + display: none; +} + input[type='radio'] { -webkit-box-shadow: inset 0 1px 2px white, 0 1px 2px rgba(0, 0, 0, .2); diff --git a/chrome/browser/resources/print_preview/print_preview.html b/chrome/browser/resources/print_preview/print_preview.html index fde7e79..d29ebc5 100644 --- a/chrome/browser/resources/print_preview/print_preview.html +++ b/chrome/browser/resources/print_preview/print_preview.html @@ -39,6 +39,8 @@ <hr> <include src="color_settings.html"></include> <hr> + <include src="header_footer_settings.html"></include> + <hr id="options-horizontal-separator"> <div id="system-dialog-div"> <button id="system-dialog-link" class="link-button" i18n-content="systemDialogOption"></button> diff --git a/chrome/browser/resources/print_preview/print_preview.js b/chrome/browser/resources/print_preview/print_preview.js index 4beefe5..f262ba4 100644 --- a/chrome/browser/resources/print_preview/print_preview.js +++ b/chrome/browser/resources/print_preview/print_preview.js @@ -51,6 +51,9 @@ var copiesSettings; // Object holding all the layout related settings. var layoutSettings; +// Object holding all the header footer related settings. +var headerFooterSettings; + // Object holding all the color related settings. var colorSettings; @@ -104,10 +107,12 @@ function onLoad() { pageSettings = print_preview.PageSettings.getInstance(); copiesSettings = print_preview.CopiesSettings.getInstance(); layoutSettings = print_preview.LayoutSettings.getInstance(); + headerFooterSettings = print_preview.HeaderFooterSettings.getInstance(); colorSettings = print_preview.ColorSettings.getInstance(); printHeader.addEventListeners(); pageSettings.addEventListeners(); copiesSettings.addEventListeners(); + headerFooterSettings.addEventListeners(); layoutSettings.addEventListeners(); colorSettings.addEventListeners(); $('printer-list').onchange = updateControlsWithSelectedPrinterCapabilities; @@ -311,6 +316,7 @@ function getSettings() { 'color': colorSettings.isColor(), 'printToPDF': printToPDF, 'isFirstRequest' : false, + 'headerFooterEnabled': headerFooterSettings.hasHeaderFooter(), 'requestID': -1}; var printerList = $('printer-list'); @@ -957,5 +963,6 @@ function setDefaultValuesAndRegeneratePreview() { <include src="print_header.js"/> <include src="page_settings.js"/> <include src="copies_settings.js"/> +<include src="header_footer_settings.js"/> <include src="layout_settings.js"/> <include src="color_settings.js"/> diff --git a/chrome/browser/ui/webui/print_preview_data_source.cc b/chrome/browser/ui/webui/print_preview_data_source.cc index bc4d694..084f904 100644 --- a/chrome/browser/ui/webui/print_preview_data_source.cc +++ b/chrome/browser/ui/webui/print_preview_data_source.cc @@ -95,6 +95,9 @@ PrintPreviewDataSource::PrintPreviewDataSource() AddLocalizedString("incrementTitle", IDS_PRINT_PREVIEW_INCREMENT_TITLE); AddLocalizedString("decrementTitle", IDS_PRINT_PREVIEW_DECREMENT_TITLE); AddLocalizedString("printPagesLabel", IDS_PRINT_PREVIEW_PRINT_PAGES_LABEL); + AddLocalizedString("optionsLabel", IDS_PRINT_PREVIEW_OPTIONS_LABEL); + AddLocalizedString("optionHeaderFooter", + IDS_PRINT_PREVIEW_OPTION_HEADER_FOOTER); set_json_path("strings.js"); add_resource_path("print_preview.js", IDR_PRINT_PREVIEW_JS); diff --git a/chrome/browser/ui/webui/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview_handler.cc index 3aae34e..d904c18 100644 --- a/chrome/browser/ui/webui/print_preview_handler.cc +++ b/chrome/browser/ui/webui/print_preview_handler.cc @@ -493,6 +493,24 @@ void PrintPreviewHandler::HandleGetPreview(const ListValue* args) { print_preview_ui->OnPrintPreviewFailed(); return; } + + // Retrieve the page title and url and send it to the renderer process if + // headers and footers are to be displayed. + bool display_header_footer = false; + if (!settings->GetBoolean(printing::kSettingHeaderFooterEnabled, + &display_header_footer)) { + NOTREACHED(); + } + if (display_header_footer) { + settings->SetString(printing::kSettingHeaderFooterTitle, + initiator_tab->GetTitle()); + std::string url; + NavigationEntry* entry = initiator_tab->controller().GetActiveEntry(); + if (entry) + url = entry->virtual_url().spec(); + settings->SetString(printing::kSettingHeaderFooterURL, url); + } + VLOG(1) << "Print preview request start"; RenderViewHost* rvh = initiator_tab->render_view_host(); rvh->Send(new PrintMsg_PrintPreview(rvh->routing_id(), *settings)); @@ -522,6 +540,8 @@ void PrintPreviewHandler::HandlePrint(const ListValue* args) { bool print_to_pdf = false; settings->GetBoolean(printing::kSettingPrintToPDF, &print_to_pdf); + settings->SetBoolean(printing::kSettingHeaderFooterEnabled, false); + TabContentsWrapper* preview_tab_wrapper = TabContentsWrapper::GetCurrentWrapperForContents(preview_tab()); diff --git a/chrome/common/print_messages.h b/chrome/common/print_messages.h index 3644428..8f3d950 100644 --- a/chrome/common/print_messages.h +++ b/chrome/common/print_messages.h @@ -54,6 +54,18 @@ IPC_STRUCT_BEGIN(PrintMsg_Print_Params) // True if this is the first preview request, used only for print preview. IPC_STRUCT_MEMBER(bool, is_first_request) + + // Specifies if the header and footer should be rendered. + IPC_STRUCT_MEMBER(bool, display_header_footer) + + // Date string to be printed as header if requested by the user. + IPC_STRUCT_MEMBER(string16, date) + + // Title string to be printed as header if requested by the user. + IPC_STRUCT_MEMBER(string16, title) + + // URL string to be printed as footer if requested by the user. + IPC_STRUCT_MEMBER(string16, url) IPC_STRUCT_END() IPC_STRUCT_BEGIN(PrintMsg_PrintPage_Params) 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(¶ms->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 { diff --git a/printing/print_job_constants.cc b/printing/print_job_constants.cc index e5c67ec..436d656 100644 --- a/printing/print_job_constants.cc +++ b/printing/print_job_constants.cc @@ -30,6 +30,37 @@ const char kSettingDeviceName[] = "deviceName"; // Print job duplex mode. const char kSettingDuplexMode[] = "duplex"; +// Option to print headers and Footers: true if selected, false if not. +const char kSettingHeaderFooterEnabled[] = "headerFooterEnabled"; + +// Default font family name for printing the headers and footers. +const char kSettingHeaderFooterFontFamilyName[] = "sans"; + +// Default font name for printing the headers and footers. +const char kSettingHeaderFooterFontName[] = "Helvetica"; + +// Default font size for printing the headers and footers. +const int kSettingHeaderFooterFontSize = 8; + +// Number of horizontal regions for headers and footers. +const float kSettingHeaderFooterHorizontalRegions = 3; + +// Interstice or gap between different header footer components. +// Hardcoded to 0.25cm = 1/10" = 7.2points. +const float kSettingHeaderFooterInterstice = 7.2f; + +// Key that specifies the date of the page that will be printed in the headers +// and footers. +const char kSettingHeaderFooterDate[] = "date"; + +// Key that specifies the title of the page that will be printed in the headers +// and footers. +const char kSettingHeaderFooterTitle[] = "title"; + +// Key that specifies the URL of the page that will be printed in the headers +// and footers. +const char kSettingHeaderFooterURL[] = "url"; + // Page orientation: true for landscape, false for portrait. const char kSettingLandscape[] = "landscape"; diff --git a/printing/print_job_constants.h b/printing/print_job_constants.h index 1997673..89a6e64 100644 --- a/printing/print_job_constants.h +++ b/printing/print_job_constants.h @@ -15,6 +15,15 @@ extern const char kSettingColor[]; extern const char kSettingCopies[]; extern const char kSettingDeviceName[]; extern const char kSettingDuplexMode[]; +extern const char kSettingHeaderFooterEnabled[]; +extern const char kSettingHeaderFooterFontFamilyName[]; +extern const char kSettingHeaderFooterFontName[]; +extern const int kSettingHeaderFooterFontSize; +extern const float kSettingHeaderFooterHorizontalRegions; +extern const float kSettingHeaderFooterInterstice; +extern const char kSettingHeaderFooterDate[]; +extern const char kSettingHeaderFooterTitle[]; +extern const char kSettingHeaderFooterURL[]; extern const char kSettingLandscape[]; extern const char kSettingPageRange[]; extern const char kSettingPageRangeFrom[]; @@ -33,6 +42,19 @@ enum DuplexMode { SHORT_EDGE, }; +// Specifies the horizontal alignment of the headers and footers. +enum HorizontalHeaderFooterPosition { + LEFT, + CENTER, + RIGHT +}; + +// Specifies the vertical alignment of the Headers and Footers. +enum VerticalHeaderFooterPosition { + TOP, + BOTTOM +}; + } // namespace printing #endif // PRINTING_PRINT_JOB_CONSTANTS_H_ diff --git a/printing/print_settings.h b/printing/print_settings.h index ee78556..8fea6dd 100644 --- a/printing/print_settings.h +++ b/printing/print_settings.h @@ -7,6 +7,8 @@ #include <string> +#include "base/memory/scoped_ptr.h" +#include "base/string16.h" #include "printing/page_range.h" #include "printing/page_setup.h" #include "ui/gfx/rect.h" @@ -95,6 +97,14 @@ class PrintSettings { // Updates the orientation and flip the page if needed. void SetOrientation(bool landscape); + // Strings to be printed as headers and footers if requested by the user. + string16 date; + string16 title; + string16 url; + + // True if the user wants headers and footers to be displayed. + bool display_header_footer; + private: ////////////////////////////////////////////////////////////////////////////// // Settings that can't be changed without side-effects. diff --git a/printing/print_settings_initializer.cc b/printing/print_settings_initializer.cc new file mode 100644 index 0000000..82d6955 --- /dev/null +++ b/printing/print_settings_initializer.cc @@ -0,0 +1,72 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "printing/print_settings_initializer.h" + +#include <algorithm> +#include <cmath> + +#include "base/i18n/time_formatting.h" +#include "base/string_number_conversions.h" +#include "base/time.h" +#include "base/utf_string_conversions.h" +#include "base/values.h" +#include "googleurl/src/gurl.h" +#include "printing/print_job_constants.h" +#include "printing/print_settings.h" +#include "printing/units.h" +#include "ui/base/text/text_elider.h" + +using base::DictionaryValue; +using base::Time; +using printing::ConvertPointsToPixelDouble; +using printing::ConvertUnitDouble; +using printing::GetHeaderFooterSegmentWidth; + +namespace printing { + +void PrintSettingsInitializer::InitHeaderFooterStrings( + const DictionaryValue& job_settings, + PrintSettings* print_settings) { + if (!job_settings.GetBoolean(printing::kSettingHeaderFooterEnabled, + &print_settings->display_header_footer)) { + NOTREACHED(); + } + if (!print_settings->display_header_footer) + return; + + string16 date = base::TimeFormatShortDateNumeric(Time::Now()); + string16 title; + std::string url; + if (!job_settings.GetString(printing::kSettingHeaderFooterTitle, &title) || + !job_settings.GetString(printing::kSettingHeaderFooterURL, &url)) { + NOTREACHED(); + } + + gfx::Font font(UTF8ToUTF16(printing::kSettingHeaderFooterFontName), + ceil(ConvertPointsToPixelDouble( + printing::kSettingHeaderFooterFontSize))); + double segment_width = GetHeaderFooterSegmentWidth(ConvertUnitDouble( + print_settings->page_setup_device_units().physical_size().width(), + print_settings->device_units_per_inch(), + printing::kPixelsPerInch)); + date = ui::ElideText(date, font, segment_width, false); + print_settings->date = date; + + // Calculate the available title width. If the date string is not long + // enough, increase the available space for the title. + // Assumes there is no header text to RIGHT of title. + double date_width = font.GetStringWidth(date); + double max_title_width = std::min(2 * segment_width, + 2 * (segment_width - date_width) + + segment_width); + print_settings->title = ui::ElideText(title, font, max_title_width, false); + + double max_url_width = 2 * segment_width; + GURL gurl(url); + print_settings->url = ui::ElideUrl(gurl, font, max_url_width, std::string()); +} + +} // namespace printing + diff --git a/printing/print_settings_initializer.h b/printing/print_settings_initializer.h new file mode 100644 index 0000000..de2e3cd --- /dev/null +++ b/printing/print_settings_initializer.h @@ -0,0 +1,34 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PRINTING_PRINT_SETTINGS_INITIALIZER_H_ +#define PRINTING_PRINT_SETTINGS_INITIALIZER_H_ + +#include "base/basictypes.h" +#include "base/logging.h" + +namespace base { +class DictionaryValue; +} + +namespace printing { + +class PrintSettings; + +// Initializes the header footer strings in the PrintSettings object from the +// provided |job_settings|. +class PrintSettingsInitializer { + public: + static void InitHeaderFooterStrings( + const base::DictionaryValue& job_settings, + PrintSettings* print_settings); + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(PrintSettingsInitializer); +}; + +} // namespace printing + +#endif // PRINTING_PRINT_SETTINGS_INITIALIZER_H_ + diff --git a/printing/printing.gyp b/printing/printing.gyp index eacf333..4f5483f 100644 --- a/printing/printing.gyp +++ b/printing/printing.gyp @@ -73,6 +73,8 @@ 'print_job_constants.h', 'print_settings.cc', 'print_settings.h', + 'print_settings_initializer.cc', + 'print_settings_initializer.h', 'print_settings_initializer_gtk.cc', 'print_settings_initializer_gtk.h', 'print_settings_initializer_mac.cc', diff --git a/printing/printing_context.cc b/printing/printing_context.cc index fb554e7..4e9d03a 100644 --- a/printing/printing_context.cc +++ b/printing/printing_context.cc @@ -5,6 +5,7 @@ #include "printing/printing_context.h" #include "base/values.h" +#include "printing/print_settings_initializer.h" namespace printing { @@ -33,4 +34,13 @@ PrintingContext::Result PrintingContext::OnError() { return abort_printing_ ? CANCEL : FAILED; } +PrintingContext::Result PrintingContext::UpdatePrintSettings( + const base::DictionaryValue& job_settings, + const PageRanges& ranges) { + PrintingContext::Result result = UpdatePrinterSettings(job_settings, ranges); + printing::PrintSettingsInitializer::InitHeaderFooterStrings(job_settings, + &settings_); + return result; +} + } // namespace printing diff --git a/printing/printing_context.h b/printing/printing_context.h index dd7e058..c7184e7 100644 --- a/printing/printing_context.h +++ b/printing/printing_context.h @@ -51,10 +51,16 @@ class PrintingContext { // default device settings. virtual Result UseDefaultSettings() = 0; - // Updates print settings. |job_settings| contains all print job settings - // information. |ranges| has the new page range settings. - virtual Result UpdatePrintSettings(const base::DictionaryValue& job_settings, - const PageRanges& ranges) = 0; + // Updates printer related settings. |job_settings| contains all print job + // settings information. |ranges| has the new page range settings. + virtual Result UpdatePrinterSettings( + const base::DictionaryValue& job_settings, + const PageRanges& ranges) = 0; + + // Updates Print Settings. |job_settings| contains all print job + // settings information. |ranges| has the new page range settings. + Result UpdatePrintSettings(const base::DictionaryValue& job_settings, + const PageRanges& ranges); // Initializes with predefined settings. virtual Result InitWithSettings(const PrintSettings& settings) = 0; diff --git a/printing/printing_context_cairo.cc b/printing/printing_context_cairo.cc index 3da44a1..16eb837 100644 --- a/printing/printing_context_cairo.cc +++ b/printing/printing_context_cairo.cc @@ -140,7 +140,7 @@ PrintingContext::Result PrintingContextCairo::UseDefaultSettings() { return OK; } -PrintingContext::Result PrintingContextCairo::UpdatePrintSettings( +PrintingContext::Result PrintingContextCairo::UpdatePrinterSettings( const DictionaryValue& job_settings, const PageRanges& ranges) { #if defined(OS_CHROMEOS) bool landscape = false; diff --git a/printing/printing_context_cairo.h b/printing/printing_context_cairo.h index 49d72b5..20c3b8c 100644 --- a/printing/printing_context_cairo.h +++ b/printing/printing_context_cairo.h @@ -39,8 +39,9 @@ class PrintingContextCairo : public PrintingContext { bool has_selection, PrintSettingsCallback* callback); virtual Result UseDefaultSettings(); - virtual Result UpdatePrintSettings(const base::DictionaryValue& job_settings, - const PageRanges& ranges); + virtual Result UpdatePrinterSettings( + const base::DictionaryValue& job_settings, + const PageRanges& ranges); virtual Result InitWithSettings(const PrintSettings& settings); virtual Result NewDocument(const string16& document_name); virtual Result NewPage(); diff --git a/printing/printing_context_mac.h b/printing/printing_context_mac.h index cb3e0e2..655ef6a 100644 --- a/printing/printing_context_mac.h +++ b/printing/printing_context_mac.h @@ -30,8 +30,9 @@ class PrintingContextMac : public PrintingContext { bool has_selection, PrintSettingsCallback* callback); virtual Result UseDefaultSettings(); - virtual Result UpdatePrintSettings(const base::DictionaryValue& job_settings, - const PageRanges& ranges); + virtual Result UpdatePrinterSettings( + const base::DictionaryValue& job_settings, + const PageRanges& ranges); virtual Result InitWithSettings(const PrintSettings& settings); virtual Result NewDocument(const string16& document_name); virtual Result NewPage(); diff --git a/printing/printing_context_mac.mm b/printing/printing_context_mac.mm index 90654e2..f839802 100644 --- a/printing/printing_context_mac.mm +++ b/printing/printing_context_mac.mm @@ -98,7 +98,7 @@ PrintingContext::Result PrintingContextMac::UseDefaultSettings() { return OK; } -PrintingContext::Result PrintingContextMac::UpdatePrintSettings( +PrintingContext::Result PrintingContextMac::UpdatePrinterSettings( const DictionaryValue& job_settings, const PageRanges& ranges) { DCHECK(!in_print_job_); diff --git a/printing/printing_context_win.cc b/printing/printing_context_win.cc index 17e5890..ef45060 100644 --- a/printing/printing_context_win.cc +++ b/printing/printing_context_win.cc @@ -302,7 +302,7 @@ PrintingContext::Result PrintingContextWin::UseDefaultSettings() { return FAILED; } -PrintingContext::Result PrintingContextWin::UpdatePrintSettings( +PrintingContext::Result PrintingContextWin::UpdatePrinterSettings( const DictionaryValue& job_settings, const PageRanges& ranges) { DCHECK(!in_print_job_); diff --git a/printing/printing_context_win.h b/printing/printing_context_win.h index 81a61c3..c830736 100644 --- a/printing/printing_context_win.h +++ b/printing/printing_context_win.h @@ -28,8 +28,9 @@ class PrintingContextWin : public PrintingContext { bool has_selection, PrintSettingsCallback* callback); virtual Result UseDefaultSettings(); - virtual Result UpdatePrintSettings(const base::DictionaryValue& job_settings, - const PageRanges& ranges); + virtual Result UpdatePrinterSettings( + const base::DictionaryValue& job_settings, + const PageRanges& ranges); virtual Result InitWithSettings(const PrintSettings& settings); virtual Result NewDocument(const string16& document_name); virtual Result NewPage(); diff --git a/printing/units.cc b/printing/units.cc index 976fa80..84d78bb 100644 --- a/printing/units.cc +++ b/printing/units.cc @@ -5,6 +5,7 @@ #include "printing/units.h" #include "base/logging.h" +#include "printing/print_job_constants.h" namespace printing { @@ -47,4 +48,18 @@ double ConvertPixelsToPointDouble(double pixels) { return ConvertUnitDouble(pixels, kPixelsPerInch, kPointsPerInch); } +double ConvertPointsToPixelDouble(double points) { + return ConvertUnitDouble(points, kPointsPerInch, kPixelsPerInch); +} + +double GetHeaderFooterSegmentWidth(double page_width) { + // Interstice is left at both ends of the page as well as between + // each region, so 1 is added. + double total_interstice_width = + (printing::kSettingHeaderFooterHorizontalRegions + 1) * + printing::kSettingHeaderFooterInterstice; + return (page_width - total_interstice_width) / + printing::kSettingHeaderFooterHorizontalRegions; +} + } // namespace printing diff --git a/printing/units.h b/printing/units.h index cc61241..bd6d67a 100644 --- a/printing/units.h +++ b/printing/units.h @@ -36,6 +36,13 @@ int ConvertPixelsToPoint(int pixels); // Converts from 1 pixel to 1 point using doubles. double ConvertPixelsToPointDouble(double pixels); +// Converts from 1 point to 1 pixel using doubles. +double ConvertPointsToPixelDouble(double points); + +// Splits the horizontal width equally into segments with an interstice +// between each segment. Returns the width of a segment. +double GetHeaderFooterSegmentWidth(double page_width); + } // namespace printing #endif // PRINTING_UNITS_H_ diff --git a/skia/ext/vector_platform_device_skia.cc b/skia/ext/vector_platform_device_skia.cc index bda7a60..0971d1a 100644 --- a/skia/ext/vector_platform_device_skia.cc +++ b/skia/ext/vector_platform_device_skia.cc @@ -193,6 +193,10 @@ void VectorPlatformDeviceSkia::drawDevice(const SkDraw& draw, pdf_device_->drawDevice(draw, real_device, x, y, paint); } +void VectorPlatformDeviceSkia::setDrawingArea(SkPDFDevice::DrawingArea area) { + pdf_device_->setDrawingArea(area); +} + #if defined(OS_WIN) void VectorPlatformDeviceSkia::DrawToNativeContext(HDC dc, int x, diff --git a/skia/ext/vector_platform_device_skia.h b/skia/ext/vector_platform_device_skia.h index 7aaa2a2..238996b 100644 --- a/skia/ext/vector_platform_device_skia.h +++ b/skia/ext/vector_platform_device_skia.h @@ -79,8 +79,12 @@ class VectorPlatformDeviceSkia : public PlatformDevice { virtual void drawDevice(const SkDraw& draw, SkDevice*, int x, int y, const SkPaint&); + // Sets the drawing area for the device. Subsequent draw calls are + // directed to the specific drawing area (margin or content area). + SK_API void setDrawingArea(SkPDFDevice::DrawingArea area); + protected: - virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config, int width, + virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config, int width, int height, bool isOpaque, Usage usage); |