gdiplus.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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. // +build windows
  5. package w32
  6. import (
  7. "errors"
  8. "fmt"
  9. "syscall"
  10. "unsafe"
  11. )
  12. const (
  13. Ok = 0
  14. GenericError = 1
  15. InvalidParameter = 2
  16. OutOfMemory = 3
  17. ObjectBusy = 4
  18. InsufficientBuffer = 5
  19. NotImplemented = 6
  20. Win32Error = 7
  21. WrongState = 8
  22. Aborted = 9
  23. FileNotFound = 10
  24. ValueOverflow = 11
  25. AccessDenied = 12
  26. UnknownImageFormat = 13
  27. FontFamilyNotFound = 14
  28. FontStyleNotFound = 15
  29. NotTrueTypeFont = 16
  30. UnsupportedGdiplusVersion = 17
  31. GdiplusNotInitialized = 18
  32. PropertyNotFound = 19
  33. PropertyNotSupported = 20
  34. ProfileNotFound = 21
  35. )
  36. func GetGpStatus(s int32) string {
  37. switch s {
  38. case Ok:
  39. return "Ok"
  40. case GenericError:
  41. return "GenericError"
  42. case InvalidParameter:
  43. return "InvalidParameter"
  44. case OutOfMemory:
  45. return "OutOfMemory"
  46. case ObjectBusy:
  47. return "ObjectBusy"
  48. case InsufficientBuffer:
  49. return "InsufficientBuffer"
  50. case NotImplemented:
  51. return "NotImplemented"
  52. case Win32Error:
  53. return "Win32Error"
  54. case WrongState:
  55. return "WrongState"
  56. case Aborted:
  57. return "Aborted"
  58. case FileNotFound:
  59. return "FileNotFound"
  60. case ValueOverflow:
  61. return "ValueOverflow"
  62. case AccessDenied:
  63. return "AccessDenied"
  64. case UnknownImageFormat:
  65. return "UnknownImageFormat"
  66. case FontFamilyNotFound:
  67. return "FontFamilyNotFound"
  68. case FontStyleNotFound:
  69. return "FontStyleNotFound"
  70. case NotTrueTypeFont:
  71. return "NotTrueTypeFont"
  72. case UnsupportedGdiplusVersion:
  73. return "UnsupportedGdiplusVersion"
  74. case GdiplusNotInitialized:
  75. return "GdiplusNotInitialized"
  76. case PropertyNotFound:
  77. return "PropertyNotFound"
  78. case PropertyNotSupported:
  79. return "PropertyNotSupported"
  80. case ProfileNotFound:
  81. return "ProfileNotFound"
  82. }
  83. return "Unknown Status Value"
  84. }
  85. var (
  86. token uintptr
  87. modgdiplus = syscall.NewLazyDLL("gdiplus.dll")
  88. procGdipCreateBitmapFromFile = modgdiplus.NewProc("GdipCreateBitmapFromFile")
  89. procGdipCreateBitmapFromHBITMAP = modgdiplus.NewProc("GdipCreateBitmapFromHBITMAP")
  90. procGdipCreateHBITMAPFromBitmap = modgdiplus.NewProc("GdipCreateHBITMAPFromBitmap")
  91. procGdipCreateBitmapFromResource = modgdiplus.NewProc("GdipCreateBitmapFromResource")
  92. procGdipCreateBitmapFromStream = modgdiplus.NewProc("GdipCreateBitmapFromStream")
  93. procGdipDisposeImage = modgdiplus.NewProc("GdipDisposeImage")
  94. procGdiplusShutdown = modgdiplus.NewProc("GdiplusShutdown")
  95. procGdiplusStartup = modgdiplus.NewProc("GdiplusStartup")
  96. )
  97. func GdipCreateBitmapFromFile(filename string) (*uintptr, error) {
  98. var bitmap *uintptr
  99. ret, _, _ := procGdipCreateBitmapFromFile.Call(
  100. uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(filename))),
  101. uintptr(unsafe.Pointer(&bitmap)))
  102. if ret != Ok {
  103. return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromFile failed with status '%s' for file '%s'", GetGpStatus(int32(ret)), filename))
  104. }
  105. return bitmap, nil
  106. }
  107. func GdipCreateBitmapFromResource(instance HINSTANCE, resId *uint16) (*uintptr, error) {
  108. var bitmap *uintptr
  109. ret, _, _ := procGdipCreateBitmapFromResource.Call(
  110. uintptr(instance),
  111. uintptr(unsafe.Pointer(resId)),
  112. uintptr(unsafe.Pointer(&bitmap)))
  113. if ret != Ok {
  114. return nil, errors.New(fmt.Sprintf("GdiCreateBitmapFromResource failed with status '%s'", GetGpStatus(int32(ret))))
  115. }
  116. return bitmap, nil
  117. }
  118. func GdipCreateBitmapFromStream(stream *IStream) (*uintptr, error) {
  119. var bitmap *uintptr
  120. ret, _, _ := procGdipCreateBitmapFromStream.Call(
  121. uintptr(unsafe.Pointer(stream)),
  122. uintptr(unsafe.Pointer(&bitmap)))
  123. if ret != Ok {
  124. return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromStream failed with status '%s'", GetGpStatus(int32(ret))))
  125. }
  126. return bitmap, nil
  127. }
  128. func GdipCreateHBITMAPFromBitmap(bitmap *uintptr, background uint32) (HBITMAP, error) {
  129. var hbitmap HBITMAP
  130. ret, _, _ := procGdipCreateHBITMAPFromBitmap.Call(
  131. uintptr(unsafe.Pointer(bitmap)),
  132. uintptr(unsafe.Pointer(&hbitmap)),
  133. uintptr(background))
  134. if ret != Ok {
  135. return 0, errors.New(fmt.Sprintf("GdipCreateHBITMAPFromBitmap failed with status '%s'", GetGpStatus(int32(ret))))
  136. }
  137. return hbitmap, nil
  138. }
  139. func GdipDisposeImage(image *uintptr) {
  140. procGdipDisposeImage.Call(uintptr(unsafe.Pointer(image)))
  141. }
  142. func GdiplusShutdown() {
  143. procGdiplusShutdown.Call(token)
  144. }
  145. func GdiplusStartup(input *GdiplusStartupInput, output *GdiplusStartupOutput) {
  146. ret, _, _ := procGdiplusStartup.Call(
  147. uintptr(unsafe.Pointer(&token)),
  148. uintptr(unsafe.Pointer(input)),
  149. uintptr(unsafe.Pointer(output)))
  150. if ret != Ok {
  151. panic("GdiplusStartup failed with status " + GetGpStatus(int32(ret)))
  152. }
  153. }