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 | |
Peter Kasting
2016/06/22 02:23:34
Nit: Trailing periods
tomhudson
2016/06/22 21:29:58
Done.
| |
34 hdr->biSize = sizeof(BITMAPINFOHEADER); | |
35 hdr->biWidth = width; | |
36 hdr->biHeight = -height; // minus means top-down bitmap | |
Peter Kasting
2016/06/22 02:23:34
Nit: Initial caps
tomhudson
2016/06/22 21:29:58
Done.
| |
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 appears to get unhappy if we create an empty bitmap, so | |
tomhudson
2016/06/22 21:29:58
Changed "appears to get unhappy if we create" to "
| |
49 // 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 |
75 void CreateBitmapHeader(int width, int height, BITMAPINFOHEADER* hdr) { | |
76 CreateBitmapHeaderWithColorDepth(width, height, 32, hdr); | |
77 } | |
Peter Kasting
2016/06/22 02:23:34
Nit Function definition order should match .h decl
tomhudson
2016/06/22 21:29:58
Done.
| |
78 | |
30 POINT SkPointToPOINT(const SkPoint& point) { | 79 POINT SkPointToPOINT(const SkPoint& point) { |
31 POINT win_point = { | 80 POINT win_point = { |
32 SkScalarRoundToInt(point.fX), SkScalarRoundToInt(point.fY) | 81 SkScalarRoundToInt(point.fX), SkScalarRoundToInt(point.fY) |
33 }; | 82 }; |
34 return win_point; | 83 return win_point; |
35 } | 84 } |
36 | 85 |
37 SkRect RECTToSkRect(const RECT& rect) { | 86 SkRect RECTToSkRect(const RECT& rect) { |
38 SkRect sk_rect = { SkIntToScalar(rect.left), SkIntToScalar(rect.top), | 87 SkRect sk_rect = { SkIntToScalar(rect.left), SkIntToScalar(rect.top), |
39 SkIntToScalar(rect.right), SkIntToScalar(rect.bottom) }; | 88 SkIntToScalar(rect.right), SkIntToScalar(rect.bottom) }; |
(...skipping 26 matching lines...) Expand all Loading... | |
66 // and arcs themselves fully respect the device context's world-to-device | 115 // and arcs themselves fully respect the device context's world-to-device |
67 // transformation. | 116 // transformation. |
68 BOOL res = SetGraphicsMode(context, GM_ADVANCED); | 117 BOOL res = SetGraphicsMode(context, GM_ADVANCED); |
69 SkASSERT(res != 0); | 118 SkASSERT(res != 0); |
70 | 119 |
71 // Enables dithering. | 120 // Enables dithering. |
72 res = SetStretchBltMode(context, HALFTONE); | 121 res = SetStretchBltMode(context, HALFTONE); |
73 SkASSERT(res != 0); | 122 SkASSERT(res != 0); |
74 // As per SetStretchBltMode() documentation, SetBrushOrgEx() must be called | 123 // As per SetStretchBltMode() documentation, SetBrushOrgEx() must be called |
75 // right after. | 124 // right after. |
76 res = SetBrushOrgEx(context, 0, 0, NULL); | 125 res = SetBrushOrgEx(context, 0, 0, nullptr); |
77 SkASSERT(res != 0); | 126 SkASSERT(res != 0); |
78 | 127 |
79 // Sets up default orientation. | 128 // Sets up default orientation. |
80 res = SetArcDirection(context, AD_CLOCKWISE); | 129 res = SetArcDirection(context, AD_CLOCKWISE); |
81 SkASSERT(res != 0); | 130 SkASSERT(res != 0); |
82 | 131 |
83 // Sets up default colors. | 132 // Sets up default colors. |
84 res = SetBkColor(context, RGB(255, 255, 255)); | 133 res = SetBkColor(context, RGB(255, 255, 255)); |
85 SkASSERT(res != CLR_INVALID); | 134 SkASSERT(res != CLR_INVALID); |
86 res = SetTextColor(context, RGB(0, 0, 0)); | 135 res = SetTextColor(context, RGB(0, 0, 0)); |
87 SkASSERT(res != CLR_INVALID); | 136 SkASSERT(res != CLR_INVALID); |
88 res = SetDCBrushColor(context, RGB(255, 255, 255)); | 137 res = SetDCBrushColor(context, RGB(255, 255, 255)); |
89 SkASSERT(res != CLR_INVALID); | 138 SkASSERT(res != CLR_INVALID); |
90 res = SetDCPenColor(context, RGB(0, 0, 0)); | 139 res = SetDCPenColor(context, RGB(0, 0, 0)); |
91 SkASSERT(res != CLR_INVALID); | 140 SkASSERT(res != CLR_INVALID); |
92 | 141 |
93 // Sets up default transparency. | 142 // Sets up default transparency. |
94 res = SetBkMode(context, OPAQUE); | 143 res = SetBkMode(context, OPAQUE); |
95 SkASSERT(res != 0); | 144 SkASSERT(res != 0); |
96 res = SetROP2(context, R2_COPYPEN); | 145 res = SetROP2(context, R2_COPYPEN); |
97 SkASSERT(res != 0); | 146 SkASSERT(res != 0); |
98 } | 147 } |
99 | 148 |
149 SkImageInfo PrepareAllocation(HDC context, BITMAP* backing) { | |
150 HBITMAP backing_handle = | |
151 static_cast<HBITMAP>(GetCurrentObject(context, OBJ_BITMAP)); | |
152 const size_t backing_size = sizeof(*backing); | |
153 if (GetObject(backing_handle, backing_size, backing) != backing_size) | |
154 return SkImageInfo(); | |
155 return SkImageInfo::MakeN32Premul(backing->bmWidth, backing->bmHeight); | |
Peter Kasting
2016/06/22 02:23:34
Nit: Fractionally less verbose; up to you
retur
tomhudson
2016/06/22 21:29:58
Done.
| |
156 } | |
157 | |
158 sk_sp<SkSurface> MapPlatformSurface(HDC context) { | |
159 BITMAP backing; | |
160 const SkImageInfo size(PrepareAllocation(context, &backing)); | |
161 if (size.isEmpty()) | |
162 return nullptr; | |
163 return SkSurface::MakeRasterDirect(size, backing.bmBits, | |
164 backing.bmWidthBytes); | |
Peter Kasting
2016/06/22 02:23:33
Nit: Likewise:
return size.IsEmpty() ? nullptr
tomhudson
2016/06/22 21:29:58
Done.
| |
165 } | |
166 | |
167 SkBitmap MapPlatformBitmap(HDC context) { | |
168 BITMAP backing; | |
169 const SkImageInfo size(PrepareAllocation(context, &backing)); | |
170 SkBitmap bitmap; | |
171 if (!size.isEmpty()) | |
172 bitmap.installPixels(size, backing.bmBits, size.minRowBytes()); | |
173 return bitmap; | |
174 } | |
175 | |
176 HDC CreateOffscreenSurface(int width, int height) { | |
177 HBITMAP bitmap = nullptr; | |
178 | |
179 // If this process doesn't have access to GDI, we'll have to use a shared | |
180 // memory segment instead. | |
181 if (!base::win::IsUser32AndGdi32Available()) | |
182 return nullptr; | |
183 | |
184 bitmap = CreateHBitmap(width, height); | |
185 if (!bitmap) | |
186 return nullptr; | |
187 | |
188 HDC hdc = CreateCompatibleDC(nullptr); | |
189 SkASSERT(hdc); | |
Peter Kasting
2016/06/22 02:23:34
Do we really want to assert here instead of just r
tomhudson
2016/06/22 21:29:58
This code was taken from code that asserted, but s
Peter Kasting
2016/06/22 23:43:51
I don't see any header comment update for this fun
| |
190 InitializeDC(hdc); | |
191 HRGN clip = CreateRectRgn(0, 0, width, height); | |
192 int result = SelectClipRgn(hdc, clip); | |
193 SkASSERT(result != ERROR); | |
194 result = DeleteObject(clip); | |
195 SkASSERT(result); | |
196 | |
197 SelectObject(hdc, bitmap); | |
198 | |
199 // The caller must call DeleteDC(hdc) on this object once done with it. | |
Peter Kasting
2016/06/22 02:23:34
It's too bad we can't return a ScopedCreateDC here
tomhudson
2016/06/22 21:29:58
Filed crbug.com/622442.
| |
200 return hdc; | |
201 } | |
202 | |
100 } // namespace skia | 203 } // namespace skia |
101 | 204 |
OLD | NEW |