1 module gfm.sdl2.sdlttf; 2 3 import std.string; 4 5 import derelict.sdl2.sdl, 6 derelict.sdl2.ttf, 7 derelict.util.exception; 8 9 import std.experimental.logger; 10 11 import gfm.sdl2.sdl, 12 gfm.sdl2.surface; 13 14 /// SDL_ttf library wrapper. 15 final class SDLTTF 16 { 17 public 18 { 19 /// Loads the SDL_ttf library. 20 /// Throws: $(D SDL2Exception) on error. 21 this(SDL2 sdl2) 22 { 23 _sdl2 = sdl2; // force loading of SDL first 24 _logger = sdl2._logger; 25 _SDLTTFInitialized = false; 26 27 try 28 { 29 DerelictSDL2ttf.load(); 30 } 31 catch(DerelictException e) 32 { 33 throw new SDL2Exception(e.msg); 34 } 35 36 int res = TTF_Init(); 37 if (res != 0) 38 throwSDL2TTFException("TTF_Init"); 39 40 _SDLTTFInitialized = true; 41 } 42 43 /// Releases the SDL_ttf library. 44 ~this() 45 { 46 if (_SDLTTFInitialized) 47 { 48 debug ensureNotInGC("SDLTTF"); 49 _SDLTTFInitialized = false; 50 TTF_Quit(); 51 } 52 } 53 } 54 55 private 56 { 57 Logger _logger; 58 SDL2 _sdl2; 59 bool _SDLTTFInitialized; 60 61 void throwSDL2TTFException(string callThatFailed) 62 { 63 string message = format("%s failed: %s", callThatFailed, getErrorString()); 64 throw new SDL2Exception(message); 65 } 66 67 const(char)[] getErrorString() 68 { 69 return fromStringz(TTF_GetError()); 70 } 71 } 72 } 73 74 /// SDL_ttf loaded font wrapper. 75 final class SDLFont 76 { 77 public 78 { 79 /// Loads a font from a file. 80 /// Params: 81 /// sdlttf = library object. 82 /// filename = path of the font file. 83 /// ptSize = font size in 72 dpi ("This basically translates to pixel height" says the doc). 84 /// Throws: $(D SDL2Exception) on error. 85 this(SDLTTF sdlttf, string filename, int ptSize) 86 { 87 _sdlttf = sdlttf; 88 _font = TTF_OpenFont(toStringz(filename), ptSize); 89 if (_font is null) 90 _sdlttf.throwSDL2TTFException("TTF_OpenFont"); 91 } 92 93 /// Releases the SDL resource. 94 ~this() 95 { 96 if (_font !is null) 97 { 98 debug ensureNotInGC("SDLFont"); 99 TTF_CloseFont(_font); 100 _font = null; 101 } 102 } 103 104 /// Returns: Font style. 105 int style() 106 { 107 return TTF_GetFontStyle(_font); 108 } 109 110 /// Set font style. 111 int setStyle(int newStyle) 112 { 113 if (newStyle != TTF_GetFontStyle(_font)) 114 TTF_SetFontStyle(_font, newStyle); 115 return newStyle; 116 } 117 118 /// Returns: Font hinting. 119 int hinting() 120 { 121 return TTF_GetFontHinting(_font); 122 } 123 124 /// Set font hinting. 125 int setHinting(int newHinting) 126 { 127 if (newHinting != TTF_GetFontHinting(_font)) 128 TTF_SetFontHinting(_font, newHinting); 129 return newHinting; 130 } 131 132 /// Returns: Font outline. 133 int outline() 134 { 135 return TTF_GetFontOutline(_font); 136 } 137 138 /// Set font outline. 139 int setOutline(int newOutline) 140 { 141 if (newOutline != TTF_GetFontOutline(_font)) 142 TTF_SetFontOutline(_font, newOutline); 143 return newOutline; 144 } 145 146 /// Returns: true if kerning is enabled. 147 bool getKerning() 148 { 149 return TTF_GetFontKerning(_font) != 0; 150 } 151 152 /// Enables/Disables font kerning. 153 bool setKerning(bool enabled) 154 { 155 TTF_SetFontKerning(_font, enabled ? 1 : 0); 156 return enabled; 157 } 158 159 /// Returns: Maximum height of a glyph in pixels. 160 int height() 161 { 162 return TTF_FontAscent(_font); 163 } 164 165 /// Returns: Height above baseline in pixels. 166 int ascent() 167 { 168 return TTF_FontAscent(_font); 169 } 170 171 /// Returns: Height below baseline. 172 int descent() 173 { 174 return TTF_FontDescent(_font); 175 } 176 177 /// Returns: Line skip, the recommended pixel interval between two lines. 178 int lineSkip() 179 { 180 return TTF_FontLineSkip(_font); 181 } 182 183 /// Returns: Size of text in pixels if rendered with this font. 184 SDL_Point measureText(string text) 185 { 186 int w, h; 187 TTF_SizeUTF8(_font, toStringz(text), &w, &h); 188 return SDL_Point(w, h); 189 } 190 191 /// Create a 32-bit ARGB surface and render the given character at high quality, 192 /// using alpha blending to dither the font with the given color. 193 /// Throws: $(D SDL2Exception) on error. 194 SDL2Surface renderGlyphBlended(dchar ch, SDL_Color color) 195 { 196 return checkedSurface(TTF_RenderGlyph_Blended(_font, cast(ushort)ch, color)); 197 } 198 199 /// Create a 32-bit ARGB surface and render the given text at high quality, 200 /// using alpha blending to dither the font with the given color. 201 /// Throws: $(D SDL2Exception) on error. 202 SDL2Surface renderTextBlended(string text, SDL_Color color) 203 { 204 return checkedSurface(TTF_RenderUTF8_Blended(_font, toStringz(text), color)); 205 } 206 207 /// Create an 8-bit palettized surface and render the given text at fast 208 /// quality with the given font and color. 209 /// Throws: $(D SDL2Exception) on error. 210 SDL2Surface renderTextSolid(string text, SDL_Color color) 211 { 212 return checkedSurface(TTF_RenderUTF8_Solid(_font, toStringz(text), color)); 213 } 214 215 /// Create an 8-bit palettized surface and render the given text at high 216 /// quality with the given font and colors. 217 /// Throws: $(D SDL2Exception) on error. 218 SDL2Surface renderTextShaded(string text, SDL_Color fg, SDL_Color bg) 219 { 220 return checkedSurface(TTF_RenderUTF8_Shaded(_font, toStringz(text), fg, bg)); 221 } 222 223 /// Create a 32-bit ARGB surface and render the given text at high quality, 224 /// using alpha blending to dither the font with the given color. 225 /// Uses multi-line text wrapping. 226 /// Throws: $(D SDL2Exception) on error. 227 SDL2Surface renderTextBlendedWrapped(string text, SDL_Color color, uint wrapLength) 228 { 229 return checkedSurface(TTF_RenderUTF8_Blended_Wrapped(_font, toStringz(text), color, wrapLength)); 230 } 231 } 232 233 private 234 { 235 SDLTTF _sdlttf; 236 TTF_Font *_font; 237 238 SDL2Surface checkedSurface(SDL_Surface* s) 239 { 240 if (s is null) 241 _sdlttf.throwSDL2TTFException("TTF_Render"); 242 return new SDL2Surface(_sdlttf._sdl2, s, SDL2Surface.Owned.YES); 243 } 244 } 245 }