// Copyright (c) 2012 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 "chrome/renderer/mock_printer.h" #include "base/basictypes.h" #include "base/file_util.h" #include "base/memory/shared_memory.h" #include "base/strings/string16.h" #include "base/strings/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" #if defined(OS_MACOSX) #include "printing/pdf_metafile_cg_mac.h" #endif namespace { void UpdateMargins(int margins_type, int dpi, PrintMsg_Print_Params* params) { if (margins_type == printing::NO_MARGINS) { params->content_size.SetSize(static_cast<int>((8.5 * dpi)), static_cast<int>((11.0 * dpi))); params->margin_left = 0; params->margin_top = 0; } else if (margins_type == printing::PRINTABLE_AREA_MARGINS) { params->content_size.SetSize(static_cast<int>((8.0 * dpi)), static_cast<int>((10.5 * dpi))); params->margin_left = static_cast<int>(0.25 * dpi); params->margin_top = static_cast<int>(0.25 * dpi); } else if (margins_type == printing::CUSTOM_MARGINS) { params->content_size.SetSize(static_cast<int>((7.9 * dpi)), static_cast<int>((10.4 * dpi))); params->margin_left = static_cast<int>(0.30 * dpi); params->margin_top = static_cast<int>(0.30 * dpi); } } } // namespace MockPrinterPage::MockPrinterPage(const void* source_data, uint32 source_size, const printing::Image& image) : source_size_(source_size), image_(image) { // Create copies of the source data source_data_.reset(new uint8[source_size]); if (source_data_.get()) memcpy(source_data_.get(), source_data, source_size); } MockPrinterPage::~MockPrinterPage() {} MockPrinter::MockPrinter() : dpi_(printing::kPointsPerInch), max_shrink_(2.0), min_shrink_(1.25), desired_dpi_(printing::kPointsPerInch), selection_only_(false), should_print_backgrounds_(false), document_cookie_(-1), current_document_cookie_(0), printer_status_(PRINTER_READY), number_pages_(0), page_number_(0), is_first_request_(true), print_to_pdf_(false), preview_request_id_(0), print_scaling_option_(blink::WebPrintScalingOptionSourceSize), display_header_footer_(false), title_(ASCIIToUTF16("title")), url_(ASCIIToUTF16("url")), use_invalid_settings_(false) { page_size_.SetSize(static_cast<int>(8.5 * dpi_), static_cast<int>(11.0 * dpi_)); content_size_.SetSize(static_cast<int>((7.5 * dpi_)), static_cast<int>((10.0 * dpi_))); margin_left_ = margin_top_ = static_cast<int>(0.5 * dpi_); printable_area_.SetRect(static_cast<int>(0.25 * dpi_), static_cast<int>(0.25 *dpi_), static_cast<int>(8 * dpi_), static_cast<int>(10.5 * dpi_)); } MockPrinter::~MockPrinter() { } void MockPrinter::ResetPrinter() { printer_status_ = PRINTER_READY; document_cookie_ = -1; } void MockPrinter::GetDefaultPrintSettings(PrintMsg_Print_Params* params) { // Verify this printer is not processing a job. // Sorry, this mock printer is very fragile. EXPECT_EQ(-1, document_cookie_); // Assign a unit document cookie and set the print settings. document_cookie_ = CreateDocumentCookie(); params->Reset(); SetPrintParams(params); } void MockPrinter::SetDefaultPrintSettings(const PrintMsg_Print_Params& params) { dpi_ = params.dpi; max_shrink_ = params.max_shrink; min_shrink_ = params.min_shrink; desired_dpi_ = params.desired_dpi; selection_only_ = params.selection_only; should_print_backgrounds_ = params.should_print_backgrounds; page_size_ = params.page_size; content_size_ = params.content_size; printable_area_ = params.printable_area; margin_left_ = params.margin_left; margin_top_ = params.margin_top; display_header_footer_ = params.display_header_footer; title_ = params.title; url_ = params.url; } void MockPrinter::UseInvalidSettings() { use_invalid_settings_ = true; PrintMsg_Print_Params empty_param; SetDefaultPrintSettings(empty_param); } void MockPrinter::UseInvalidPageSize() { page_size_.SetSize(0, 0); } void MockPrinter::UseInvalidContentSize() { content_size_.SetSize(0, 0); } void MockPrinter::ScriptedPrint(int cookie, int expected_pages_count, bool has_selection, PrintMsg_PrintPages_Params* settings) { // Verify the input parameters. EXPECT_EQ(document_cookie_, cookie); settings->Reset(); settings->params.dpi = dpi_; settings->params.max_shrink = max_shrink_; settings->params.min_shrink = min_shrink_; settings->params.desired_dpi = desired_dpi_; settings->params.selection_only = selection_only_; settings->params.should_print_backgrounds = should_print_backgrounds_; settings->params.document_cookie = document_cookie_; settings->params.page_size = page_size_; settings->params.content_size = content_size_; settings->params.printable_area = printable_area_; settings->params.is_first_request = is_first_request_; settings->params.print_scaling_option = print_scaling_option_; settings->params.print_to_pdf = print_to_pdf_; settings->params.preview_request_id = preview_request_id_; settings->params.display_header_footer = display_header_footer_; settings->params.title = title_; settings->params.url = url_; printer_status_ = PRINTER_PRINTING; } void MockPrinter::UpdateSettings(int cookie, PrintMsg_PrintPages_Params* params, const std::vector<int>& pages, int margins_type) { if (document_cookie_ == -1) { document_cookie_ = CreateDocumentCookie(); } params->Reset(); params->pages = pages; SetPrintParams(&(params->params)); UpdateMargins(margins_type, dpi_, &(params->params)); printer_status_ = PRINTER_PRINTING; } void MockPrinter::SetPrintedPagesCount(int cookie, int number_pages) { // Verify the input parameter and update the printer status so that the // RenderViewTest class can verify the this function finishes without errors. EXPECT_EQ(document_cookie_, cookie); EXPECT_EQ(PRINTER_PRINTING, printer_status_); EXPECT_EQ(0, number_pages_); EXPECT_EQ(0, page_number_); // Initialize the job status. number_pages_ = number_pages; page_number_ = 0; pages_.clear(); } void MockPrinter::PrintPage(const PrintHostMsg_DidPrintPage_Params& params) { // Verify the input parameter and update the printer status so that the // RenderViewTest class can verify the this function finishes without errors. EXPECT_EQ(PRINTER_PRINTING, printer_status_); EXPECT_EQ(document_cookie_, params.document_cookie); EXPECT_EQ(page_number_, params.page_number); EXPECT_LE(params.page_number, number_pages_); #if defined(OS_WIN) || defined(OS_MACOSX) // Load the data sent from a RenderView object and create a PageData object. // We duplicate the given file handle when creating a base::SharedMemory // instance so that its destructor closes the copy. EXPECT_GT(params.data_size, 0U); #if defined(OS_WIN) base::SharedMemory metafile_data(params.metafile_data_handle, true, GetCurrentProcess()); #elif defined(OS_MACOSX) base::SharedMemory metafile_data(params.metafile_data_handle, true); #endif metafile_data.Map(params.data_size); #if defined(OS_MACOSX) printing::PdfMetafileCg metafile; #else printing::NativeMetafile metafile; #endif metafile.InitFromData(metafile_data.memory(), params.data_size); printing::Image image(metafile); MockPrinterPage* page_data = new MockPrinterPage(metafile_data.memory(), params.data_size, image); scoped_refptr<MockPrinterPage> page(page_data); pages_.push_back(page); #endif // We finish printing a printing job. // Reset the job status and the printer status. ++page_number_; if (number_pages_ == page_number_) ResetPrinter(); } int MockPrinter::GetPrintedPages() const { if (printer_status_ != PRINTER_READY) return -1; return page_number_; } const MockPrinterPage* MockPrinter::GetPrintedPage(unsigned int pageno) const { if (pages_.size() > pageno) return pages_[pageno].get(); else return NULL; } int MockPrinter::GetWidth(unsigned int page) const { if (printer_status_ != PRINTER_READY || page >= pages_.size()) return -1; return pages_[page]->width(); } int MockPrinter::GetHeight(unsigned int page) const { if (printer_status_ != PRINTER_READY || page >= pages_.size()) return -1; return pages_[page]->height(); } bool MockPrinter::GetBitmapChecksum( unsigned int page, std::string* checksum) const { if (printer_status_ != PRINTER_READY || page >= pages_.size()) return false; *checksum = pages_[page]->image().checksum(); return true; } bool MockPrinter::SaveSource( unsigned int page, const base::FilePath& filepath) const { if (printer_status_ != PRINTER_READY || page >= pages_.size()) return false; const uint8* source_data = pages_[page]->source_data(); uint32 source_size = pages_[page]->source_size(); file_util::WriteFile(filepath, reinterpret_cast<const char*>(source_data), source_size); return true; } bool MockPrinter::SaveBitmap( unsigned int page, const base::FilePath& filepath) const { if (printer_status_ != PRINTER_READY || page >= pages_.size()) return false; pages_[page]->image().SaveToPng(filepath); return true; } int MockPrinter::CreateDocumentCookie() { return use_invalid_settings_ ? 0 : ++current_document_cookie_; } void MockPrinter::SetPrintParams(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->should_print_backgrounds = should_print_backgrounds_; params->document_cookie = document_cookie_; params->page_size = page_size_; params->content_size = content_size_; params->printable_area = printable_area_; params->margin_left = margin_left_; params->margin_top = margin_top_; params->is_first_request = is_first_request_; params->print_scaling_option = print_scaling_option_; params->print_to_pdf = print_to_pdf_; params->preview_request_id = preview_request_id_; params->display_header_footer = display_header_footer_; params->title = title_; params->url = url_; }