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 /printing | |
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 'printing')
-rw-r--r-- | printing/image.cc | 134 | ||||
-rw-r--r-- | printing/image.h | 24 |
2 files changed, 127 insertions, 31 deletions
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 |