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