summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/chrome.gyp2
-rw-r--r--chrome/renderer/mock_printer.cc57
-rw-r--r--chrome/renderer/mock_printer.h56
-rw-r--r--chrome/renderer/mock_printer_driver_win.cc125
-rw-r--r--chrome/renderer/mock_printer_driver_win.h25
-rw-r--r--chrome/renderer/render_view.cc16
-rw-r--r--chrome/renderer/render_view.h1
-rw-r--r--chrome/renderer/render_view_unittest.cc50
-rw-r--r--printing/image.cc134
-rw-r--r--printing/image.h24
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