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