Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "skia/ext/skia_utils_win.h" | 5 #include "skia/ext/skia_utils_win.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <windows.h> | 8 #include <windows.h> |
| 9 | 9 |
| 10 #include "base/debug/gdi_debug_util_win.h" | |
| 11 #include "base/win/win_util.h" | |
| 10 #include "third_party/skia/include/core/SkRect.h" | 12 #include "third_party/skia/include/core/SkRect.h" |
| 13 #include "third_party/skia/include/core/SkSurface.h" | |
| 11 #include "third_party/skia/include/core/SkTypes.h" | 14 #include "third_party/skia/include/core/SkTypes.h" |
| 12 #include "third_party/skia/include/effects/SkGradientShader.h" | 15 #include "third_party/skia/include/effects/SkGradientShader.h" |
| 13 | 16 |
| 14 namespace { | 17 namespace { |
| 15 | 18 |
| 16 static_assert(offsetof(RECT, left) == offsetof(SkIRect, fLeft), "o1"); | 19 static_assert(offsetof(RECT, left) == offsetof(SkIRect, fLeft), "o1"); |
| 17 static_assert(offsetof(RECT, top) == offsetof(SkIRect, fTop), "o2"); | 20 static_assert(offsetof(RECT, top) == offsetof(SkIRect, fTop), "o2"); |
| 18 static_assert(offsetof(RECT, right) == offsetof(SkIRect, fRight), "o3"); | 21 static_assert(offsetof(RECT, right) == offsetof(SkIRect, fRight), "o3"); |
| 19 static_assert(offsetof(RECT, bottom) == offsetof(SkIRect, fBottom), "o4"); | 22 static_assert(offsetof(RECT, bottom) == offsetof(SkIRect, fBottom), "o4"); |
| 20 static_assert(sizeof(RECT().left) == sizeof(SkIRect().fLeft), "o5"); | 23 static_assert(sizeof(RECT().left) == sizeof(SkIRect().fLeft), "o5"); |
| 21 static_assert(sizeof(RECT().top) == sizeof(SkIRect().fTop), "o6"); | 24 static_assert(sizeof(RECT().top) == sizeof(SkIRect().fTop), "o6"); |
| 22 static_assert(sizeof(RECT().right) == sizeof(SkIRect().fRight), "o7"); | 25 static_assert(sizeof(RECT().right) == sizeof(SkIRect().fRight), "o7"); |
| 23 static_assert(sizeof(RECT().bottom) == sizeof(SkIRect().fBottom), "o8"); | 26 static_assert(sizeof(RECT().bottom) == sizeof(SkIRect().fBottom), "o8"); |
| 24 static_assert(sizeof(RECT) == sizeof(SkIRect), "o9"); | 27 static_assert(sizeof(RECT) == sizeof(SkIRect), "o9"); |
| 25 | 28 |
| 29 void CreateBitmapHeaderWithColorDepth(LONG width, | |
| 30 LONG height, | |
| 31 WORD color_depth, | |
| 32 BITMAPINFOHEADER* hdr) { | |
| 33 // These values are shared with gfx::PlatformDevice. | |
| 34 hdr->biSize = sizeof(BITMAPINFOHEADER); | |
| 35 hdr->biWidth = width; | |
| 36 hdr->biHeight = -height; // Minus means top-down bitmap. | |
| 37 hdr->biPlanes = 1; | |
| 38 hdr->biBitCount = color_depth; | |
| 39 hdr->biCompression = BI_RGB; // No compression. | |
| 40 hdr->biSizeImage = 0; | |
| 41 hdr->biXPelsPerMeter = 1; | |
| 42 hdr->biYPelsPerMeter = 1; | |
| 43 hdr->biClrUsed = 0; | |
| 44 hdr->biClrImportant = 0; | |
| 45 } | |
| 46 | |
| 47 HBITMAP CreateHBitmap(int width, int height) { | |
| 48 // CreateDIBSection fails to allocate anything if we try to create an empty | |
| 49 // bitmap, so just create a minimal bitmap. | |
| 50 if ((width == 0) || (height == 0)) { | |
| 51 width = 1; | |
| 52 height = 1; | |
| 53 } | |
| 54 | |
| 55 BITMAPINFOHEADER hdr = {0}; | |
| 56 CreateBitmapHeaderWithColorDepth(width, height, 32, &hdr); | |
| 57 | |
| 58 HBITMAP hbitmap = CreateDIBSection(nullptr, | |
| 59 reinterpret_cast<BITMAPINFO*>(&hdr), | |
| 60 0, nullptr, nullptr, 0); | |
| 61 | |
| 62 // If CreateDIBSection() failed, try to get some useful information out | |
| 63 // before we crash for post-mortem analysis. | |
| 64 if (!hbitmap) | |
| 65 base::debug::GDIBitmapAllocFailure(&hdr, nullptr); | |
| 66 | |
| 67 return hbitmap; | |
| 68 } | |
| 69 | |
| 70 | |
| 26 } // namespace | 71 } // namespace |
| 27 | 72 |
| 28 namespace skia { | 73 namespace skia { |
| 29 | 74 |
| 30 POINT SkPointToPOINT(const SkPoint& point) { | 75 POINT SkPointToPOINT(const SkPoint& point) { |
| 31 POINT win_point = { | 76 POINT win_point = { |
| 32 SkScalarRoundToInt(point.fX), SkScalarRoundToInt(point.fY) | 77 SkScalarRoundToInt(point.fX), SkScalarRoundToInt(point.fY) |
| 33 }; | 78 }; |
| 34 return win_point; | 79 return win_point; |
| 35 } | 80 } |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 66 // and arcs themselves fully respect the device context's world-to-device | 111 // and arcs themselves fully respect the device context's world-to-device |
| 67 // transformation. | 112 // transformation. |
| 68 BOOL res = SetGraphicsMode(context, GM_ADVANCED); | 113 BOOL res = SetGraphicsMode(context, GM_ADVANCED); |
| 69 SkASSERT(res != 0); | 114 SkASSERT(res != 0); |
| 70 | 115 |
| 71 // Enables dithering. | 116 // Enables dithering. |
| 72 res = SetStretchBltMode(context, HALFTONE); | 117 res = SetStretchBltMode(context, HALFTONE); |
| 73 SkASSERT(res != 0); | 118 SkASSERT(res != 0); |
| 74 // As per SetStretchBltMode() documentation, SetBrushOrgEx() must be called | 119 // As per SetStretchBltMode() documentation, SetBrushOrgEx() must be called |
| 75 // right after. | 120 // right after. |
| 76 res = SetBrushOrgEx(context, 0, 0, NULL); | 121 res = SetBrushOrgEx(context, 0, 0, nullptr); |
| 77 SkASSERT(res != 0); | 122 SkASSERT(res != 0); |
| 78 | 123 |
| 79 // Sets up default orientation. | 124 // Sets up default orientation. |
| 80 res = SetArcDirection(context, AD_CLOCKWISE); | 125 res = SetArcDirection(context, AD_CLOCKWISE); |
| 81 SkASSERT(res != 0); | 126 SkASSERT(res != 0); |
| 82 | 127 |
| 83 // Sets up default colors. | 128 // Sets up default colors. |
| 84 res = SetBkColor(context, RGB(255, 255, 255)); | 129 res = SetBkColor(context, RGB(255, 255, 255)); |
| 85 SkASSERT(res != CLR_INVALID); | 130 SkASSERT(res != CLR_INVALID); |
| 86 res = SetTextColor(context, RGB(0, 0, 0)); | 131 res = SetTextColor(context, RGB(0, 0, 0)); |
| 87 SkASSERT(res != CLR_INVALID); | 132 SkASSERT(res != CLR_INVALID); |
| 88 res = SetDCBrushColor(context, RGB(255, 255, 255)); | 133 res = SetDCBrushColor(context, RGB(255, 255, 255)); |
| 89 SkASSERT(res != CLR_INVALID); | 134 SkASSERT(res != CLR_INVALID); |
| 90 res = SetDCPenColor(context, RGB(0, 0, 0)); | 135 res = SetDCPenColor(context, RGB(0, 0, 0)); |
| 91 SkASSERT(res != CLR_INVALID); | 136 SkASSERT(res != CLR_INVALID); |
| 92 | 137 |
| 93 // Sets up default transparency. | 138 // Sets up default transparency. |
| 94 res = SetBkMode(context, OPAQUE); | 139 res = SetBkMode(context, OPAQUE); |
| 95 SkASSERT(res != 0); | 140 SkASSERT(res != 0); |
| 96 res = SetROP2(context, R2_COPYPEN); | 141 res = SetROP2(context, R2_COPYPEN); |
| 97 SkASSERT(res != 0); | 142 SkASSERT(res != 0); |
| 98 } | 143 } |
| 99 | 144 |
| 145 SkImageInfo PrepareAllocation(HDC context, BITMAP* backing) { | |
| 146 HBITMAP backing_handle = | |
| 147 static_cast<HBITMAP>(GetCurrentObject(context, OBJ_BITMAP)); | |
| 148 const size_t backing_size = sizeof(*backing); | |
| 149 return (GetObject(backing_handle, backing_size, backing) == backing_size) | |
| 150 ? SkImageInfo::MakeN32Premul(backing->bmWidth, backing->bmHeight) | |
| 151 : SkImageInfo(); | |
| 152 } | |
| 153 | |
| 154 sk_sp<SkSurface> MapPlatformSurface(HDC context) { | |
| 155 BITMAP backing; | |
| 156 const SkImageInfo size(PrepareAllocation(context, &backing)); | |
| 157 return size.isEmpty() ? nullptr | |
| 158 : SkSurface::MakeRasterDirect(size, backing.bmBits, | |
| 159 backing.bmWidthBytes); | |
| 160 } | |
| 161 | |
| 162 SkBitmap MapPlatformBitmap(HDC context) { | |
| 163 BITMAP backing; | |
| 164 const SkImageInfo size(PrepareAllocation(context, &backing)); | |
| 165 SkBitmap bitmap; | |
| 166 if (!size.isEmpty()) | |
| 167 bitmap.installPixels(size, backing.bmBits, size.minRowBytes()); | |
| 168 return bitmap; | |
| 169 } | |
| 170 | |
| 171 HDC CreateOffscreenSurface(int width, int height) { | |
| 172 HBITMAP bitmap = nullptr; | |
| 173 | |
| 174 // If this process doesn't have access to GDI, we'll have to use a shared | |
| 175 // memory segment instead. | |
| 176 if (!base::win::IsUser32AndGdi32Available()) | |
| 177 return nullptr; | |
| 178 | |
| 179 bitmap = CreateHBitmap(width, height); | |
| 180 if (!bitmap) | |
| 181 return nullptr; | |
| 182 | |
| 183 HDC hdc = CreateCompatibleDC(nullptr); | |
|
Peter Kasting
2016/06/22 23:43:52
Seems like we could use ScopedCreateDC here to avo
| |
| 184 if (!hdc) | |
| 185 return nullptr; | |
| 186 InitializeDC(hdc); | |
| 187 HRGN clip = CreateRectRgn(0, 0, width, height); | |
| 188 if (SelectClipRgn(hdc, clip) == ERROR) { | |
| 189 DeleteObject(hdc); | |
| 190 return nullptr; | |
| 191 } | |
| 192 if (!DeleteObject(clip)) { | |
| 193 DeleteObject(hdc); | |
| 194 return nullptr; | |
| 195 } | |
| 196 | |
| 197 SelectObject(hdc, bitmap); | |
| 198 | |
| 199 // The caller must call DeleteDC(hdc) on this object once done with it. | |
| 200 return hdc; | |
| 201 } | |
| 202 | |
| 203 void CreateBitmapHeader(int width, int height, BITMAPINFOHEADER* hdr) { | |
| 204 CreateBitmapHeaderWithColorDepth(width, height, 32, hdr); | |
| 205 } | |
| 206 | |
| 100 } // namespace skia | 207 } // namespace skia |
| 101 | 208 |
| OLD | NEW |