diff options
author | sverrir@chromium.org <sverrir@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-16 17:23:58 +0000 |
---|---|---|
committer | sverrir@chromium.org <sverrir@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-16 17:23:58 +0000 |
commit | aa82249f5670f88c545039f7ae997643c97fd639 (patch) | |
tree | 11ea4e90843eb246e77813ddac68b30bf4d907b0 /chrome/renderer | |
parent | 538173f8209bd078cb82627e32b06ae522766072 (diff) | |
download | chromium_src-aa82249f5670f88c545039f7ae997643c97fd639.zip chromium_src-aa82249f5670f88c545039f7ae997643c97fd639.tar.gz chromium_src-aa82249f5670f88c545039f7ae997643c97fd639.tar.bz2 |
Print only the focused frame. This makes more sense than trying to print all frames since most of the time you end up with ugly clipping and scroll bars on the printed page.
This also fixes printing issue with print selection since we don't pick up the currently selected text if's not in the main frame.
Also did some refactoring of the printing test in render_view_unittest. Mainly to reuse the new Image class.
BUG=http://crbug.com/15250
TEST=Print pages with frames. Print selection when using multiple frames (one example in bug).
Review URL: http://codereview.chromium.org/149644
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20876 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/mock_printer.cc | 57 | ||||
-rw-r--r-- | chrome/renderer/mock_printer.h | 56 | ||||
-rw-r--r-- | chrome/renderer/mock_printer_driver_win.cc | 125 | ||||
-rw-r--r-- | chrome/renderer/mock_printer_driver_win.h | 25 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 16 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 1 | ||||
-rw-r--r-- | chrome/renderer/render_view_unittest.cc | 50 |
7 files changed, 89 insertions, 241 deletions
diff --git a/chrome/renderer/mock_printer.cc b/chrome/renderer/mock_printer.cc index 2454a0c..4462ce7 100644 --- a/chrome/renderer/mock_printer.cc +++ b/chrome/renderer/mock_printer.cc @@ -5,9 +5,7 @@ #include "chrome/renderer/mock_printer.h" #include "base/file_util.h" -#include "base/gfx/png_encoder.h" #include "base/logging.h" -#include "base/md5.h" #include "base/shared_memory.h" #include "chrome/common/ipc_message_utils.h" #include "chrome/common/render_messages.h" @@ -116,8 +114,12 @@ void MockPrinter::PrintPage(const ViewHostMsg_DidPrintPage_Params& params) { base::SharedMemory emf_data(params.metafile_data_handle, true, GetCurrentProcess()); emf_data.Map(params.data_size); - MockPrinterPage* page_data = driver_.LoadSource(emf_data.memory(), - params.data_size); + printing::NativeMetafile metafile; + metafile.CreateFromData(emf_data.memory(), params.data_size); + printing::Image image(metafile); + MockPrinterPage* page_data = new MockPrinterPage(emf_data.memory(), + params.data_size, + image); if (!page_data) { printer_status_ = PRINTER_ERROR; return; @@ -140,6 +142,13 @@ int MockPrinter::GetPrintedPages() const { return page_number_; } +const MockPrinterPage* MockPrinter::GetPrintedPage(size_t pageno) const { + if (pages_.size() > pageno) + return pages_[pageno]; + else + return NULL; +} + int MockPrinter::GetWidth(size_t page) const { if (printer_status_ != PRINTER_READY || page >= pages_.size()) return -1; @@ -152,27 +161,10 @@ int MockPrinter::GetHeight(size_t page) const { return pages_[page]->height(); } -bool MockPrinter::GetSourceChecksum(size_t page, std::string* checksum) const { - if (printer_status_ != PRINTER_READY || page >= pages_.size()) - return false; - return GetChecksum(pages_[page]->source_data(), pages_[page]->source_size(), - checksum); -} - bool MockPrinter::GetBitmapChecksum(size_t page, std::string* checksum) const { if (printer_status_ != PRINTER_READY || page >= pages_.size()) return false; - return GetChecksum(pages_[page]->bitmap_data(), pages_[page]->bitmap_size(), - checksum); -} - -bool MockPrinter::GetBitmap(size_t page, - const void** data, - size_t* size) const { - if (printer_status_ != PRINTER_READY || page >= pages_.size()) - return false; - *data = pages_[page]->bitmap_data(); - *size = pages_[page]->bitmap_size(); + *checksum = pages_[page]->image().checksum(); return true; } @@ -191,17 +183,8 @@ bool MockPrinter::SaveBitmap(size_t page, const std::wstring& filename) const { if (printer_status_ != PRINTER_READY || page >= pages_.size()) return false; - int width = pages_[page]->width(); - int height = pages_[page]->height(); - int row_byte_width = width * 4; - const uint8* bitmap_data = pages_[page]->bitmap_data(); - std::vector<unsigned char> compressed; - PNGEncoder::Encode(bitmap_data, - PNGEncoder::FORMAT_BGRA, width, height, - row_byte_width, true, &compressed); - file_util::WriteFile(filename, - reinterpret_cast<char*>(&*compressed.begin()), - compressed.size()); + + pages_[page]->image().SaveToPng(filename); return true; } @@ -209,11 +192,3 @@ int MockPrinter::CreateDocumentCookie() { return ++current_document_cookie_; } -bool MockPrinter::GetChecksum(const void* data, - size_t size, - std::string* checksum) const { - MD5Digest digest; - MD5Sum(data, size, &digest); - checksum->assign(HexEncode(&digest, sizeof(digest))); - return true; -} diff --git a/chrome/renderer/mock_printer.h b/chrome/renderer/mock_printer.h index 16577cb..ba3f0de 100644 --- a/chrome/renderer/mock_printer.h +++ b/chrome/renderer/mock_printer.h @@ -11,10 +11,7 @@ #include "base/basictypes.h" #include "base/ref_counted.h" #include "base/scoped_ptr.h" - -#if defined(OS_WIN) -#include "chrome/renderer/mock_printer_driver_win.h" -#endif +#include "printing/image.h" struct ViewMsg_Print_Params; struct ViewMsg_PrintPages_Params; @@ -26,49 +23,30 @@ struct ViewHostMsg_DidPrintPage_Params; // a smart pointer of this object (i.e. scoped_refptr<>). class MockPrinterPage : public base::RefCounted<MockPrinterPage> { public: - MockPrinterPage() - : width_(0), - height_(0), - source_size_(0), - bitmap_size_(0) { - } - - MockPrinterPage(int width, - int height, - const void* source_data, + MockPrinterPage(const void* source_data, size_t source_size, - const void* bitmap_data, - size_t bitmap_size) - : width_(width), - height_(height), - source_size_(source_size), - bitmap_size_(bitmap_size) { - // Create copies of the source data and the bitmap data. + 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); - bitmap_data_.reset(new uint8[bitmap_size]); - if (bitmap_data_.get()) - memcpy(bitmap_data_.get(), bitmap_data, bitmap_size); } ~MockPrinterPage() { } - int width() { return width_; } - int height() { return height_; } - const uint8* source_data() { return source_data_.get(); } - const size_t source_size() { return source_size_; } - const uint8* bitmap_data() { return bitmap_data_.get(); } - const size_t bitmap_size() { return bitmap_size_; } + int width() const { return image_.size().width(); } + int height() const { return image_.size().height(); } + const uint8* source_data() const { return source_data_.get(); } + const size_t source_size() const { return source_size_; } + const printing::Image& image() const { return image_; } private: - int width_; - int height_; size_t source_size_; scoped_array<uint8> source_data_; - size_t bitmap_size_; - scoped_array<uint8> bitmap_data_; + printing::Image image_; DISALLOW_COPY_AND_ASSIGN(MockPrinterPage); }; @@ -108,9 +86,13 @@ class MockPrinter { // Functions that retrieve the output pages. Status GetPrinterStatus() const { return printer_status_; } int GetPrintedPages() const; + + // Get a pointer to the printed page, returns NULL if pageno has not been + // printed. The pointer is for read only view and should not be deleted. + const MockPrinterPage* GetPrintedPage(size_t pageno) const; + int GetWidth(size_t page) const; int GetHeight(size_t page) const; - bool GetSourceChecksum(size_t page, std::string* checksum) const; bool GetBitmapChecksum(size_t page, std::string* checksum) const; bool GetSource(size_t page, const void** data, size_t* size) const; bool GetBitmap(size_t page, const void** data, size_t* size) const; @@ -149,10 +131,6 @@ class MockPrinter { int page_number_; std::vector<scoped_refptr<MockPrinterPage> > pages_; -#if defined(OS_WIN) - MockPrinterDriverWin driver_; -#endif - DISALLOW_COPY_AND_ASSIGN(MockPrinter); }; diff --git a/chrome/renderer/mock_printer_driver_win.cc b/chrome/renderer/mock_printer_driver_win.cc deleted file mode 100644 index 8fefd8e..0000000 --- a/chrome/renderer/mock_printer_driver_win.cc +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2009 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_driver_win.h" - -#include "base/gfx/gdi_util.h" -#include "base/logging.h" -#include "printing/emf_win.h" -#include "chrome/renderer/mock_printer.h" -#include "skia/ext/platform_device.h" - -namespace { - -// A simple class which temporarily overrides system settings. -// The bitmap image rendered via the PlayEnhMetaFile() function depends on -// some system settings. -// As a workaround for such dependency, this class saves the system settings -// and changes them. This class also restore the saved settings in its -// destructor. -class SystemSettingsOverride { - public: - SystemSettingsOverride() : font_smoothing_(0) { - } - - ~SystemSettingsOverride() { - SystemParametersInfo(SPI_SETFONTSMOOTHING, font_smoothing_, NULL, 0); - } - - BOOL Init(BOOL font_smoothing) { - if (!SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &font_smoothing_, 0)) - return FALSE; - return SystemParametersInfo(SPI_SETFONTSMOOTHING, font_smoothing, NULL, 0); - } - - private: - BOOL font_smoothing_; -}; - -// A class which renders an EMF data and returns a raw bitmap data. -// The bitmap data returned from Create() is deleted in the destructor of this -// class. So, we need to create a copy of this bitmap data if it is used after -// this object is deleted, -class EmfRenderer { - public: - EmfRenderer() : dc_(NULL), bitmap_(NULL) { - } - - ~EmfRenderer() { - if (bitmap_) { - DeleteObject(bitmap_); - bitmap_ = NULL; - } - if (dc_) { - DeleteDC(dc_); - dc_ = NULL; - } - } - - const void* Create(int width, int height, const printing::Emf* emf) { - CHECK(!dc_ && !bitmap_); - - BITMAPV4HEADER header; - gfx::CreateBitmapV4Header(width, height, &header); - - dc_ = CreateCompatibleDC(NULL); - if (!dc_) - return NULL; - - void* bits; - bitmap_ = CreateDIBSection(dc_, reinterpret_cast<BITMAPINFO*>(&header), 0, - &bits, NULL, 0); - if (!bitmap_ || !bits) - return NULL; - - SelectObject(dc_, bitmap_); - - skia::PlatformDevice::InitializeDC(dc_); - emf->Playback(dc_, NULL); - - return reinterpret_cast<uint8*>(bits); - } - - private: - HDC dc_; - HBITMAP bitmap_; -}; - -} // namespace - -MockPrinterDriverWin::MockPrinterDriverWin() { -} - -MockPrinterDriverWin::~MockPrinterDriverWin() { -} - -MockPrinterPage* MockPrinterDriverWin::LoadSource(const void* source_data, - size_t source_size) { - // This code is mostly copied from the Image::LoadEMF() function in - // "src/chrome/browser/printing/printing_layout_uitest.cc". - printing::Emf emf; - emf.CreateFromData(source_data, source_size); - gfx::Rect rect(emf.GetBounds()); - - // Create a temporary DC and bitmap to retrieve the renderered data. - if (rect.width() <= 0 || rect.height() <= 0) - return NULL; - - // Disable the font-smoothing feature of Windows. - SystemSettingsOverride system_settings; - system_settings.Init(FALSE); - - // Render the EMF data and create a bitmap. - EmfRenderer renderer; - const void* bitmap_data = renderer.Create(rect.width(), rect.height(), &emf); - if (!bitmap_data) - return NULL; - - // Create a new MockPrinterPage instance and return it. - size_t row_byte_width = rect.width() * 4; - size_t bitmap_size = row_byte_width * rect.height(); - return new MockPrinterPage(rect.width(), rect.height(), - source_data, source_size, - bitmap_data, bitmap_size); -} diff --git a/chrome/renderer/mock_printer_driver_win.h b/chrome/renderer/mock_printer_driver_win.h deleted file mode 100644 index 117aa16..0000000 --- a/chrome/renderer/mock_printer_driver_win.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2009 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 CHROME_RENDERER_MOCK_PRINTER_DRIVER_WIN_H_ -#define CHROME_RENDERER_MOCK_PRINTER_DRIVER_WIN_H_ - -#include "base/basictypes.h" - -class MockPrinterPage; - -// Implements the platform-dependent part of a pseudo printer object. -// This class renders a platform-dependent input and creates a MockPrinterPage -// instance. -class MockPrinterDriverWin { - public: - MockPrinterDriverWin(); - ~MockPrinterDriverWin(); - - MockPrinterPage* LoadSource(const void* data, size_t size); - - DISALLOW_COPY_AND_ASSIGN(MockPrinterDriverWin); -}; - -#endif // CHROME_RENDERER_MOCK_PRINTER_DRIVER_WIN_H_ diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 96cf524a..9967ca9 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -451,8 +451,14 @@ void RenderView::SendThumbnail() { void RenderView::OnPrintPages() { DCHECK(webview()); - if (webview()) - Print(webview()->GetMainFrame(), false); + if (webview()) { + // If the user has selected text in the currently focused frame we print + // only that frame (this makes print selection work for multiple frames). + if (webview()->GetFocusedFrame()->HasSelection()) + Print(webview()->GetFocusedFrame(), false); + else + Print(webview()->GetMainFrame(), false); + } } void RenderView::OnPrintingDone(int document_cookie, bool success) { @@ -2309,7 +2315,11 @@ void RenderView::SetInputMethodState(bool enabled) { } void RenderView::ScriptedPrint(WebFrame* frame) { - Print(frame, true); + DCHECK(webview()); + if (webview()) { + // Print the full page - not just the frame the javascript is running from. + Print(webview()->GetMainFrame(), true); + } } void RenderView::UserMetricsRecordAction(const std::wstring& action) { diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index c8afcd2..4310d47 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -390,6 +390,7 @@ class RenderView : public RenderWidget, FRIEND_TEST(RenderViewTest, ImeComposition); FRIEND_TEST(RenderViewTest, OnSetTextDirection); FRIEND_TEST(RenderViewTest, OnPrintPages); + FRIEND_TEST(RenderViewTest, PrintWithIframe); FRIEND_TEST(RenderViewTest, PrintLayoutTest); FRIEND_TEST(RenderViewTest, OnHandleKeyboardEvent); FRIEND_TEST(RenderViewTest, InsertCharacters); diff --git a/chrome/renderer/render_view_unittest.cc b/chrome/renderer/render_view_unittest.cc index 4b4ed60..135c78d 100644 --- a/chrome/renderer/render_view_unittest.cc +++ b/chrome/renderer/render_view_unittest.cc @@ -3,10 +3,13 @@ // found in the LICENSE file. #include "base/file_util.h" +#include "base/shared_memory.h" #include "chrome/common/native_web_keyboard_event.h" #include "chrome/common/render_messages.h" #include "chrome/test/render_view_test.h" #include "net/base/net_errors.h" +#include "printing/image.h" +#include "printing/native_metafile.h" #include "testing/gtest/include/gtest/gtest.h" #include "webkit/api/public/WebURLError.h" @@ -363,6 +366,45 @@ TEST_F(RenderViewTest, PrintWithJavascript) { #endif } +TEST_F(RenderViewTest, PrintWithIframe) { +#if defined(OS_WIN) + // Document that populates an iframe.. + const char html[] = + "<html><body>Lorem Ipsum:" + "<iframe name=\"sub1\" id=\"sub1\"></iframe><script>" + " document.write(frames['sub1'].name);" + " frames['sub1'].document.write(" + " '<p>Cras tempus ante eu felis semper luctus!</p>');" + "</script></body></html>"; + + LoadHTML(html); + + // Find the frame and set it as the focused one. This should mean that that + // the printout should only contain the contents of that frame. + WebFrame* sub1_frame = view_->webview()->GetFrameWithName(L"sub1"); + ASSERT_TRUE(sub1_frame); + view_->webview()->SetFocusedFrame(sub1_frame); + ASSERT_NE(view_->webview()->GetFocusedFrame(), + view_->webview()->GetMainFrame()); + + // Initiate printing. + view_->OnPrintPages(); + + // Verify output through MockPrinter. + const MockPrinter* printer(render_thread_.printer()); + ASSERT_EQ(1, printer->GetPrintedPages()); + const printing::Image& image1(printer->GetPrintedPage(0)->image()); + + // TODO(sverrir): Figure out a way to improve this test to actually print + // only the content of the iframe. Currently image1 will contain the full + // page. + EXPECT_NE(0, image1.size().width()); + EXPECT_NE(0, image1.size().height()); +#else + NOTIMPLEMENTED(); +#endif +} + // Tests if we can print a page and verify its results. // This test prints HTML pages into a pseudo printer and check their outputs, // i.e. a simplified version of the PrintingLayoutTextTest UI test. @@ -431,14 +473,6 @@ TEST_F(RenderViewTest, PrintLayoutTest) { if (kTestPages[i].checksum) EXPECT_EQ(kTestPages[i].checksum, bitmap_actual); - // Retrieve the bitmap data from the pseudo printer. - // TODO(hbono): implement a function which retrieves an expected result - // from a file and compares it with this bitmap data. - const void* bitmap_data; - size_t bitmap_size; - EXPECT_TRUE(render_thread_.printer()->GetBitmap(0, &bitmap_data, - &bitmap_size)); - if (baseline) { // Save the source data and the bitmap data into temporary files to // create base-line results. |