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 }