This source file includes following definitions.
- CreateHBitmap
 
- GetBitmapDC
 
- ReleaseBitmapDC
 
- IsBitmapDCCreated
 
- SetMatrixClip
 
- LoadConfig
 
- DeleteHBitmapCallback
 
- InstallHBitmapPixels
 
- Create
 
- Create
 
- CreateAndClear
 
- transform_
 
- BeginPlatformPaint
 
- EndPlatformPaint
 
- setMatrixClip
 
- DrawToNativeContext
 
- onAccessBitmap
 
- onCreateDevice
 
- CreatePlatformCanvas
 
- Allocate
 
#include <windows.h>
#include <psapi.h>
#include "base/debug/gdi_debug_util_win.h"
#include "base/logging.h"
#include "skia/ext/bitmap_platform_device_win.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "third_party/skia/include/core/SkUtils.h"
namespace {
HBITMAP CreateHBitmap(int width, int height, bool is_opaque,
                             HANDLE shared_section, void** data) {
  
  
  if ((width == 0) || (height == 0)) {
    width = 1;
    height = 1;
  }
  BITMAPINFOHEADER hdr = {0};
  hdr.biSize = sizeof(BITMAPINFOHEADER);
  hdr.biWidth = width;
  hdr.biHeight = -height;  
  hdr.biPlanes = 1;
  hdr.biBitCount = 32;
  hdr.biCompression = BI_RGB;  
  hdr.biSizeImage = 0;
  hdr.biXPelsPerMeter = 1;
  hdr.biYPelsPerMeter = 1;
  hdr.biClrUsed = 0;
  hdr.biClrImportant = 0;
  HBITMAP hbitmap = CreateDIBSection(NULL, reinterpret_cast<BITMAPINFO*>(&hdr),
                                     0, data, shared_section, 0);
#if !defined(_WIN64)
  
  
  if (!hbitmap)
    base::debug::GDIBitmapAllocFailure(&hdr, shared_section);
#endif
  return hbitmap;
}
}  
namespace skia {
HDC BitmapPlatformDevice::GetBitmapDC() {
  if (!hdc_) {
    hdc_ = CreateCompatibleDC(NULL);
    InitializeDC(hdc_);
    old_hbitmap_ = static_cast<HBITMAP>(SelectObject(hdc_, hbitmap_));
  }
  LoadConfig();
  return hdc_;
}
void BitmapPlatformDevice::ReleaseBitmapDC() {
  SkASSERT(hdc_);
  SelectObject(hdc_, old_hbitmap_);
  DeleteDC(hdc_);
  hdc_ = NULL;
  old_hbitmap_ = NULL;
}
bool BitmapPlatformDevice::IsBitmapDCCreated()
    const {
  return hdc_ != NULL;
}
void BitmapPlatformDevice::SetMatrixClip(
    const SkMatrix& transform,
    const SkRegion& region) {
  transform_ = transform;
  clip_region_ = region;
  config_dirty_ = true;
}
void BitmapPlatformDevice::LoadConfig() {
  if (!config_dirty_ || !hdc_)
    return;  
  config_dirty_ = false;
  
  LoadTransformToDC(hdc_, transform_);
  LoadClippingRegionToDC(hdc_, clip_region_, transform_);
}
static void DeleteHBitmapCallback(void* addr, void* context) {
  DeleteObject(static_cast<HBITMAP>(context));
}
static bool InstallHBitmapPixels(SkBitmap* bitmap, int width, int height,
                                 bool is_opaque, void* data, HBITMAP hbitmap) {
  const SkAlphaType at = is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
  const SkImageInfo info = SkImageInfo::MakeN32(width, height, at);
  const size_t rowBytes = info.minRowBytes();
  return bitmap->installPixels(info, data, rowBytes, DeleteHBitmapCallback,
                               hbitmap);
}
BitmapPlatformDevice* BitmapPlatformDevice::Create(
    int width,
    int height,
    bool is_opaque,
    HANDLE shared_section) {
  void* data;
  HBITMAP hbitmap = CreateHBitmap(width, height, is_opaque, shared_section,
                                  &data);
  if (!hbitmap)
    return NULL;
  SkBitmap bitmap;
  if (!InstallHBitmapPixels(&bitmap, width, height, is_opaque, data, hbitmap))
    return NULL;
#ifndef NDEBUG
  
  if (!shared_section && is_opaque)
    
    
    bitmap.eraseARGB(255, 0, 255, 128);  
#endif
  
  
  return new BitmapPlatformDevice(hbitmap, bitmap);
}
BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
                                                   bool is_opaque) {
  return Create(width, height, is_opaque, NULL);
}
BitmapPlatformDevice* BitmapPlatformDevice::CreateAndClear(int width,
                                                           int height,
                                                           bool is_opaque) {
  BitmapPlatformDevice* device = BitmapPlatformDevice::Create(width, height,
                                                              is_opaque);
  if (device && !is_opaque)
    device->clear(0);
  return device;
}
BitmapPlatformDevice::BitmapPlatformDevice(
    HBITMAP hbitmap,
    const SkBitmap& bitmap)
    : SkBitmapDevice(bitmap),
      hbitmap_(hbitmap),
      old_hbitmap_(NULL),
      hdc_(NULL),
      config_dirty_(true),  
      transform_(SkMatrix::I()) {
  
  SkDEBUGCODE(begin_paint_count_ = 0);
  SetPlatformDevice(this, this);
  
  BITMAP bitmap_data;
  if (GetObject(hbitmap_, sizeof(BITMAP), &bitmap_data)) {
    SkIRect rect;
    rect.set(0, 0, bitmap_data.bmWidth, bitmap_data.bmHeight);
    clip_region_ = SkRegion(rect);
  }
}
BitmapPlatformDevice::~BitmapPlatformDevice() {
  SkASSERT(begin_paint_count_ == 0);
  if (hdc_)
    ReleaseBitmapDC();
}
HDC BitmapPlatformDevice::BeginPlatformPaint() {
  SkDEBUGCODE(begin_paint_count_++);
  return GetBitmapDC();
}
void BitmapPlatformDevice::EndPlatformPaint() {
  SkASSERT(begin_paint_count_--);
  PlatformDevice::EndPlatformPaint();
}
void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform,
                                         const SkRegion& region,
                                         const SkClipStack&) {
  SetMatrixClip(transform, region);
}
void BitmapPlatformDevice::DrawToNativeContext(HDC dc, int x, int y,
                                               const RECT* src_rect) {
  bool created_dc = !IsBitmapDCCreated();
  HDC source_dc = BeginPlatformPaint();
  RECT temp_rect;
  if (!src_rect) {
    temp_rect.left = 0;
    temp_rect.right = width();
    temp_rect.top = 0;
    temp_rect.bottom = height();
    src_rect = &temp_rect;
  }
  int copy_width = src_rect->right - src_rect->left;
  int copy_height = src_rect->bottom - src_rect->top;
  
  
  SkMatrix identity;
  identity.reset();
  LoadTransformToDC(source_dc, identity);
  if (isOpaque()) {
    BitBlt(dc,
           x,
           y,
           copy_width,
           copy_height,
           source_dc,
           src_rect->left,
           src_rect->top,
           SRCCOPY);
  } else {
    SkASSERT(copy_width != 0 && copy_height != 0);
    BLENDFUNCTION blend_function = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
    GdiAlphaBlend(dc,
                  x,
                  y,
                  copy_width,
                  copy_height,
                  source_dc,
                  src_rect->left,
                  src_rect->top,
                  copy_width,
                  copy_height,
                  blend_function);
  }
  LoadTransformToDC(source_dc, transform_);
  EndPlatformPaint();
  if (created_dc)
    ReleaseBitmapDC();
}
const SkBitmap& BitmapPlatformDevice::onAccessBitmap() {
  
  
  if (IsBitmapDCCreated())
    GdiFlush();
  return SkBitmapDevice::onAccessBitmap();
}
SkBaseDevice* BitmapPlatformDevice::onCreateDevice(const SkImageInfo& info,
                                                   Usage ) {
  SkASSERT(info.colorType() == kPMColor_SkColorType);
  return BitmapPlatformDevice::CreateAndClear(info.width(), info.height(),
                                              info.isOpaque());
}
SkCanvas* CreatePlatformCanvas(int width,
                               int height,
                               bool is_opaque,
                               HANDLE shared_section,
                               OnFailureType failureType) {
  skia::RefPtr<SkBaseDevice> dev = skia::AdoptRef(
      BitmapPlatformDevice::Create(width, height, is_opaque, shared_section));
  return CreateCanvas(dev, failureType);
}
PlatformBitmap::~PlatformBitmap() {
  if (surface_) {
    if (platform_extra_)
      SelectObject(surface_, reinterpret_cast<HGDIOBJ>(platform_extra_));
    DeleteDC(surface_);
  }
}
bool PlatformBitmap::Allocate(int width, int height, bool is_opaque) {
  void* data;
  HBITMAP hbitmap = CreateHBitmap(width, height, is_opaque, 0, &data);
  if (!hbitmap)
    return false;
  surface_ = CreateCompatibleDC(NULL);
  InitializeDC(surface_);
  
  
  
  HGDIOBJ stock_bitmap = SelectObject(surface_, hbitmap);
  platform_extra_ = reinterpret_cast<intptr_t>(stock_bitmap);
  if (!InstallHBitmapPixels(&bitmap_, width, height, is_opaque, data, hbitmap))
    return false;
  bitmap_.lockPixels();
  return true;
}
}