1 
2 //          Copyright Michael D. Parker 2018.
3 // Distributed under the Boost Software License, Version 1.0.
4 //    (See accompanying file LICENSE_1_0.txt or copy at
5 //          http://www.boost.org/LICENSE_1_0.txt)
6 
7 module bindbc.sdl.ttf;
8 
9 version(BindSDL_TTF):
10 
11 import core.stdc.config;
12 import bindbc.sdl.bind.sdlerror : SDL_GetError, SDL_SetError;
13 import bindbc.sdl.bind.sdlpixels : SDL_Color;
14 import bindbc.sdl.bind.sdlrwops : SDL_RWops;
15 import bindbc.sdl.bind.sdlsurface : SDL_Surface;
16 import bindbc.sdl.bind.sdlversion : SDL_version;
17 
18 alias TTF_SetError = SDL_SetError;
19 alias TTF_GetError = SDL_GetError;
20 
21 enum SDLTTFSupport {
22     noLibrary,
23     badLibrary,
24     sdlTTF2012 = 2012,
25     sdlTTF2013 = 2013,
26     sdlTTF2014 = 2014,
27 }
28 
29 enum ubyte SDL_TTF_MAJOR_VERSION = 2;
30 enum ubyte SDL_TTF_MINOR_VERSION = 0;
31 
32 version(SDL_TTF_2014) {
33     enum sdlTTFSupport = SDLTTFSupport.sdlTTF2014;
34     enum ubyte SDL_TTF_PATCHLEVEL = 14;
35 }
36 else version(SDL_TTF_2013) {
37     enum sdlTTFSupport = SDLTTFSupport.sdlTTF2013;
38     enum ubyte SDL_TTF_PATCHLEVEL = 13;
39 }
40 else {
41     enum sdlTTFSupport = SDLTTFSupport.sdlTTF2012;
42     enum ubyte SDL_TTF_PATCHLEVEL = 12;
43 }
44 
45 alias TTF_MAJOR_VERSION = SDL_TTF_MAJOR_VERSION;
46 alias TTF_MINOR_VERSION = SDL_TTF_MINOR_VERSION;
47 alias TTF_PATCHLEVEL = SDL_TTF_PATCHLEVEL;
48 
49 @nogc nothrow
50 void SDL_TTF_VERSION(SDL_version* X) {
51     X.major = SDL_TTF_MAJOR_VERSION;
52     X.minor = SDL_TTF_MINOR_VERSION;
53     X.patch = SDL_TTF_PATCHLEVEL;
54 }
55 alias TTF_VERSION = SDL_TTF_VERSION;
56 
57 enum {
58     UNICODE_BOM_NATIVE = 0xFEFF,
59     UNICODE_BOM_SWAPPED = 0xFFFE,
60     TTF_STYLE_NORMAL = 0x00,
61     TTF_STYLE_BOLD = 0x01,
62     TTF_STYLE_ITALIC = 0x02,
63     TTF_STYLE_UNDERLINE = 0x04,
64     TTF_STYLE_STRIKETHROUGH = 0x08,
65 }
66 
67 enum {
68     TTF_HINTING_NORMAL = 0,
69     TTF_HINTING_LIGHT = 1,
70     TTF_HINTING_MONO = 2,
71     TTF_HINTING_NONE = 3,
72 }
73 
74 struct TTF_Font;
75 
76 version(BindSDL_Static) {
77     extern(C) @nogc nothrow {
78         SDL_version* TTF_Linked_Version();
79         void TTF_ByteSwappedUNICODE(int);
80         int TTF_Init();
81         TTF_Font * TTF_OpenFont(const(char)*,int);
82         TTF_Font * TTF_OpenFontIndex(const(char)*,int,c_long );
83         TTF_Font * TTF_OpenFontRW(SDL_RWops*,int,int);
84         TTF_Font * TTF_OpenFontIndexRW(SDL_RWops*,int,int,c_long);
85         int TTF_GetFontStyle(const(TTF_Font)*);
86         void TTF_SetFontStyle(const(TTF_Font)*,int style);
87         int TTF_GetFontOutline(const(TTF_Font)*);
88         void TTF_SetFontOutline(TTF_Font*,int);
89         int TTF_GetFontHinting(const(TTF_Font)*);
90         void TTF_SetFontHinting(TTF_Font*,int);
91         int TTF_FontHeight(const(TTF_Font)*);
92         int TTF_FontAscent(const(TTF_Font)*);
93         int TTF_FontDescent(const(TTF_Font)*);
94         int TTF_FontLineSkip(const(TTF_Font)*);
95         int TTF_GetFontKerning(const(TTF_Font)*);
96         void TTF_SetFontKerning(TTF_Font*,int);
97         int TTF_FontFaces(const(TTF_Font)*);
98         int TTF_FontFaceIsFixedWidth(const(TTF_Font)*);
99         char* TTF_FontFaceFamilyName(const(TTF_Font)*);
100         char* TTF_FontFaceStyleName(const(TTF_Font)*);
101         int TTF_GlyphIsProvided(const(TTF_Font)*,ushort);
102         int TTF_GlyphMetrics(TTF_Font*,ushort,int*,int*,int*,int*,int*);
103         int TTF_SizeText(TTF_Font*,const(char)*,int*,int*);
104         int TTF_SizeUTF8(TTF_Font*,const(char)*,int*,int*);
105         int TTF_SizeUNICODE(TTF_Font*,ushort*,int*,int*);
106         SDL_Surface* TTF_RenderText_Solid(TTF_Font*,const(char)*,SDL_Color);
107         SDL_Surface* TTF_RenderUTF8_Solid(TTF_Font*,const(char)*,SDL_Color);
108         SDL_Surface* TTF_RenderUNICODE_Solid(TTF_Font*,const(ushort)*,SDL_Color);
109         SDL_Surface* TTF_RenderGlyph_Solid(TTF_Font*,ushort,SDL_Color);
110         SDL_Surface* TTF_RenderText_Shaded(TTF_Font*,const(char)*,SDL_Color,SDL_Color);
111         SDL_Surface* TTF_RenderUTF8_Shaded(TTF_Font*,const(char)*,SDL_Color,SDL_Color);
112         SDL_Surface* TTF_RenderUNICODE_Shaded(TTF_Font*,const(ushort)*,SDL_Color,SDL_Color);
113         SDL_Surface* TTF_RenderGlyph_Shaded(TTF_Font*,ushort,SDL_Color,SDL_Color);
114         SDL_Surface* TTF_RenderText_Blended(TTF_Font*,const(char)*,SDL_Color);
115         SDL_Surface* TTF_RenderUTF8_Blended(TTF_Font*,const(char)*,SDL_Color);
116         SDL_Surface* TTF_RenderUNICODE_Blended(TTF_Font*,const(ushort)*,SDL_Color);
117         SDL_Surface* TTF_RenderText_Blended_Wrapped(TTF_Font*,const(char)*,SDL_Color,uint);
118         SDL_Surface* TTF_RenderUTF8_Blended_Wrapped(TTF_Font*,const(char)*,SDL_Color,uint);
119         SDL_Surface* TTF_RenderUNICODE_Blended_Wrapped(TTF_Font*,const(ushort)*,SDL_Color,uint);
120         SDL_Surface* TTF_RenderGlyph_Blended(TTF_Font*,ushort,SDL_Color);
121         void TTF_CloseFont(TTF_Font*);
122         void TTF_Quit();
123         int TTF_WasInit();
124         int TTF_GetFontKerningSize(TTF_Font*,int,int);
125 
126         static if(sdlTTFSupport >= SDLTTFSupport.sdlTTF2014) {
127             int TTF_GetFontKerningSizeGlyphs(TTF_Font*,ushort,ushort);
128         }
129     }
130 }
131 else {
132     import bindbc.loader;
133 
134     extern(C) @nogc nothrow {
135         alias pTTF_Linked_Version = SDL_version* function();
136         alias pTTF_ByteSwappedUNICODE = void function(int);
137         alias pTTF_Init = int function();
138         alias pTTF_OpenFont = TTF_Font * function(const(char)*,int);
139         alias pTTF_OpenFontIndex = TTF_Font * function(const(char)*,int,c_long );
140         alias pTTF_OpenFontRW = TTF_Font * function(SDL_RWops*,int,int);
141         alias pTTF_OpenFontIndexRW = TTF_Font * function(SDL_RWops*,int,int,c_long);
142         alias pTTF_GetFontStyle = int function(const(TTF_Font)*);
143         alias pTTF_SetFontStyle = void function(const(TTF_Font)*,int style);
144         alias pTTF_GetFontOutline = int function(const(TTF_Font)*);
145         alias pTTF_SetFontOutline = void function(TTF_Font*,int);
146         alias pTTF_GetFontHinting = int function(const(TTF_Font)*);
147         alias pTTF_SetFontHinting = void function(TTF_Font*,int);
148         alias pTTF_FontHeight = int function(const(TTF_Font)*);
149         alias pTTF_FontAscent = int function(const(TTF_Font)*);
150         alias pTTF_FontDescent = int function(const(TTF_Font)*);
151         alias pTTF_FontLineSkip = int function(const(TTF_Font)*);
152         alias pTTF_GetFontKerning = int function(const(TTF_Font)*);
153         alias pTTF_SetFontKerning = void function(TTF_Font*,int);
154         alias pTTF_FontFaces = int function(const(TTF_Font)*);
155         alias pTTF_FontFaceIsFixedWidth = int function(const(TTF_Font)*);
156         alias pTTF_FontFaceFamilyName = char* function(const(TTF_Font)*);
157         alias pTTF_FontFaceStyleName = char* function(const(TTF_Font)*);
158         alias pTTF_GlyphIsProvided = int function(const(TTF_Font)*,ushort);
159         alias pTTF_GlyphMetrics = int function(TTF_Font*,ushort,int*,int*,int*,int*,int*);
160         alias pTTF_SizeText = int function(TTF_Font*,const(char)*,int*,int*);
161         alias pTTF_SizeUTF8 = int function(TTF_Font*,const(char)*,int*,int*);
162         alias pTTF_SizeUNICODE = int function(TTF_Font*,ushort*,int*,int*);
163         alias pTTF_RenderText_Solid = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color);
164         alias pTTF_RenderUTF8_Solid = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color);
165         alias pTTF_RenderUNICODE_Solid = SDL_Surface* function(TTF_Font*,const(ushort)*,SDL_Color);
166         alias pTTF_RenderGlyph_Solid = SDL_Surface* function(TTF_Font*,ushort,SDL_Color);
167         alias pTTF_RenderText_Shaded = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color,SDL_Color);
168         alias pTTF_RenderUTF8_Shaded = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color,SDL_Color);
169         alias pTTF_RenderUNICODE_Shaded = SDL_Surface* function(TTF_Font*,const(ushort)*,SDL_Color,SDL_Color);
170         alias pTTF_RenderGlyph_Shaded = SDL_Surface* function(TTF_Font*,ushort,SDL_Color,SDL_Color);
171         alias pTTF_RenderText_Blended = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color);
172         alias pTTF_RenderUTF8_Blended = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color);
173         alias pTTF_RenderUNICODE_Blended = SDL_Surface* function(TTF_Font*,const(ushort)*,SDL_Color);
174         alias pTTF_RenderText_Blended_Wrapped = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color,uint);
175         alias pTTF_RenderUTF8_Blended_Wrapped = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color,uint);
176         alias pTTF_RenderUNICODE_Blended_Wrapped = SDL_Surface* function(TTF_Font*,const(ushort)*,SDL_Color,uint);
177         alias pTTF_RenderGlyph_Blended = SDL_Surface* function(TTF_Font*,ushort,SDL_Color);
178         alias pTTF_CloseFont = void function(TTF_Font*);
179         alias pTTF_Quit = void function();
180         alias pTTF_WasInit = int function();
181         alias pTTF_GetFontKerningSize = int function(TTF_Font*,int,int);
182     }
183 
184     __gshared {
185         pTTF_Linked_Version TTF_Linked_Version;
186         pTTF_ByteSwappedUNICODE TTF_ByteSwappedUNICODE;
187         pTTF_Init TTF_Init;
188         pTTF_OpenFont TTF_OpenFont;
189         pTTF_OpenFontIndex TTF_OpenFontIndex;
190         pTTF_OpenFontRW TTF_OpenFontRW;
191         pTTF_OpenFontIndexRW TTF_OpenFontIndexRW;
192         pTTF_GetFontStyle TTF_GetFontStyle;
193         pTTF_SetFontStyle TTF_SetFontStyle;
194         pTTF_GetFontOutline TTF_GetFontOutline;
195         pTTF_SetFontOutline TTF_SetFontOutline;
196         pTTF_GetFontHinting TTF_GetFontHinting;
197         pTTF_SetFontHinting TTF_SetFontHinting;
198         pTTF_FontHeight TTF_FontHeight;
199         pTTF_FontAscent TTF_FontAscent;
200         pTTF_FontDescent TTF_FontDescent;
201         pTTF_FontLineSkip TTF_FontLineSkip;
202         pTTF_GetFontKerning TTF_GetFontKerning;
203         pTTF_SetFontKerning TTF_SetFontKerning;
204         pTTF_FontFaces TTF_FontFaces;
205         pTTF_FontFaceIsFixedWidth TTF_FontFaceIsFixedWidth;
206         pTTF_FontFaceFamilyName TTF_FontFaceFamilyName;
207         pTTF_FontFaceStyleName TTF_FontFaceStyleName;
208         pTTF_GlyphIsProvided TTF_GlyphIsProvided;
209         pTTF_GlyphMetrics TTF_GlyphMetrics;
210         pTTF_SizeText TTF_SizeText;
211         pTTF_SizeUTF8 TTF_SizeUTF8;
212         pTTF_SizeUNICODE TTF_SizeUNICODE;
213         pTTF_RenderText_Solid TTF_RenderText_Solid;
214         pTTF_RenderUTF8_Solid TTF_RenderUTF8_Solid;
215         pTTF_RenderUNICODE_Solid TTF_RenderUNICODE_Solid;
216         pTTF_RenderGlyph_Solid TTF_RenderGlyph_Solid;
217         pTTF_RenderText_Shaded TTF_RenderText_Shaded;
218         pTTF_RenderUTF8_Shaded TTF_RenderUTF8_Shaded;
219         pTTF_RenderUNICODE_Shaded TTF_RenderUNICODE_Shaded;
220         pTTF_RenderGlyph_Shaded TTF_RenderGlyph_Shaded;
221         pTTF_RenderText_Blended TTF_RenderText_Blended;
222         pTTF_RenderUTF8_Blended TTF_RenderUTF8_Blended;
223         pTTF_RenderUNICODE_Blended TTF_RenderUNICODE_Blended;
224         pTTF_RenderText_Blended_Wrapped TTF_RenderText_Blended_Wrapped;
225         pTTF_RenderUTF8_Blended_Wrapped TTF_RenderUTF8_Blended_Wrapped;
226         pTTF_RenderUNICODE_Blended_Wrapped TTF_RenderUNICODE_Blended_Wrapped;
227         pTTF_RenderGlyph_Blended TTF_RenderGlyph_Blended;
228         pTTF_CloseFont TTF_CloseFont;
229         pTTF_Quit TTF_Quit;
230         pTTF_WasInit TTF_WasInit;
231         pTTF_GetFontKerningSize TTF_GetFontKerningSize;
232     }
233 
234     static if(sdlTTFSupport >= SDLTTFSupport.sdlTTF2014) {
235         extern(C) @nogc nothrow {
236             alias pTTF_GetFontKerningSizeGlyphs = int function(TTF_Font*,ushort,ushort);
237         }
238 
239         __gshared {
240             pTTF_GetFontKerningSizeGlyphs TTF_GetFontKerningSizeGlyphs;
241         }
242     }
243 
244     private {
245         SharedLib lib;
246         SDLTTFSupport loadedVersion;
247     }
248 
249     void unloadSDLTTF()
250     {
251         if(lib != invalidHandle) {
252             lib.unload();
253         }
254     }
255 
256     SDLTTFSupport loadedSDLTTFVersion() { return loadedVersion; }
257 
258     bool isSDLTTFLoaded()
259     {
260         return  lib != invalidHandle;
261     }
262 
263     SDLTTFSupport loadSDLTTF()
264     {
265         version(Windows) {
266             const(char)[][1] libNames = ["SDL2_ttf.dll"];
267         }
268         else version(OSX) {
269             const(char)[][6] libNames = [
270                 "libSDL2_ttf.dylib",
271                 "/usr/local/lib/libSDL2_ttf.dylib",
272                 "../Frameworks/SDL2_ttf.framework/SDL2_ttf",
273                 "/Library/Frameworks/SDL2_ttf.framework/SDL2_ttf",
274                 "/System/Library/Frameworks/SDL2_ttf.framework/SDL2_ttf",
275                 "/opt/local/lib/libSDL2_ttf.dylib"
276             ];
277         }
278         else version(Posix) {
279             const(char)[][6] libNames = [
280                 "libSDL2_ttf.so",
281                 "/usr/local/lib/libSDL2_ttf.so",
282                 "libSDL2-2.0_ttf.so",
283                 "/usr/local/lib/libSDL2-2.0_ttf.so",
284                 "libSDL2-2.0_ttf.so.0",
285                 "/usr/local/lib/libSDL2-2.0_ttf.so.0"
286             ];
287         }
288         else static assert(0, "bindbc-sdl is not yet supported on this platform.");
289 
290         SDLTTFSupport ret;
291         foreach(name; libNames) {
292             ret = loadSDLTTF(name.ptr);
293             if(ret != SDLTTFSupport.noLibrary) break;
294         }
295         return ret;
296     }
297 
298     SDLTTFSupport loadSDLTTF(const(char)* libName)
299     {
300         lib = load(libName);
301         if(lib == invalidHandle) {
302             return SDLTTFSupport.noLibrary;
303         }
304 
305         auto errCount = errorCount();
306         loadedVersion = SDLTTFSupport.badLibrary;
307 
308         lib.bindSymbol(cast(void**)&TTF_Linked_Version,"TTF_Linked_Version");
309         lib.bindSymbol(cast(void**)&TTF_ByteSwappedUNICODE,"TTF_ByteSwappedUNICODE");
310         lib.bindSymbol(cast(void**)&TTF_Init,"TTF_Init");
311         lib.bindSymbol(cast(void**)&TTF_OpenFont,"TTF_OpenFont");
312         lib.bindSymbol(cast(void**)&TTF_OpenFontIndex,"TTF_OpenFontIndex");
313         lib.bindSymbol(cast(void**)&TTF_OpenFontRW,"TTF_OpenFontRW");
314         lib.bindSymbol(cast(void**)&TTF_OpenFontIndexRW,"TTF_OpenFontIndexRW");
315         lib.bindSymbol(cast(void**)&TTF_GetFontStyle,"TTF_GetFontStyle");
316         lib.bindSymbol(cast(void**)&TTF_SetFontStyle,"TTF_SetFontStyle");
317         lib.bindSymbol(cast(void**)&TTF_GetFontOutline,"TTF_GetFontOutline");
318         lib.bindSymbol(cast(void**)&TTF_SetFontOutline,"TTF_SetFontOutline");
319         lib.bindSymbol(cast(void**)&TTF_GetFontHinting,"TTF_GetFontHinting");
320         lib.bindSymbol(cast(void**)&TTF_SetFontHinting,"TTF_SetFontHinting");
321         lib.bindSymbol(cast(void**)&TTF_FontHeight,"TTF_FontHeight");
322         lib.bindSymbol(cast(void**)&TTF_FontAscent,"TTF_FontAscent");
323         lib.bindSymbol(cast(void**)&TTF_FontDescent,"TTF_FontDescent");
324         lib.bindSymbol(cast(void**)&TTF_FontLineSkip,"TTF_FontLineSkip");
325         lib.bindSymbol(cast(void**)&TTF_GetFontKerning,"TTF_GetFontKerning");
326         lib.bindSymbol(cast(void**)&TTF_SetFontKerning,"TTF_SetFontKerning");
327         lib.bindSymbol(cast(void**)&TTF_FontFaces,"TTF_FontFaces");
328         lib.bindSymbol(cast(void**)&TTF_FontFaceIsFixedWidth,"TTF_FontFaceIsFixedWidth");
329         lib.bindSymbol(cast(void**)&TTF_FontFaceFamilyName,"TTF_FontFaceFamilyName");
330         lib.bindSymbol(cast(void**)&TTF_FontFaceStyleName,"TTF_FontFaceStyleName");
331         lib.bindSymbol(cast(void**)&TTF_GlyphIsProvided,"TTF_GlyphIsProvided");
332         lib.bindSymbol(cast(void**)&TTF_GlyphMetrics,"TTF_GlyphMetrics");
333         lib.bindSymbol(cast(void**)&TTF_SizeText,"TTF_SizeText");
334         lib.bindSymbol(cast(void**)&TTF_SizeUTF8,"TTF_SizeUTF8");
335         lib.bindSymbol(cast(void**)&TTF_SizeUNICODE,"TTF_SizeUNICODE");
336         lib.bindSymbol(cast(void**)&TTF_RenderText_Solid,"TTF_RenderText_Solid");
337         lib.bindSymbol(cast(void**)&TTF_RenderUTF8_Solid,"TTF_RenderUTF8_Solid");
338         lib.bindSymbol(cast(void**)&TTF_RenderUNICODE_Solid,"TTF_RenderUNICODE_Solid");
339         lib.bindSymbol(cast(void**)&TTF_RenderGlyph_Solid,"TTF_RenderGlyph_Solid");
340         lib.bindSymbol(cast(void**)&TTF_RenderText_Shaded,"TTF_RenderText_Shaded");
341         lib.bindSymbol(cast(void**)&TTF_RenderUTF8_Shaded,"TTF_RenderUTF8_Shaded");
342         lib.bindSymbol(cast(void**)&TTF_RenderUNICODE_Shaded,"TTF_RenderUNICODE_Shaded");
343         lib.bindSymbol(cast(void**)&TTF_RenderGlyph_Shaded,"TTF_RenderGlyph_Shaded");
344         lib.bindSymbol(cast(void**)&TTF_RenderText_Blended,"TTF_RenderText_Blended");
345         lib.bindSymbol(cast(void**)&TTF_RenderUTF8_Blended,"TTF_RenderUTF8_Blended");
346         lib.bindSymbol(cast(void**)&TTF_RenderUNICODE_Blended,"TTF_RenderUNICODE_Blended");
347         lib.bindSymbol(cast(void**)&TTF_RenderText_Blended_Wrapped,"TTF_RenderText_Blended_Wrapped");
348         lib.bindSymbol(cast(void**)&TTF_RenderUTF8_Blended_Wrapped,"TTF_RenderUTF8_Blended_Wrapped");
349         lib.bindSymbol(cast(void**)&TTF_RenderUNICODE_Blended_Wrapped,"TTF_RenderUNICODE_Blended_Wrapped");
350         lib.bindSymbol(cast(void**)&TTF_RenderGlyph_Blended,"TTF_RenderGlyph_Blended");
351         lib.bindSymbol(cast(void**)&TTF_CloseFont,"TTF_CloseFont");
352         lib.bindSymbol(cast(void**)&TTF_Quit,"TTF_Quit");
353         lib.bindSymbol(cast(void**)&TTF_WasInit,"TTF_WasInit");
354         lib.bindSymbol(cast(void**)&TTF_GetFontKerningSize,"TTF_GetFontKerningSize");
355 
356         if(errorCount() != errCount) return SDLTTFSupport.badLibrary;
357         else loadedVersion = SDLTTFSupport.sdlTTF2012;
358 
359         static if(sdlTTFSupport >= SDLTTFSupport.sdlTTF2014) {
360             lib.bindSymbol(cast(void**)&TTF_GetFontKerningSizeGlyphs,"TTF_GetFontKerningSizeGlyphs");
361 
362             if(errorCount() != errCount) return SDLTTFSupport.badLibrary;
363             else loadedVersion = SDLTTFSupport.sdlTTF2014;
364         }
365 
366         return loadedVersion;
367     }
368 }