1 /* 2 ******************************************************************************************* 3 * Dgame (a D game framework) - Copyright (c) Randy Schütt 4 * 5 * This software is provided 'as-is', without any express or implied warranty. 6 * In no event will the authors be held liable for any damages arising from 7 * the use of this software. 8 * 9 * Permission is granted to anyone to use this software for any purpose, 10 * including commercial applications, and to alter it and redistribute it 11 * freely, subject to the following restrictions: 12 * 13 * 1. The origin of this software must not be misrepresented; you must not claim 14 * that you wrote the original software. If you use this software in a product, 15 * an acknowledgment in the product documentation would be appreciated but is 16 * not required. 17 * 18 * 2. Altered source versions must be plainly marked as such, and must not be 19 * misrepresented as being the original software. 20 * 21 * 3. This notice may not be removed or altered from any source distribution. 22 ******************************************************************************************* 23 */ 24 module Dgame.System.Font; 25 26 private: 27 28 import derelict.sdl2.types; 29 import derelict.sdl2.ttf; 30 31 import Dgame.Graphic.Color; 32 import Dgame.Graphic.Surface; 33 34 import Dgame.Internal.Error; 35 import Dgame.Internal.d2c; 36 37 enum ubyte MinDepth = 24; 38 39 public: 40 41 /** 42 * Font is the low-level class for loading and manipulating character fonts. 43 * This class is meant to be used by Dgame.Graphic.Text. 44 * 45 * Author: Randy Schuett (rswhite4@googlemail.com) 46 */ 47 struct Font { 48 private: 49 TTF_Font* _ttf; 50 ubyte _fontSize; 51 52 public: 53 /** 54 * The default size of every Font is 10 55 */ 56 enum ubyte DefaultSize = 10; 57 58 /** 59 * Available Font styles 60 */ 61 enum Style { 62 Normal = TTF_STYLE_NORMAL, /// Used to indicate regular, normal, plain rendering style. 63 Bold = TTF_STYLE_BOLD, /// Used to indicate bold rendering style.This is used in a bitmask along with other styles. 64 Italic = TTF_STYLE_ITALIC, /// Used to indicate italicized rendering style.This is used in a bitmask along with other styles. 65 Underline = TTF_STYLE_UNDERLINE, /// Used to indicate underlined rendering style.This is used in a bitmask along with other styles. 66 StrikeThrough = TTF_STYLE_STRIKETHROUGH /// Used to indicate strikethrough rendering style.This is used in a bitmask along with other styles. 67 } 68 69 /** 70 * Available Font modes 71 */ 72 enum Mode : ubyte { 73 Solid, /// Solid 74 Shaded, /// Shaded 75 Blended /// Blended 76 } 77 78 /** 79 * CTor 80 */ 81 @nogc 82 this(string filename, ubyte fontSize) nothrow { 83 this.loadFromFile(filename, fontSize); 84 } 85 86 /** 87 * Postblit is disabled 88 */ 89 @disable 90 this(this); 91 92 /** 93 * DTor 94 */ 95 @nogc 96 ~this() nothrow { 97 TTF_CloseFont(_ttf); 98 } 99 100 /** 101 * Load the font from a file. 102 * Returns if the loading was successful. 103 * If not, an error message is shown, which describes the problem. 104 * If the second parameter isn't 0, the current font size will be replaced with that. 105 * If the current size is also 0, the DefaultSize (10) will be used. 106 * 107 * See: DefaultSize 108 */ 109 @nogc 110 bool loadFromFile(string filename, ubyte fontSize) nothrow { 111 _fontSize = fontSize == 0 ? DefaultSize : fontSize; 112 _ttf = TTF_OpenFont(toStringz(filename), _fontSize); 113 if (!_ttf) { 114 print_fmt("Error by loading TTF_Font %s: %s\n", toStringz(filename), TTF_GetError()); 115 return false; 116 } 117 118 return true; 119 } 120 121 /** 122 * Set the Font style. 123 * 124 * See: Font.Style enum 125 */ 126 @nogc 127 void setStyle(Style style) nothrow { 128 if (_ttf) 129 TTF_SetFontStyle(_ttf, style); 130 } 131 132 /** 133 * Returns the current Font style. 134 * 135 * See: Font.Style enum 136 */ 137 @nogc 138 Style getStyle() const nothrow { 139 if (_ttf) 140 return cast(Style) TTF_GetFontStyle(_ttf); 141 return Style.Normal; 142 } 143 144 /** 145 * Draws the text on a Surface by using this Font and the given Mode (default is Mode.Solid) 146 * The text (and the Surface) is colorized by fg / bg Color. 147 * 148 * Note: The background color is ignored if your mode is not Font.Mode.Shaded 149 * 150 * Returns a Surface with the text or throws an Error 151 */ 152 @nogc 153 Surface render(string text, const Color4b fg, const Color4b bg, Mode mode = Mode.Solid) nothrow { 154 assert(_ttf, "Font is invalid"); 155 156 SDL_Color a = void; 157 SDL_Color b = void; 158 159 _transfer(fg, a); 160 _transfer(bg, b); 161 162 SDL_Surface* sdl_srfc; 163 final switch (mode) { 164 case Mode.Solid: 165 sdl_srfc = TTF_RenderUTF8_Solid(_ttf, toStringz(text), a); 166 break; 167 case Mode.Shaded: 168 sdl_srfc = TTF_RenderUTF8_Shaded(_ttf, toStringz(text), a, b); 169 break; 170 case Mode.Blended: 171 sdl_srfc = TTF_RenderUTF8_Blended(_ttf, toStringz(text), a); 172 break; 173 } 174 175 assert_fmt(sdl_srfc, "Error by rendering text: %s", TTF_GetError()); 176 177 Surface srfc = Surface(sdl_srfc); 178 if (srfc.bits < MinDepth) 179 srfc.adaptTo(MinDepth); 180 181 return srfc; 182 } 183 }