Index: printing/image.cc |
=================================================================== |
--- printing/image.cc (revision 20864) |
+++ printing/image.cc (working copy) |
@@ -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 @@ |
} |
} |
-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 @@ |
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 @@ |
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 @@ |
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(); |
+#endif |
+ |
return false; |
-#endif |
} |
+ |
+} // namespace printing |