15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/image.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/win/scoped_gdi_object.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/win/scoped_hdc.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/win/scoped_select_object.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/metafile.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/platform_device.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/gdi_util.h"  // EMF support
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A simple class which temporarily overrides system settings.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The bitmap image rendered via the PlayEnhMetaFile() function depends on
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// some system settings.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// As a workaround for such dependency, this class saves the system settings
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and changes them. This class also restore the saved settings in its
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destructor.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DisableFontSmoothing {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit DisableFontSmoothing() : enable_again_(false) {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BOOL enabled;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &enabled, 0) &&
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        enabled) {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (SystemParametersInfo(SPI_SETFONTSMOOTHING, FALSE, NULL, 0))
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        enable_again_ = true;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~DisableFontSmoothing() {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (enable_again_) {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BOOL result = SystemParametersInfo(SPI_SETFONTSMOOTHING, TRUE, NULL, 0);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(result);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool enable_again_;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DisableFontSmoothing);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace printing {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Image::LoadMetafile(const Metafile& metafile) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Rect rect(metafile.GetPageBounds(1));
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DisableFontSmoothing disable_in_this_scope;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a temporary HDC and bitmap to retrieve the rendered data.
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::win::ScopedCreateDC hdc(::CreateCompatibleDC(NULL));
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BITMAPV4HEADER hdr;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(rect.x(), 0);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(rect.y(), 0);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(rect.width(), 0);  // Metafile could be empty.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(rect.height(), 0);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rect.width() < 1 || rect.height() < 1)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_ = rect.size();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::CreateBitmapV4Header(rect.width(), rect.height(), &hdr);
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned char* bits = NULL;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::win::ScopedBitmap bitmap(
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ::CreateDIBSection(hdc.Get(), reinterpret_cast<BITMAPINFO*>(&hdr), 0,
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         reinterpret_cast<void**>(&bits), NULL, 0));
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bitmap);
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::win::ScopedSelectObject select_object(hdc.Get(), bitmap);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  skia::InitializeDC(hdc.Get());
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool success = metafile.Playback(hdc.Get(), NULL);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  row_length_ = size_.width() * sizeof(uint32);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t bytes = row_length_ * size_.height();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bytes);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data_.assign(bits, bits + bytes);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return success;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace printing
90