diff options
-rw-r--r-- | chrome/chrome.gyp | 2 | ||||
-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 | ||||
-rw-r--r-- | printing/image.cc | 134 | ||||
-rw-r--r-- | printing/image.h | 24 |
10 files changed, 216 insertions, 274 deletions
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index e78c383..e76e2f3 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -3221,8 +3221,6 @@ 'renderer/mock_keyboard_driver_win.h', 'renderer/mock_printer.cc', 'renderer/mock_printer.h', - 'renderer/mock_printer_driver_win.cc', - 'renderer/mock_printer_driver_win.h', 'renderer/mock_render_process.h', 'renderer/mock_render_thread.cc', 'renderer/mock_render_thread.h', 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. diff --git a/printing/image.cc b/printing/image.cc index 8f397d8..667adae 100644 --- a/printing/image.cc +++ b/printing/image.cc @@ -8,15 +8,59 @@ #include "base/gfx/png_decoder.h" #include "base/gfx/png_encoder.h" #include "base/gfx/rect.h" +#include "base/md5.h" #include "base/string_util.h" -#include "printing/native_metafile.h" #include "skia/ext/platform_device.h" #if defined(OS_WIN) #include "base/gfx/gdi_util.h" // EMF support #endif -printing::Image::Image(const std::wstring& filename) : ignore_alpha_(true) { +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 DisableFontSmoothing { + public: + explicit DisableFontSmoothing(bool disable) : enable_again_(false) { + if (disable) { +#if defined(OS_WIN) + BOOL enabled; + if (SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &enabled, 0) && + enabled) { + if (SystemParametersInfo(SPI_SETFONTSMOOTHING, FALSE, NULL, 0)) + enable_again_ = true; + } +#endif + } + } + + ~DisableFontSmoothing() { + if (enable_again_) { +#if defined(OS_WIN) + BOOL result = SystemParametersInfo(SPI_SETFONTSMOOTHING, TRUE, NULL, 0); + DCHECK(result); +#endif + } + } + + private: + bool enable_again_; + + DISALLOW_EVIL_CONSTRUCTORS(DisableFontSmoothing); +}; + +} // namespace + +namespace printing { + +Image::Image(const std::wstring& filename) + : row_length_(0), + ignore_alpha_(true) { std::string data; file_util::ReadFileToString(filename, &data); std::wstring ext = file_util::GetFileExtensionFromPath(filename); @@ -35,7 +79,26 @@ printing::Image::Image(const std::wstring& filename) : ignore_alpha_(true) { } } -bool printing::Image::SaveToPng(const std::wstring& filename) { +Image::Image(const NativeMetafile& metafile) + : row_length_(0), + ignore_alpha_(true) { + LoadMetafile(metafile); +} + +Image::Image(const Image& image) + : size_(image.size_), + row_length_(image.row_length_), + data_(image.data_), + ignore_alpha_(image.ignore_alpha_) { +} + +std::string Image::checksum() const { + MD5Digest digest; + MD5Sum(&data_[0], data_.size(), &digest); + return HexEncode(&digest, sizeof(digest)); +} + +bool Image::SaveToPng(const std::wstring& filename) const { DCHECK(!data_.empty()); std::vector<unsigned char> compressed; bool success = PNGEncoder::Encode(&*data_.begin(), @@ -56,7 +119,7 @@ bool printing::Image::SaveToPng(const std::wstring& filename) { return success; } -double printing::Image::PercentageDifferent(const Image& rhs) const { +double Image::PercentageDifferent(const Image& rhs) const { if (size_.width() == 0 || size_.height() == 0 || rhs.size_.width() == 0 || rhs.size_.height() == 0) return 100.; @@ -113,7 +176,7 @@ double printing::Image::PercentageDifferent(const Image& rhs) const { return static_cast<double>(pixels_different) / total_pixels * 100.; } -bool printing::Image::LoadPng(const std::string& compressed) { +bool Image::LoadPng(const std::string& compressed) { int w; int h; bool success = PNGDecoder::Decode( @@ -124,39 +187,54 @@ bool printing::Image::LoadPng(const std::string& compressed) { return success; } -bool printing::Image::LoadMetafile(const std::string& data) { +bool Image::LoadMetafile(const std::string& data) { DCHECK(!data.empty()); #if defined(OS_WIN) - printing::NativeMetafile metafile; + NativeMetafile metafile; metafile.CreateFromData(data.data(), data.size()); + return LoadMetafile(metafile); +#else + NOTIMPLEMENTED(); + return false; +#endif +} + +bool Image::LoadMetafile(const NativeMetafile& metafile) { +#if defined(OS_WIN) gfx::Rect rect(metafile.GetBounds()); + DisableFontSmoothing disable_in_this_scope(true); // Create a temporary HDC and bitmap to retrieve the rendered data. HDC hdc = CreateCompatibleDC(NULL); BITMAPV4HEADER hdr; DCHECK_EQ(rect.x(), 0); DCHECK_EQ(rect.y(), 0); - DCHECK_GT(rect.width(), 0); - DCHECK_GT(rect.height(), 0); - size_ = rect.size(); - gfx::CreateBitmapV4Header(rect.width(), rect.height(), &hdr); - void* bits; - HBITMAP bitmap = CreateDIBSection(hdc, - reinterpret_cast<BITMAPINFO*>(&hdr), 0, - &bits, NULL, 0); - DCHECK(bitmap); - DCHECK(SelectObject(hdc, bitmap)); - skia::PlatformDevice::InitializeDC(hdc); - bool success = metafile.Playback(hdc, NULL); - row_length_ = size_.width() * sizeof(uint32); - size_t bytes = row_length_ * size_.height(); - DCHECK(bytes); - data_.resize(bytes); - memcpy(&*data_.begin(), bits, bytes); - DeleteDC(hdc); - DeleteObject(bitmap); - return success; + DCHECK_GE(rect.width(), 0); // Metafile could be empty. + DCHECK_GE(rect.height(), 0); + if (rect.width() > 0 && rect.height() > 0) { + size_ = rect.size(); + gfx::CreateBitmapV4Header(rect.width(), rect.height(), &hdr); + void* bits; + HBITMAP bitmap = CreateDIBSection(hdc, + reinterpret_cast<BITMAPINFO*>(&hdr), 0, + &bits, NULL, 0); + DCHECK(bitmap); + DCHECK(SelectObject(hdc, bitmap)); + skia::PlatformDevice::InitializeDC(hdc); + bool success = metafile.Playback(hdc, NULL); + row_length_ = size_.width() * sizeof(uint32); + size_t bytes = row_length_ * size_.height(); + DCHECK(bytes); + data_.resize(bytes); + memcpy(&*data_.begin(), bits, bytes); + DeleteDC(hdc); + DeleteObject(bitmap); + return success; + } #else NOTIMPLEMENTED(); - return false; #endif + + return false; } + +} // namespace printing diff --git a/printing/image.h b/printing/image.h index 8ef1007..a927549 100644 --- a/printing/image.h +++ b/printing/image.h @@ -11,10 +11,11 @@ #include "base/basictypes.h" #include "base/gfx/size.h" #include "base/logging.h" +#include "printing/native_metafile.h" namespace printing { -// Lightweight raw-bitmap management. The image, once initialized, is immuable. +// Lightweight raw-bitmap management. The image, once initialized, is immutable. // The main purpose is testing image contents. class Image { public: @@ -23,12 +24,22 @@ class Image { // If image loading fails size().IsEmpty() will be true. explicit Image(const std::wstring& filename); + // Creates the image from the metafile. Deduces bounds based on bounds in + // metafile. If loading fails size().IsEmpty() will be true. + explicit Image(const NativeMetafile& metafile); + + // Copy constructor. + explicit Image(const Image& image); + const gfx::Size& size() const { return size_; } + // Return a checksum of the image (MD5 over the internal data structure). + std::string checksum() const; + // Save image as PNG. - bool SaveToPng(const std::wstring& filename); + bool SaveToPng(const std::wstring& filename) const; // Returns % of pixels different double PercentageDifferent(const Image& rhs) const; @@ -50,10 +61,16 @@ class Image { } private: + // Construct from metafile. This is kept internal since it's ambiguous what + // kind of data is used (png, bmp, metafile etc). + Image(const void* data, size_t size); + bool LoadPng(const std::string& compressed); bool LoadMetafile(const std::string& data); + bool LoadMetafile(const NativeMetafile& metafile); + // Pixel dimensions of the image. gfx::Size size_; @@ -67,7 +84,8 @@ class Image { // Flag to signal if the comparison functions should ignore the alpha channel. const bool ignore_alpha_; // Currently always true. - DISALLOW_EVIL_CONSTRUCTORS(Image); + // Prevent operator= (this function has no implementation) + Image& operator=(const Image& image); }; } // namespace printing |