1 // Written in the D programming language. 2 /++ 3 + Authors: KanzakiKino 4 + Copyright: KanzakiKino 2018 5 + License: LGPL-3.0 6 + 7 + This module declares utilities related to font. 8 ++/ 9 module g4d.ft.font; 10 import g4d.ft.lib, 11 g4d.util.bitmap, 12 g4d.exception; 13 import gl3n.linalg; 14 import std.conv, 15 std.string; 16 17 /// A struct of one glyph. 18 struct Glyph 19 { 20 /// Bitmap of the glyph. 21 BitmapA bmp; 22 /// Size of moving from origin. 23 vec2i bearing; 24 /// Width of collision. 25 size_t advance; 26 } 27 28 /// An object of Font. 29 class Font 30 { 31 protected static FT_Library _library; 32 protected static void initLibrary () 33 { 34 if ( !_library ) { 35 DerelictFT.load(); 36 enforce!FT_Init_FreeType( &_library ); 37 } 38 } 39 protected static size_t _fontCount; 40 41 protected FT_Face _face; 42 43 /// 44 this ( string path ) 45 { 46 initLibrary(); 47 _fontCount++; 48 49 enforce!FT_New_Face( _library, path.toStringz, 0, &_face ); 50 } 51 /// 52 ~this () 53 { 54 enforce!FT_Done_Face( _face ); 55 if ( --_fontCount <= 0 ) { 56 enforce!FT_Done_FreeType( _library ); 57 _library = null; 58 } 59 } 60 61 /// Renders the character. 62 Glyph render ( vec2i sz, dchar c ) 63 { 64 enforce!FT_Set_Pixel_Sizes( _face, sz.x.to!uint, sz.y.to!uint ); 65 66 auto index = FT_Get_Char_Index( _face, c ); 67 enforce!FT_Load_Glyph( _face, index, FT_LOAD_RENDER ); 68 69 auto ftbmp = _face.glyph.bitmap; 70 auto size = vec2i( ftbmp.width.to!int, ftbmp.rows.to!int ); 71 auto bmp = new BitmapA( size, ftbmp.buffer ); 72 73 auto metrics = _face.glyph.metrics; 74 auto bearing = vec2i( metrics.horiBearingX.to!int/64, 75 metrics.horiBearingY.to!int/64 ); 76 77 return Glyph( bmp, bearing, metrics.horiAdvance/64 ); 78 } 79 } 80 81 /// An object of font face. Font face knows its size. 82 class FontFace 83 { 84 protected Font _font; 85 /// Font. 86 const @property font () { return _font; } 87 88 /// Size of the Font. 89 const vec2i size; 90 91 /// 92 this ( Font f, vec2i s ) 93 { 94 if ( s.x == 0 ) s.x = s.y; 95 if ( s.y == 0 ) s.y = s.x; 96 _font = f; 97 size = s; 98 } 99 100 /// Renders the character. 101 Glyph render ( dchar c ) 102 { 103 return _font.render( size, c ); 104 } 105 }