1 module d2d.font.ttffont;
2 
3 import d2d;
4 
5 /// Implementation for SDL_ttf.
6 class TTFFont : IFont
7 {
8 private:
9 	TTF_Font* _handle;
10 
11 public:
12 	~this()
13 	{
14 		dispose();
15 	}
16 
17 	/// Handle to underlying `TTF_Font*` handle.
18 	@property TTF_Font* handle()
19 	{
20 		return _handle;
21 	}
22 
23 	/// Loads the font from a file.
24 	override void load(string file, int sizeInPt)
25 	{
26 		_handle = TTF_OpenFont(file.toStringz(), sizeInPt);
27 		if (!valid)
28 			throw new Exception(cast(string) TTF_GetError().fromStringz());
29 	}
30 
31 	/// Returns if `_handle` is not `null`.
32 	override @property bool valid()
33 	{
34 		return _handle !is null;
35 	}
36 
37 	/// Deallocates memory and invalidates this.
38 	override void dispose()
39 	{
40 		if (valid)
41 		{
42 			TTF_CloseFont(_handle);
43 			_handle = null;
44 		}
45 	}
46 
47 	/// Renders a string to an IText.
48 	override IText render(string text, float scale = 1.0f)
49 	{
50 		TTFText ret = new TTFText(this);
51 		ret.text = text;
52 		ret.scale = scale;
53 		return ret;
54 	}
55 
56 	/// Renders a multiline string to an IText.
57 	override IText renderMultiline(string text, float scale = 1.0f)
58 	{
59 		TTFText ret = new TTFText(this);
60 		ret.text = text;
61 		ret.scale = scale;
62 		ret.multiline = true;
63 		return ret;
64 	}
65 
66 	/// Returns the line height of this font.
67 	@property float lineHeight()
68 	{
69 		return TTF_FontHeight(_handle);
70 	}
71 
72 	/// Returns the dimensions of a string with this font.
73 	override vec2 measureText(string text, float scale = 1.0f)
74 	{
75 		int w, h;
76 		TTF_SizeUTF8(_handle, text.toStringz(), &w, &h);
77 		return vec2(w * scale, h * scale);
78 	}
79 
80 	/// Returns the dimensions of a multiline string with this font.
81 	override vec2 measureTextMultiline(string text, float scale = 1.0f)
82 	{
83 		string[] lines = text.split('\n');
84 		int w, h;
85 		foreach (string line; lines)
86 		{
87 			int lw, lh;
88 			TTF_SizeText(_handle, line.toStringz(), &lw, &lh);
89 			w = max(w, lw);
90 			h += lh;
91 		}
92 		return vec2(w * scale, h * scale);
93 	}
94 }