1 /** 2 DynamicFont renders vector font files at runtime. 3 4 Copyright: 5 Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. 6 Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) 7 Copyright (c) 2017-2018 Godot-D contributors 8 9 License: $(LINK2 https://opensource.org/licenses/MIT, MIT License) 10 11 12 */ 13 module godot.dynamicfont; 14 import std.meta : AliasSeq, staticIndexOf; 15 import std.traits : Unqual; 16 import godot.d.traits; 17 import godot.core; 18 import godot.c; 19 import godot.d.bind; 20 import godot.d.reference; 21 import godot.globalenums; 22 import godot.object; 23 import godot.classdb; 24 import godot.font; 25 import godot.dynamicfontdata; 26 /** 27 DynamicFont renders vector font files at runtime. 28 29 DynamicFont renders vector font files (such as TTF or OTF) dynamically at runtime instead of using a prerendered texture atlas like $(D BitmapFont). This trades the faster loading time of $(D BitmapFont)s for the ability to change font parameters like size and spacing during runtime. $(D DynamicFontData) is used for referencing the font file paths. DynamicFont also supports defining one or more fallback fonts, which will be used when displaying a character not supported by the main font. 30 DynamicFont uses the $(D url=https://www.freetype.org/)FreeType$(D /url) library for rasterization. 31 32 33 var dynamic_font = DynamicFont.new() 34 dynamic_font.font_data = load("res://BarlowCondensed-Bold.ttf") 35 dynamic_font.size = 64 36 $"Label".set("custom_fonts/font", dynamic_font) 37 38 39 $(B Note:) DynamicFont doesn't support features such as kerning, right-to-left typesetting, ligatures, text shaping, variable fonts and optional font features yet. If you wish to "bake" an optional font feature into a TTF font file, you can use $(D url=https://fontforge.org/)FontForge$(D /url) to do so. In FontForge, use $(B File > Generate Fonts), click $(B Options), choose the desired features then generate the font. 40 */ 41 @GodotBaseClass struct DynamicFont 42 { 43 package(godot) enum string _GODOT_internal_name = "DynamicFont"; 44 public: 45 @nogc nothrow: 46 union { /** */ godot_object _godot_object; /** */ Font _GODOT_base; } 47 alias _GODOT_base this; 48 alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses); 49 package(godot) __gshared bool _classBindingInitialized = false; 50 package(godot) static struct GDNativeClassBinding 51 { 52 __gshared: 53 @GodotName("add_fallback") GodotMethod!(void, DynamicFontData) addFallback; 54 @GodotName("get_available_chars") GodotMethod!(String) getAvailableChars; 55 @GodotName("get_fallback") GodotMethod!(DynamicFontData, long) getFallback; 56 @GodotName("get_fallback_count") GodotMethod!(long) getFallbackCount; 57 @GodotName("get_font_data") GodotMethod!(DynamicFontData) getFontData; 58 @GodotName("get_outline_color") GodotMethod!(Color) getOutlineColor; 59 @GodotName("get_outline_size") GodotMethod!(long) getOutlineSize; 60 @GodotName("get_size") GodotMethod!(long) getSize; 61 @GodotName("get_spacing") GodotMethod!(long, long) getSpacing; 62 @GodotName("get_use_filter") GodotMethod!(bool) getUseFilter; 63 @GodotName("get_use_mipmaps") GodotMethod!(bool) getUseMipmaps; 64 @GodotName("remove_fallback") GodotMethod!(void, long) removeFallback; 65 @GodotName("set_fallback") GodotMethod!(void, long, DynamicFontData) setFallback; 66 @GodotName("set_font_data") GodotMethod!(void, DynamicFontData) setFontData; 67 @GodotName("set_outline_color") GodotMethod!(void, Color) setOutlineColor; 68 @GodotName("set_outline_size") GodotMethod!(void, long) setOutlineSize; 69 @GodotName("set_size") GodotMethod!(void, long) setSize; 70 @GodotName("set_spacing") GodotMethod!(void, long, long) setSpacing; 71 @GodotName("set_use_filter") GodotMethod!(void, bool) setUseFilter; 72 @GodotName("set_use_mipmaps") GodotMethod!(void, bool) setUseMipmaps; 73 } 74 /// 75 pragma(inline, true) bool opEquals(in DynamicFont other) const 76 { return _godot_object.ptr is other._godot_object.ptr; } 77 /// 78 pragma(inline, true) typeof(null) opAssign(typeof(null) n) 79 { _godot_object.ptr = n; return null; } 80 /// 81 pragma(inline, true) bool opEquals(typeof(null) n) const 82 { return _godot_object.ptr is n; } 83 /// 84 size_t toHash() const @trusted { return cast(size_t)_godot_object.ptr; } 85 mixin baseCasts; 86 /// Construct a new instance of DynamicFont. 87 /// Note: use `memnew!DynamicFont` instead. 88 static DynamicFont _new() 89 { 90 static godot_class_constructor constructor; 91 if(constructor is null) constructor = _godot_api.godot_get_class_constructor("DynamicFont"); 92 if(constructor is null) return typeof(this).init; 93 return cast(DynamicFont)(constructor()); 94 } 95 @disable new(size_t s); 96 /// 97 enum SpacingType : int 98 { 99 /** 100 Spacing at the top. 101 */ 102 spacingTop = 0, 103 /** 104 Spacing at the bottom. 105 */ 106 spacingBottom = 1, 107 /** 108 Spacing for each character. 109 */ 110 spacingChar = 2, 111 /** 112 Spacing for the space character. 113 */ 114 spacingSpace = 3, 115 } 116 /// 117 enum Constants : int 118 { 119 spacingTop = 0, 120 spacingBottom = 1, 121 spacingChar = 2, 122 spacingSpace = 3, 123 } 124 /** 125 Adds a fallback font. 126 */ 127 void addFallback(DynamicFontData data) 128 { 129 checkClassBinding!(typeof(this))(); 130 ptrcall!(void)(GDNativeClassBinding.addFallback, _godot_object, data); 131 } 132 /** 133 Returns a string containing all the characters available in the main and all the fallback fonts. 134 If a given character is included in more than one font, it appears only once in the returned string. 135 */ 136 String getAvailableChars() const 137 { 138 checkClassBinding!(typeof(this))(); 139 return ptrcall!(String)(GDNativeClassBinding.getAvailableChars, _godot_object); 140 } 141 /** 142 Returns the fallback font at index `idx`. 143 */ 144 Ref!DynamicFontData getFallback(in long idx) const 145 { 146 checkClassBinding!(typeof(this))(); 147 return ptrcall!(DynamicFontData)(GDNativeClassBinding.getFallback, _godot_object, idx); 148 } 149 /** 150 Returns the number of fallback fonts. 151 */ 152 long getFallbackCount() const 153 { 154 checkClassBinding!(typeof(this))(); 155 return ptrcall!(long)(GDNativeClassBinding.getFallbackCount, _godot_object); 156 } 157 /** 158 159 */ 160 Ref!DynamicFontData getFontData() const 161 { 162 checkClassBinding!(typeof(this))(); 163 return ptrcall!(DynamicFontData)(GDNativeClassBinding.getFontData, _godot_object); 164 } 165 /** 166 167 */ 168 Color getOutlineColor() const 169 { 170 checkClassBinding!(typeof(this))(); 171 return ptrcall!(Color)(GDNativeClassBinding.getOutlineColor, _godot_object); 172 } 173 /** 174 175 */ 176 long getOutlineSize() const 177 { 178 checkClassBinding!(typeof(this))(); 179 return ptrcall!(long)(GDNativeClassBinding.getOutlineSize, _godot_object); 180 } 181 /** 182 183 */ 184 long getSize() const 185 { 186 checkClassBinding!(typeof(this))(); 187 return ptrcall!(long)(GDNativeClassBinding.getSize, _godot_object); 188 } 189 /** 190 Returns the spacing for the given `type` (see $(D spacingtype)). 191 */ 192 long getSpacing(in long type) const 193 { 194 checkClassBinding!(typeof(this))(); 195 return ptrcall!(long)(GDNativeClassBinding.getSpacing, _godot_object, type); 196 } 197 /** 198 199 */ 200 bool getUseFilter() const 201 { 202 checkClassBinding!(typeof(this))(); 203 return ptrcall!(bool)(GDNativeClassBinding.getUseFilter, _godot_object); 204 } 205 /** 206 207 */ 208 bool getUseMipmaps() const 209 { 210 checkClassBinding!(typeof(this))(); 211 return ptrcall!(bool)(GDNativeClassBinding.getUseMipmaps, _godot_object); 212 } 213 /** 214 Removes the fallback font at index `idx`. 215 */ 216 void removeFallback(in long idx) 217 { 218 checkClassBinding!(typeof(this))(); 219 ptrcall!(void)(GDNativeClassBinding.removeFallback, _godot_object, idx); 220 } 221 /** 222 Sets the fallback font at index `idx`. 223 */ 224 void setFallback(in long idx, DynamicFontData data) 225 { 226 checkClassBinding!(typeof(this))(); 227 ptrcall!(void)(GDNativeClassBinding.setFallback, _godot_object, idx, data); 228 } 229 /** 230 231 */ 232 void setFontData(DynamicFontData data) 233 { 234 checkClassBinding!(typeof(this))(); 235 ptrcall!(void)(GDNativeClassBinding.setFontData, _godot_object, data); 236 } 237 /** 238 239 */ 240 void setOutlineColor(in Color color) 241 { 242 checkClassBinding!(typeof(this))(); 243 ptrcall!(void)(GDNativeClassBinding.setOutlineColor, _godot_object, color); 244 } 245 /** 246 247 */ 248 void setOutlineSize(in long size) 249 { 250 checkClassBinding!(typeof(this))(); 251 ptrcall!(void)(GDNativeClassBinding.setOutlineSize, _godot_object, size); 252 } 253 /** 254 255 */ 256 void setSize(in long data) 257 { 258 checkClassBinding!(typeof(this))(); 259 ptrcall!(void)(GDNativeClassBinding.setSize, _godot_object, data); 260 } 261 /** 262 Sets the spacing for `type` (see $(D spacingtype)) to `value` in pixels (not relative to the font size). 263 */ 264 void setSpacing(in long type, in long value) 265 { 266 checkClassBinding!(typeof(this))(); 267 ptrcall!(void)(GDNativeClassBinding.setSpacing, _godot_object, type, value); 268 } 269 /** 270 271 */ 272 void setUseFilter(in bool enable) 273 { 274 checkClassBinding!(typeof(this))(); 275 ptrcall!(void)(GDNativeClassBinding.setUseFilter, _godot_object, enable); 276 } 277 /** 278 279 */ 280 void setUseMipmaps(in bool enable) 281 { 282 checkClassBinding!(typeof(this))(); 283 ptrcall!(void)(GDNativeClassBinding.setUseMipmaps, _godot_object, enable); 284 } 285 /** 286 Extra spacing at the bottom in pixels. 287 */ 288 @property long extraSpacingBottom() 289 { 290 return getSpacing(1); 291 } 292 /// ditto 293 @property void extraSpacingBottom(long v) 294 { 295 setSpacing(1, v); 296 } 297 /** 298 Extra spacing for each character in pixels. 299 This can be a negative number to make the distance between characters smaller. 300 */ 301 @property long extraSpacingChar() 302 { 303 return getSpacing(2); 304 } 305 /// ditto 306 @property void extraSpacingChar(long v) 307 { 308 setSpacing(2, v); 309 } 310 /** 311 Extra spacing for the space character (in addition to $(D extraSpacingChar)) in pixels. 312 This can be a negative number to make the distance between words smaller. 313 */ 314 @property long extraSpacingSpace() 315 { 316 return getSpacing(3); 317 } 318 /// ditto 319 @property void extraSpacingSpace(long v) 320 { 321 setSpacing(3, v); 322 } 323 /** 324 Extra spacing at the top in pixels. 325 */ 326 @property long extraSpacingTop() 327 { 328 return getSpacing(0); 329 } 330 /// ditto 331 @property void extraSpacingTop(long v) 332 { 333 setSpacing(0, v); 334 } 335 /** 336 The font data. 337 */ 338 @property DynamicFontData fontData() 339 { 340 return getFontData(); 341 } 342 /// ditto 343 @property void fontData(DynamicFontData v) 344 { 345 setFontData(v); 346 } 347 /** 348 The font outline's color. 349 $(B Note:) It's recommended to leave this at the default value so that you can adjust it in individual controls. For example, if the outline is made black here, it won't be possible to change its color using a Label's font outline modulate theme item. 350 */ 351 @property Color outlineColor() 352 { 353 return getOutlineColor(); 354 } 355 /// ditto 356 @property void outlineColor(Color v) 357 { 358 setOutlineColor(v); 359 } 360 /** 361 The font outline's thickness in pixels (not relative to the font size). 362 */ 363 @property long outlineSize() 364 { 365 return getOutlineSize(); 366 } 367 /// ditto 368 @property void outlineSize(long v) 369 { 370 setOutlineSize(v); 371 } 372 /** 373 The font size in pixels. 374 */ 375 @property long size() 376 { 377 return getSize(); 378 } 379 /// ditto 380 @property void size(long v) 381 { 382 setSize(v); 383 } 384 /** 385 If `true`, filtering is used. This makes the font blurry instead of pixelated when scaling it if font oversampling is disabled or ineffective. It's recommended to enable this when using the font in a control whose size changes over time, unless a pixel art aesthetic is desired. 386 */ 387 @property bool useFilter() 388 { 389 return getUseFilter(); 390 } 391 /// ditto 392 @property void useFilter(bool v) 393 { 394 setUseFilter(v); 395 } 396 /** 397 If `true`, mipmapping is used. This improves the font's appearance when downscaling it if font oversampling is disabled or ineffective. 398 */ 399 @property bool useMipmaps() 400 { 401 return getUseMipmaps(); 402 } 403 /// ditto 404 @property void useMipmaps(bool v) 405 { 406 setUseMipmaps(v); 407 } 408 }