font.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. // Font extension
  2. package al
  3. /*
  4. #cgo pkg-config: allegro_font-5
  5. #cgo CFLAGS: -I/usr/local/include
  6. #cgo linux LDFLAGS: -lc_nonshared
  7. #include <stdlib.h>
  8. #include <allegro5/allegro.h>
  9. #include <allegro5/allegro_font.h>
  10. #include "helpers.h"
  11. */
  12. import "C"
  13. import "runtime"
  14. import "unsafe"
  15. type Font struct {
  16. handle *C.ALLEGRO_FONT
  17. }
  18. const (
  19. ALIGN_LEFT = C.ALLEGRO_ALIGN_LEFT
  20. ALIGN_CENTRE = C.ALLEGRO_ALIGN_CENTRE
  21. ALIGN_CENTER = C.ALLEGRO_ALIGN_CENTER
  22. ALIGN_RIGHT = C.ALLEGRO_ALIGN_RIGHT
  23. ALIGN_INTEGER = C.ALLEGRO_ALIGN_INTEGER
  24. )
  25. // Converts a font to it's underlying C pointer
  26. func (self *Font) toC() *C.ALLEGRO_FONT {
  27. return (*C.ALLEGRO_FONT)(self.handle)
  28. }
  29. // Destroys the font.
  30. func (self *Font) Destroy() {
  31. if self.handle != nil {
  32. C.al_destroy_font(self.toC())
  33. }
  34. self.handle = nil
  35. }
  36. // Wraps a C font into a go font
  37. func wrapFontRaw(data *C.ALLEGRO_FONT) *Font {
  38. if data == nil {
  39. return nil
  40. }
  41. return &Font{data}
  42. }
  43. // Sets up a finalizer for this Font that calls Destroy()
  44. func (self *Font) SetDestroyFinalizer() *Font {
  45. if self != nil {
  46. runtime.SetFinalizer(self, func(me *Font) { me.Destroy() })
  47. }
  48. return self
  49. }
  50. // Wraps a C voice into a go mixer and sets up a finalizer that calls Destroy()
  51. func wrapFont(data *C.ALLEGRO_FONT) *Font {
  52. self := wrapFontRaw(data)
  53. return self.SetDestroyFinalizer()
  54. }
  55. /*
  56. TODO:
  57. ALLEGRO_FONT_FUNC(bool, al_register_font_loader, (const char *ext, ALLEGRO_FONT *(*load)(const char *filename, int size, int flags)));
  58. */
  59. func loadBitmapFont(filename string) *C.ALLEGRO_FONT {
  60. cfilename := cstr(filename)
  61. defer cstrFree(cfilename)
  62. return C.al_load_bitmap_font(cfilename)
  63. }
  64. func loadBitmapFontFlags(filename string, flags int) *C.ALLEGRO_FONT {
  65. cfilename := cstr(filename)
  66. defer cstrFree(cfilename)
  67. return C.al_load_bitmap_font_flags(cfilename, C.int(flags))
  68. }
  69. func loadFont(filename string, size, flags int) *C.ALLEGRO_FONT {
  70. cfilename := cstr(filename)
  71. defer cstrFree(cfilename)
  72. return C.al_load_font(cfilename, C.int(size), C.int(flags))
  73. }
  74. func (self *Bitmap) grabFont(ranges []int) *C.ALLEGRO_FONT {
  75. cn := C.int(len(ranges) / 2)
  76. cranges := (*C.int)(unsafe.Pointer(&ranges[0]))
  77. return C.al_grab_font_from_bitmap(self.handle, cn, cranges)
  78. }
  79. func createBuiltinFont() *C.ALLEGRO_FONT {
  80. return C.al_create_builtin_font()
  81. }
  82. // Loads a font from the give bitmap filename
  83. func LoadBitmapFontRaw(filename string) *Font {
  84. return wrapFontRaw(loadBitmapFont(filename))
  85. }
  86. // Loads a font from the give bitmap filename
  87. func LoadBitmapFont(filename string) *Font {
  88. return LoadBitmapFontRaw(filename).SetDestroyFinalizer()
  89. }
  90. // Loads a font from the give bitmap filename with the given flags
  91. func LoadBitmapFontFlagsRaw(filename string, flags int) *Font {
  92. return wrapFontRaw(loadBitmapFontFlags(filename, flags))
  93. }
  94. // Loads a font from the give bitmap filename with the given flags
  95. func LoadBitmapFontFlags(filename string, flags int) *Font {
  96. return LoadBitmapFontFlagsRaw(filename, flags).SetDestroyFinalizer()
  97. }
  98. // Loads a font from the give font filename with the given size and flags.
  99. func LoadFontRaw(filename string, size, flags int) *Font {
  100. return wrapFontRaw(loadFont(filename, size, flags))
  101. }
  102. // Loads a font from the give font filename with the given size and flags.
  103. func LoadFont(filename string, size, flags int) *Font {
  104. return LoadFontRaw(filename, size, flags).SetDestroyFinalizer()
  105. }
  106. // Converts this bitmap into a font
  107. func (self *Bitmap) GrabFontRaw(ranges []int) *Font {
  108. return wrapFontRaw(self.grabFont(ranges))
  109. }
  110. // Converts this bitmap into a font
  111. func (self *Bitmap) GrabFont(ranges []int) *Font {
  112. return self.GrabFontRaw(ranges).SetDestroyFinalizer()
  113. }
  114. // Creates a builtin font. It must be Destroy() when done using it just like any other font.
  115. func CreateBuiltinFontRaw() *Font {
  116. return wrapFontRaw(createBuiltinFont())
  117. }
  118. // Creates a builtin font. Has a finalizer set that will call Destroy().
  119. func CreateBuiltinFont() *Font {
  120. return wrapFont(createBuiltinFont())
  121. }
  122. // Ustr basics
  123. type Ustr struct {
  124. handle *C.ALLEGRO_USTR
  125. }
  126. // Converts a USTR to it's underlying C pointer
  127. func (self *Ustr) toC() *C.ALLEGRO_USTR {
  128. return (*C.ALLEGRO_USTR)(self.handle)
  129. }
  130. // Destroys the USTR.
  131. func (self *Ustr) Destroy() {
  132. if self.handle != nil {
  133. C.al_ustr_free(self.toC())
  134. }
  135. self.handle = nil
  136. }
  137. // Wraps a C USTR into a go font
  138. func wrapUstrRaw(data *C.ALLEGRO_USTR) *Ustr {
  139. if data == nil {
  140. return nil
  141. }
  142. return &Ustr{data}
  143. }
  144. // Sets up a finalizer for this Ustr that calls Destroy()
  145. func (self *Ustr) SetDestroyFinalizer() *Ustr {
  146. if self != nil {
  147. runtime.SetFinalizer(self, func(me *Ustr) { me.Destroy() })
  148. }
  149. return self
  150. }
  151. // Wraps a C Ustr into go Ustr and sets up a finalizer that calls Destroy()
  152. func wrapUstr(data *C.ALLEGRO_USTR) *Ustr {
  153. self := wrapUstrRaw(data)
  154. return self.SetDestroyFinalizer()
  155. }
  156. // Draws an allegro UTF8 string
  157. func (font *Font) DrawUstr(color Color, x, y float32, flags int, ustr *Ustr) {
  158. C.al_draw_ustr(font.toC(), color.toC(), C.float(x), C.float(y), C.int(flags), ustr.toC())
  159. }
  160. // Draws a C string
  161. func (font *Font) DrawText(color Color, x, y float32, flags int, text string) {
  162. ctext := cstr(text)
  163. defer cstrFree(ctext)
  164. C.al_draw_text(font.toC(), color.toC(), C.float(x), C.float(y), C.int(flags), ctext)
  165. }
  166. // Draws an allegro UTF8 string, justified
  167. func (font *Font) DrawJustifiedUstr(color Color, x1, x2, y, diff float32, flags int, ustr *Ustr) {
  168. C.al_draw_justified_ustr(font.toC(), color.toC(), cf(x1), cf(x2), cf(y), cf(diff), ci(flags), ustr.toC())
  169. }
  170. // Draws a C string, justified
  171. func (font *Font) DrawJustifiedText(color Color, x1, x2, y, diff float32, flags int, text string) {
  172. ctext := cstr(text)
  173. defer cstrFree(ctext)
  174. C.al_draw_justified_text(font.toC(), color.toC(), cf(x1), cf(x2), cf(y), cf(diff), ci(flags), ctext)
  175. }
  176. /*
  177. TODO (or even better, implement in Go)
  178. ALLEGRO_FONT_PRINTFUNC(void, al_draw_textf, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, char const *format, ...), 6, 7);
  179. ALLEGRO_FONT_PRINTFUNC(void, al_draw_justified_textf, (const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x1, float x2, float y, float diff, int flags, char const *format, ...), 8, 9);
  180. */
  181. // Gets the width of a UTF8 encoded string for this font.
  182. func (font *Font) UstrWidth(ustr *Ustr) int {
  183. return int(C.al_get_ustr_width(font.toC(), ustr.toC()))
  184. }
  185. // Gets the width of a string for this font.
  186. func (font *Font) TextWidth(text string) int {
  187. ctext := cstr(text)
  188. defer cstrFree(ctext)
  189. return int(C.al_get_text_width(font.toC(), ctext))
  190. }
  191. // Gets the line height of this font.
  192. func (font *Font) LineHeight() int {
  193. return int(C.al_get_font_line_height(font.toC()))
  194. }
  195. // Gets the ascent of this font.
  196. func (font *Font) Ascent() int {
  197. return int(C.al_get_font_ascent(font.toC()))
  198. }
  199. // Gets the descent of this font.
  200. func (font *Font) Descent() int {
  201. return int(C.al_get_font_descent(font.toC()))
  202. }
  203. // Gets the dimension of a UTF-8 text in this font.
  204. func (font *Font) UstrDimension(ustr *Ustr) (bbx, bby, bbw, bbh int) {
  205. var cbbx, cbby, cbbw, cbbh C.int
  206. C.al_get_ustr_dimensions(font.toC(), ustr.toC(), &cbbx, &cbby, &cbbw, &cbbh)
  207. return int(cbbx), int(cbby), int(cbbw), int(cbbh)
  208. }
  209. // Gets the dimension of a textthis font.
  210. func (font *Font) TextDimension(text string) (bbx, bby, bbw, bbh int) {
  211. ctext := cstr(text)
  212. defer cstrFree(ctext)
  213. var cbbx, cbby, cbbw, cbbh C.int
  214. C.al_get_text_dimensions(font.toC(), ctext, &cbbx, &cbby, &cbbw, &cbbh)
  215. return int(cbbx), int(cbby), int(cbbw), int(cbbh)
  216. }
  217. // Initializes the font addon
  218. func InitFontAddon() {
  219. C.al_init_font_addon()
  220. }
  221. // Close the font addon
  222. func ShutdownFontAddon() {
  223. C.al_init_font_addon()
  224. }
  225. // Gets the allegro font addon version
  226. func GetAllegroFontVersion() uint32 {
  227. return (uint32)(C.al_get_allegro_font_version())
  228. }
  229. // Gets the range of cvharacters supported bu the font
  230. // TODO: fix return value.
  231. /*
  232. func (font *Font) Ranges() (ranges []byte, count int) {
  233. count = int(C.al_get_font_ranges(font.toC(), 0, nil))
  234. size := count * 2 * C.sizeof(C.int)
  235. arr := malloc(count * 2 * C.sizeof(C.int))
  236. defer free(arr)
  237. C.al_get_font_ranges(font.toC(), ci(count), arr)
  238. ranges := C.GoBytes(arr, ci(size))
  239. return ranges, count
  240. }
  241. */
  242. /*
  243. ALLEGRO_FONT_FUNC(int, al_get_font_ranges, (ALLEGRO_FONT *font,
  244. int ranges_count, int *ranges));
  245. */