1// Copyright 2010-2012 The W32 Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build windows
6
7package w32
8
9import (
10	"syscall"
11	"unsafe"
12)
13
14var (
15	modgdi32 = syscall.NewLazyDLL("gdi32.dll")
16
17	procGetDeviceCaps             = modgdi32.NewProc("GetDeviceCaps")
18	procDeleteObject              = modgdi32.NewProc("DeleteObject")
19	procCreateFontIndirect        = modgdi32.NewProc("CreateFontIndirectW")
20	procAbortDoc                  = modgdi32.NewProc("AbortDoc")
21	procBitBlt                    = modgdi32.NewProc("BitBlt")
22	procCloseEnhMetaFile          = modgdi32.NewProc("CloseEnhMetaFile")
23	procCopyEnhMetaFile           = modgdi32.NewProc("CopyEnhMetaFileW")
24	procCreateBrushIndirect       = modgdi32.NewProc("CreateBrushIndirect")
25	procCreateCompatibleDC        = modgdi32.NewProc("CreateCompatibleDC")
26	procCreateDC                  = modgdi32.NewProc("CreateDCW")
27	procCreateDIBSection          = modgdi32.NewProc("CreateDIBSection")
28	procCreateEnhMetaFile         = modgdi32.NewProc("CreateEnhMetaFileW")
29	procCreateIC                  = modgdi32.NewProc("CreateICW")
30	procDeleteDC                  = modgdi32.NewProc("DeleteDC")
31	procDeleteEnhMetaFile         = modgdi32.NewProc("DeleteEnhMetaFile")
32	procEllipse                   = modgdi32.NewProc("Ellipse")
33	procEndDoc                    = modgdi32.NewProc("EndDoc")
34	procEndPage                   = modgdi32.NewProc("EndPage")
35	procExtCreatePen              = modgdi32.NewProc("ExtCreatePen")
36	procGetEnhMetaFile            = modgdi32.NewProc("GetEnhMetaFileW")
37	procGetEnhMetaFileHeader      = modgdi32.NewProc("GetEnhMetaFileHeader")
38	procGetObject                 = modgdi32.NewProc("GetObjectW")
39	procGetStockObject            = modgdi32.NewProc("GetStockObject")
40	procGetTextExtentExPoint      = modgdi32.NewProc("GetTextExtentExPointW")
41	procGetTextExtentPoint32      = modgdi32.NewProc("GetTextExtentPoint32W")
42	procGetTextMetrics            = modgdi32.NewProc("GetTextMetricsW")
43	procLineTo                    = modgdi32.NewProc("LineTo")
44	procMoveToEx                  = modgdi32.NewProc("MoveToEx")
45	procPlayEnhMetaFile           = modgdi32.NewProc("PlayEnhMetaFile")
46	procRectangle                 = modgdi32.NewProc("Rectangle")
47	procResetDC                   = modgdi32.NewProc("ResetDCW")
48	procSelectObject              = modgdi32.NewProc("SelectObject")
49	procSetBkMode                 = modgdi32.NewProc("SetBkMode")
50	procSetBrushOrgEx             = modgdi32.NewProc("SetBrushOrgEx")
51	procSetStretchBltMode         = modgdi32.NewProc("SetStretchBltMode")
52	procSetTextColor              = modgdi32.NewProc("SetTextColor")
53	procSetBkColor                = modgdi32.NewProc("SetBkColor")
54	procStartDoc                  = modgdi32.NewProc("StartDocW")
55	procStartPage                 = modgdi32.NewProc("StartPage")
56	procStretchBlt                = modgdi32.NewProc("StretchBlt")
57	procSetDIBitsToDevice         = modgdi32.NewProc("SetDIBitsToDevice")
58	procChoosePixelFormat         = modgdi32.NewProc("ChoosePixelFormat")
59	procDescribePixelFormat       = modgdi32.NewProc("DescribePixelFormat")
60	procGetEnhMetaFilePixelFormat = modgdi32.NewProc("GetEnhMetaFilePixelFormat")
61	procGetPixelFormat            = modgdi32.NewProc("GetPixelFormat")
62	procSetPixelFormat            = modgdi32.NewProc("SetPixelFormat")
63	procSwapBuffers               = modgdi32.NewProc("SwapBuffers")
64)
65
66func GetDeviceCaps(hdc HDC, index int) int {
67	ret, _, _ := procGetDeviceCaps.Call(
68		uintptr(hdc),
69		uintptr(index))
70
71	return int(ret)
72}
73
74func DeleteObject(hObject HGDIOBJ) bool {
75	ret, _, _ := procDeleteObject.Call(
76		uintptr(hObject))
77
78	return ret != 0
79}
80
81func CreateFontIndirect(logFont *LOGFONT) HFONT {
82	ret, _, _ := procCreateFontIndirect.Call(
83		uintptr(unsafe.Pointer(logFont)))
84
85	return HFONT(ret)
86}
87
88func AbortDoc(hdc HDC) int {
89	ret, _, _ := procAbortDoc.Call(
90		uintptr(hdc))
91
92	return int(ret)
93}
94
95func BitBlt(hdcDest HDC, nXDest, nYDest, nWidth, nHeight int, hdcSrc HDC, nXSrc, nYSrc int, dwRop uint) {
96	ret, _, _ := procBitBlt.Call(
97		uintptr(hdcDest),
98		uintptr(nXDest),
99		uintptr(nYDest),
100		uintptr(nWidth),
101		uintptr(nHeight),
102		uintptr(hdcSrc),
103		uintptr(nXSrc),
104		uintptr(nYSrc),
105		uintptr(dwRop))
106
107	if ret == 0 {
108		panic("BitBlt failed")
109	}
110}
111
112func CloseEnhMetaFile(hdc HDC) HENHMETAFILE {
113	ret, _, _ := procCloseEnhMetaFile.Call(
114		uintptr(hdc))
115
116	return HENHMETAFILE(ret)
117}
118
119func CopyEnhMetaFile(hemfSrc HENHMETAFILE, lpszFile *uint16) HENHMETAFILE {
120	ret, _, _ := procCopyEnhMetaFile.Call(
121		uintptr(hemfSrc),
122		uintptr(unsafe.Pointer(lpszFile)))
123
124	return HENHMETAFILE(ret)
125}
126
127func CreateBrushIndirect(lplb *LOGBRUSH) HBRUSH {
128	ret, _, _ := procCreateBrushIndirect.Call(
129		uintptr(unsafe.Pointer(lplb)))
130
131	return HBRUSH(ret)
132}
133
134func CreateCompatibleDC(hdc HDC) HDC {
135	ret, _, _ := procCreateCompatibleDC.Call(
136		uintptr(hdc))
137
138	if ret == 0 {
139		panic("Create compatible DC failed")
140	}
141
142	return HDC(ret)
143}
144
145func CreateDC(lpszDriver, lpszDevice, lpszOutput *uint16, lpInitData *DEVMODE) HDC {
146	ret, _, _ := procCreateDC.Call(
147		uintptr(unsafe.Pointer(lpszDriver)),
148		uintptr(unsafe.Pointer(lpszDevice)),
149		uintptr(unsafe.Pointer(lpszOutput)),
150		uintptr(unsafe.Pointer(lpInitData)))
151
152	return HDC(ret)
153}
154
155func CreateDIBSection(hdc HDC, pbmi *BITMAPINFO, iUsage uint, ppvBits *unsafe.Pointer, hSection HANDLE, dwOffset uint) HBITMAP {
156	ret, _, _ := procCreateDIBSection.Call(
157		uintptr(hdc),
158		uintptr(unsafe.Pointer(pbmi)),
159		uintptr(iUsage),
160		uintptr(unsafe.Pointer(ppvBits)),
161		uintptr(hSection),
162		uintptr(dwOffset))
163
164	return HBITMAP(ret)
165}
166
167func CreateEnhMetaFile(hdcRef HDC, lpFilename *uint16, lpRect *RECT, lpDescription *uint16) HDC {
168	ret, _, _ := procCreateEnhMetaFile.Call(
169		uintptr(hdcRef),
170		uintptr(unsafe.Pointer(lpFilename)),
171		uintptr(unsafe.Pointer(lpRect)),
172		uintptr(unsafe.Pointer(lpDescription)))
173
174	return HDC(ret)
175}
176
177func CreateIC(lpszDriver, lpszDevice, lpszOutput *uint16, lpdvmInit *DEVMODE) HDC {
178	ret, _, _ := procCreateIC.Call(
179		uintptr(unsafe.Pointer(lpszDriver)),
180		uintptr(unsafe.Pointer(lpszDevice)),
181		uintptr(unsafe.Pointer(lpszOutput)),
182		uintptr(unsafe.Pointer(lpdvmInit)))
183
184	return HDC(ret)
185}
186
187func DeleteDC(hdc HDC) bool {
188	ret, _, _ := procDeleteDC.Call(
189		uintptr(hdc))
190
191	return ret != 0
192}
193
194func DeleteEnhMetaFile(hemf HENHMETAFILE) bool {
195	ret, _, _ := procDeleteEnhMetaFile.Call(
196		uintptr(hemf))
197
198	return ret != 0
199}
200
201func Ellipse(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int) bool {
202	ret, _, _ := procEllipse.Call(
203		uintptr(hdc),
204		uintptr(nLeftRect),
205		uintptr(nTopRect),
206		uintptr(nRightRect),
207		uintptr(nBottomRect))
208
209	return ret != 0
210}
211
212func EndDoc(hdc HDC) int {
213	ret, _, _ := procEndDoc.Call(
214		uintptr(hdc))
215
216	return int(ret)
217}
218
219func EndPage(hdc HDC) int {
220	ret, _, _ := procEndPage.Call(
221		uintptr(hdc))
222
223	return int(ret)
224}
225
226func ExtCreatePen(dwPenStyle, dwWidth uint, lplb *LOGBRUSH, dwStyleCount uint, lpStyle *uint) HPEN {
227	ret, _, _ := procExtCreatePen.Call(
228		uintptr(dwPenStyle),
229		uintptr(dwWidth),
230		uintptr(unsafe.Pointer(lplb)),
231		uintptr(dwStyleCount),
232		uintptr(unsafe.Pointer(lpStyle)))
233
234	return HPEN(ret)
235}
236
237func GetEnhMetaFile(lpszMetaFile *uint16) HENHMETAFILE {
238	ret, _, _ := procGetEnhMetaFile.Call(
239		uintptr(unsafe.Pointer(lpszMetaFile)))
240
241	return HENHMETAFILE(ret)
242}
243
244func GetEnhMetaFileHeader(hemf HENHMETAFILE, cbBuffer uint, lpemh *ENHMETAHEADER) uint {
245	ret, _, _ := procGetEnhMetaFileHeader.Call(
246		uintptr(hemf),
247		uintptr(cbBuffer),
248		uintptr(unsafe.Pointer(lpemh)))
249
250	return uint(ret)
251}
252
253func GetObject(hgdiobj HGDIOBJ, cbBuffer uintptr, lpvObject unsafe.Pointer) int {
254	ret, _, _ := procGetObject.Call(
255		uintptr(hgdiobj),
256		uintptr(cbBuffer),
257		uintptr(lpvObject))
258
259	return int(ret)
260}
261
262func GetStockObject(fnObject int) HGDIOBJ {
263	ret, _, _ := procGetDeviceCaps.Call(
264		uintptr(fnObject))
265
266	return HGDIOBJ(ret)
267}
268
269func GetTextExtentExPoint(hdc HDC, lpszStr *uint16, cchString, nMaxExtent int, lpnFit, alpDx *int, lpSize *SIZE) bool {
270	ret, _, _ := procGetTextExtentExPoint.Call(
271		uintptr(hdc),
272		uintptr(unsafe.Pointer(lpszStr)),
273		uintptr(cchString),
274		uintptr(nMaxExtent),
275		uintptr(unsafe.Pointer(lpnFit)),
276		uintptr(unsafe.Pointer(alpDx)),
277		uintptr(unsafe.Pointer(lpSize)))
278
279	return ret != 0
280}
281
282func GetTextExtentPoint32(hdc HDC, lpString *uint16, c int, lpSize *SIZE) bool {
283	ret, _, _ := procGetTextExtentPoint32.Call(
284		uintptr(hdc),
285		uintptr(unsafe.Pointer(lpString)),
286		uintptr(c),
287		uintptr(unsafe.Pointer(lpSize)))
288
289	return ret != 0
290}
291
292func GetTextMetrics(hdc HDC, lptm *TEXTMETRIC) bool {
293	ret, _, _ := procGetTextMetrics.Call(
294		uintptr(hdc),
295		uintptr(unsafe.Pointer(lptm)))
296
297	return ret != 0
298}
299
300func LineTo(hdc HDC, nXEnd, nYEnd int) bool {
301	ret, _, _ := procLineTo.Call(
302		uintptr(hdc),
303		uintptr(nXEnd),
304		uintptr(nYEnd))
305
306	return ret != 0
307}
308
309func MoveToEx(hdc HDC, x, y int, lpPoint *POINT) bool {
310	ret, _, _ := procMoveToEx.Call(
311		uintptr(hdc),
312		uintptr(x),
313		uintptr(y),
314		uintptr(unsafe.Pointer(lpPoint)))
315
316	return ret != 0
317}
318
319func PlayEnhMetaFile(hdc HDC, hemf HENHMETAFILE, lpRect *RECT) bool {
320	ret, _, _ := procPlayEnhMetaFile.Call(
321		uintptr(hdc),
322		uintptr(hemf),
323		uintptr(unsafe.Pointer(lpRect)))
324
325	return ret != 0
326}
327
328func Rectangle(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int) bool {
329	ret, _, _ := procRectangle.Call(
330		uintptr(hdc),
331		uintptr(nLeftRect),
332		uintptr(nTopRect),
333		uintptr(nRightRect),
334		uintptr(nBottomRect))
335
336	return ret != 0
337}
338
339func ResetDC(hdc HDC, lpInitData *DEVMODE) HDC {
340	ret, _, _ := procResetDC.Call(
341		uintptr(hdc),
342		uintptr(unsafe.Pointer(lpInitData)))
343
344	return HDC(ret)
345}
346
347func SelectObject(hdc HDC, hgdiobj HGDIOBJ) HGDIOBJ {
348	ret, _, _ := procSelectObject.Call(
349		uintptr(hdc),
350		uintptr(hgdiobj))
351
352	if ret == 0 {
353		panic("SelectObject failed")
354	}
355
356	return HGDIOBJ(ret)
357}
358
359func SetBkMode(hdc HDC, iBkMode int) int {
360	ret, _, _ := procSetBkMode.Call(
361		uintptr(hdc),
362		uintptr(iBkMode))
363
364	if ret == 0 {
365		panic("SetBkMode failed")
366	}
367
368	return int(ret)
369}
370
371func SetBrushOrgEx(hdc HDC, nXOrg, nYOrg int, lppt *POINT) bool {
372	ret, _, _ := procSetBrushOrgEx.Call(
373		uintptr(hdc),
374		uintptr(nXOrg),
375		uintptr(nYOrg),
376		uintptr(unsafe.Pointer(lppt)))
377
378	return ret != 0
379}
380
381func SetStretchBltMode(hdc HDC, iStretchMode int) int {
382	ret, _, _ := procSetStretchBltMode.Call(
383		uintptr(hdc),
384		uintptr(iStretchMode))
385
386	return int(ret)
387}
388
389func SetTextColor(hdc HDC, crColor COLORREF) COLORREF {
390	ret, _, _ := procSetTextColor.Call(
391		uintptr(hdc),
392		uintptr(crColor))
393
394	if ret == CLR_INVALID {
395		panic("SetTextColor failed")
396	}
397
398	return COLORREF(ret)
399}
400
401func SetBkColor(hdc HDC, crColor COLORREF) COLORREF {
402	ret, _, _ := procSetBkColor.Call(
403		uintptr(hdc),
404		uintptr(crColor))
405
406	if ret == CLR_INVALID {
407		panic("SetBkColor failed")
408	}
409
410	return COLORREF(ret)
411}
412
413func StartDoc(hdc HDC, lpdi *DOCINFO) int {
414	ret, _, _ := procStartDoc.Call(
415		uintptr(hdc),
416		uintptr(unsafe.Pointer(lpdi)))
417
418	return int(ret)
419}
420
421func StartPage(hdc HDC) int {
422	ret, _, _ := procStartPage.Call(
423		uintptr(hdc))
424
425	return int(ret)
426}
427
428func StretchBlt(hdcDest HDC, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest int, hdcSrc HDC, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc int, dwRop uint) {
429	ret, _, _ := procStretchBlt.Call(
430		uintptr(hdcDest),
431		uintptr(nXOriginDest),
432		uintptr(nYOriginDest),
433		uintptr(nWidthDest),
434		uintptr(nHeightDest),
435		uintptr(hdcSrc),
436		uintptr(nXOriginSrc),
437		uintptr(nYOriginSrc),
438		uintptr(nWidthSrc),
439		uintptr(nHeightSrc),
440		uintptr(dwRop))
441
442	if ret == 0 {
443		panic("StretchBlt failed")
444	}
445}
446
447func SetDIBitsToDevice(hdc HDC, xDest, yDest, dwWidth, dwHeight, xSrc, ySrc int, uStartScan, cScanLines uint, lpvBits []byte, lpbmi *BITMAPINFO, fuColorUse uint) int {
448	ret, _, _ := procSetDIBitsToDevice.Call(
449		uintptr(hdc),
450		uintptr(xDest),
451		uintptr(yDest),
452		uintptr(dwWidth),
453		uintptr(dwHeight),
454		uintptr(xSrc),
455		uintptr(ySrc),
456		uintptr(uStartScan),
457		uintptr(cScanLines),
458		uintptr(unsafe.Pointer(&lpvBits[0])),
459		uintptr(unsafe.Pointer(lpbmi)),
460		uintptr(fuColorUse))
461
462	return int(ret)
463}
464
465func ChoosePixelFormat(hdc HDC, pfd *PIXELFORMATDESCRIPTOR) int {
466	ret, _, _ := procChoosePixelFormat.Call(
467		uintptr(hdc),
468		uintptr(unsafe.Pointer(pfd)),
469	)
470	return int(ret)
471}
472
473func DescribePixelFormat(hdc HDC, iPixelFormat int, nBytes uint, pfd *PIXELFORMATDESCRIPTOR) int {
474	ret, _, _ := procDescribePixelFormat.Call(
475		uintptr(hdc),
476		uintptr(iPixelFormat),
477		uintptr(nBytes),
478		uintptr(unsafe.Pointer(pfd)),
479	)
480	return int(ret)
481}
482
483func GetEnhMetaFilePixelFormat(hemf HENHMETAFILE, cbBuffer uint32, pfd *PIXELFORMATDESCRIPTOR) uint {
484	ret, _, _ := procGetEnhMetaFilePixelFormat.Call(
485		uintptr(hemf),
486		uintptr(cbBuffer),
487		uintptr(unsafe.Pointer(pfd)),
488	)
489	return uint(ret)
490}
491
492func GetPixelFormat(hdc HDC) int {
493	ret, _, _ := procGetPixelFormat.Call(
494		uintptr(hdc),
495	)
496	return int(ret)
497}
498
499func SetPixelFormat(hdc HDC, iPixelFormat int, pfd *PIXELFORMATDESCRIPTOR) bool {
500	ret, _, _ := procSetPixelFormat.Call(
501		uintptr(hdc),
502		uintptr(iPixelFormat),
503		uintptr(unsafe.Pointer(pfd)),
504	)
505	return ret == TRUE
506}
507
508func SwapBuffers(hdc HDC) bool {
509	ret, _, _ := procSwapBuffers.Call(uintptr(hdc))
510	return ret == TRUE
511}
512