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