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 protected Glyph createGlyph ( bool needbmp = true ) 62 { 63 Glyph g; 64 65 BitmapA bmp = null; 66 if ( needbmp ) { 67 auto ftbmp = _face.glyph.bitmap; 68 auto size = vec2i( 69 ftbmp.width.to!int, ftbmp.rows.to!int ); 70 bmp = new BitmapA( size, ftbmp.buffer ); 71 } 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 /// Retrieves metrics only. 81 Glyph retrieveMetrics ( vec2i sz, dchar c ) 82 { 83 enforce!FT_Set_Pixel_Sizes( _face, sz.x.to!uint, sz.y.to!uint ); 84 85 auto index = FT_Get_Char_Index( _face, c ); 86 enforce!FT_Load_Glyph( _face, index, FT_LOAD_NO_BITMAP ); 87 88 return createGlyph( false ); 89 } 90 91 /// Renders the character. 92 Glyph render ( vec2i sz, dchar c ) 93 { 94 enforce!FT_Set_Pixel_Sizes( _face, sz.x.to!uint, sz.y.to!uint ); 95 96 auto index = FT_Get_Char_Index( _face, c ); 97 enforce!FT_Load_Glyph( _face, index, FT_LOAD_RENDER ); 98 99 return createGlyph( true ); 100 } 101 } 102 103 /// An object of font face. Font face knows its size. 104 class FontFace 105 { 106 protected Font _font; 107 /// Font. 108 const @property font () { return _font; } 109 110 /// Size of the Font. 111 const vec2i size; 112 113 /// 114 this ( Font f, vec2i s ) 115 { 116 if ( s.x == 0 ) s.x = s.y; 117 if ( s.y == 0 ) s.y = s.x; 118 _font = f; 119 size = s; 120 } 121 122 /// Retrieves the metrics. 123 Glyph retrieveMetrics ( dchar c ) 124 { 125 return _font.retrieveMetrics( size, c ); 126 } 127 128 /// Renders the character. 129 Glyph render ( dchar c ) 130 { 131 return _font.render( size, c ); 132 } 133 }