Chromium Code Reviews| Index: skia/ext/skia_utils_win.cc | 
| diff --git a/skia/ext/skia_utils_win.cc b/skia/ext/skia_utils_win.cc | 
| index 9873373725705fe6f8e4491a54ebd56916829276..c53bb3e35838a22e3018acbceaaa7b67236c56a0 100644 | 
| --- a/skia/ext/skia_utils_win.cc | 
| +++ b/skia/ext/skia_utils_win.cc | 
| @@ -7,7 +7,10 @@ | 
| #include <stddef.h> | 
| #include <windows.h> | 
| +#include "base/debug/gdi_debug_util_win.h" | 
| +#include "base/win/win_util.h" | 
| #include "third_party/skia/include/core/SkRect.h" | 
| +#include "third_party/skia/include/core/SkSurface.h" | 
| #include "third_party/skia/include/core/SkTypes.h" | 
| #include "third_party/skia/include/effects/SkGradientShader.h" | 
| @@ -23,8 +26,42 @@ static_assert(sizeof(RECT().right) == sizeof(SkIRect().fRight), "o7"); | 
| static_assert(sizeof(RECT().bottom) == sizeof(SkIRect().fBottom), "o8"); | 
| static_assert(sizeof(RECT) == sizeof(SkIRect), "o9"); | 
| -} // namespace | 
| +HBITMAP CreateHBitmap(int width, int height) { | 
| + // CreateDIBSection appears to get unhappy if we create an empty bitmap, so | 
| + // just create a minimal bitmap. | 
| + if ((width == 0) || (height == 0)) { | 
| + width = 1; | 
| + height = 1; | 
| + } | 
| + | 
| + BITMAPINFOHEADER hdr = {0}; | 
| + hdr.biSize = sizeof(BITMAPINFOHEADER); | 
| + hdr.biWidth = width; | 
| + hdr.biHeight = -height; // minus means top-down bitmap | 
| + hdr.biPlanes = 1; | 
| + hdr.biBitCount = 32; | 
| + hdr.biCompression = BI_RGB; // no compression | 
| + hdr.biSizeImage = 0; | 
| + hdr.biXPelsPerMeter = 1; | 
| + hdr.biYPelsPerMeter = 1; | 
| + hdr.biClrUsed = 0; | 
| + hdr.biClrImportant = 0; | 
| + | 
| + HBITMAP hbitmap = CreateDIBSection(nullptr, reinterpret_cast<BITMAPINFO*>(&hdr), | 
| 
 
Peter Kasting
2016/02/16 21:12:10
Nit: 80 columns
 
tomhudson
2016/06/21 22:20:22
Done.
 
 | 
| + 0, nullptr, nullptr, 0); | 
| + | 
| +#if !defined(_WIN64) | 
| + // If CreateDIBSection() failed, try to get some useful | 
| 
 
Peter Kasting
2016/02/16 21:12:10
Nit: Wrap as late as possible
 
tomhudson
2016/06/21 22:20:22
Done.
 
 | 
| + // information out before we crash for post-mortem analysis. | 
| + if (!hbitmap) | 
| + base::debug::GDIBitmapAllocFailure(&hdr, nullptr); | 
| +#endif | 
| + | 
| + return hbitmap; | 
| +} | 
| + | 
| +} // namespace | 
| namespace skia { | 
| POINT SkPointToPOINT(const SkPoint& point) { | 
| @@ -73,7 +110,7 @@ void InitializeDC(HDC context) { | 
| SkASSERT(res != 0); | 
| // As per SetStretchBltMode() documentation, SetBrushOrgEx() must be called | 
| // right after. | 
| - res = SetBrushOrgEx(context, 0, 0, NULL); | 
| + res = SetBrushOrgEx(context, 0, 0, nullptr); | 
| SkASSERT(res != 0); | 
| // Sets up default orientation. | 
| @@ -97,5 +134,94 @@ void InitializeDC(HDC context) { | 
| SkASSERT(res != 0); | 
| } | 
| +#if 0 | 
| +namespace { | 
| + | 
| +bool PrepareAllocation(HDC context, SkImageInfo* size, BITMAP* backing) { | 
| + HBITMAP backing_handle = | 
| + static_cast<HBITMAP>(GetCurrentObject(context, OBJ_BITMAP)); | 
| + if (GetObject(backing_handle, sizeof(*backing), | 
| + backing) != sizeof(*backing)) | 
| + return false; | 
| + *size = SkImageInfo::MakeN32Premul(backing->bmWidth, | 
| + backing->bmHeight); | 
| + return true; | 
| +} | 
| + | 
| +} | 
| + | 
| +SkSurface* MapPlatformSurface(HDC context) { | 
| + SkImageInfo size; | 
| + Bitmap backing; | 
| + if (!PrepareAllocation(HDC, &size, &backing)) | 
| + return nullptr; | 
| + return SkSurface::NewRasterDirect(size, backing.bmBits, | 
| + backing.bmWidthBytes); | 
| +} | 
| + | 
| +SkBitmap MapPlatformBitmap(HDC context) { | 
| + SkImageInfo size; | 
| + Bitmap backing; | 
| + SkBitmap bitmap; | 
| + if (PrepareAllocation(HDC, &size, &backing)) | 
| + bitmap.installPixels(size, backing.bmBits, size.minRowBytes()); | 
| + return bitmap; | 
| +} | 
| +#endif | 
| + | 
| +SkSurface* MapPlatformSurface(HDC context) { | 
| + HBITMAP backing_handle = | 
| + static_cast<HBITMAP>(GetCurrentObject(context, OBJ_BITMAP)); | 
| + BITMAP backing; | 
| + if (GetObject(backing_handle, sizeof(backing), | 
| + &backing) != sizeof(backing)) | 
| + return nullptr; | 
| + return SkSurface::NewRasterDirect( | 
| + SkImageInfo::MakeN32Premul(backing.bmWidth, backing.bmHeight), | 
| + backing.bmBits, backing.bmWidthBytes); | 
| +} | 
| + | 
| +SkBitmap MapPlatformBitmap(HDC context) { | 
| + HBITMAP backing_handle = | 
| + static_cast<HBITMAP>(GetCurrentObject(context, OBJ_BITMAP)); | 
| + BITMAP backing; | 
| + SkBitmap bitmap; | 
| + if (GetObject(backing_handle, sizeof(backing), | 
| + &backing) == sizeof(backing)) { | 
| + SkImageInfo size = SkImageInfo::MakeN32Premul(backing.bmWidth, | 
| + backing.bmHeight); | 
| + bitmap.installPixels(size, backing.bmBits, size.minRowBytes()); | 
| + } | 
| + return bitmap; | 
| +} | 
| + | 
| +HDC CreateOffscreenSurface(int width, int height) { | 
| + HBITMAP bitmap = nullptr; | 
| + | 
| + // If this process doesn't have access to GDI, we'll have to use a shared | 
| + // memory segment instead. | 
| + if (!base::win::IsUser32AndGdi32Available()) | 
| + return nullptr; | 
| + | 
| + bitmap = CreateHBitmap(width, height); | 
| + if (!bitmap) | 
| + return nullptr; | 
| + | 
| + HDC hdc = CreateCompatibleDC(nullptr); | 
| + SkASSERT(hdc); | 
| + InitializeDC(hdc); | 
| + HRGN clip = CreateRectRgn(0, 0, width, height); | 
| + int result = SelectClipRgn(hdc, clip); | 
| + SkASSERT(result != ERROR); | 
| + result = DeleteObject(clip); | 
| + SkASSERT(result); | 
| + | 
| + SelectObject(hdc, bitmap); | 
| + | 
| + // need to clean up by calling DeleteDC(hdc) else we leak! | 
| + | 
| + return hdc; | 
| +} | 
| + | 
| } // namespace skia |