1 module d2d.font.ttftext;
2
3 import d2d;
4
5 import std.algorithm : max;
6
7 /// Implementation containing text drawable functions using a TTF font. Nice for static texts, slow for dynamic texts.
8 class TTFText : RectangleShape, IText
9 {
10 private:
11 float _scale = 1.0f;
12 string _text = "";
13 TTFFont _font;
14 bool _multiline = false;
15
16 public:
17 /// Creates an empty ttf text
18 this(TTFFont font)
19 {
20 _font = font;
21 texture = new Texture();
22 texture.create(0, 0, []);
23 }
24
25 /// Gets the scale in percent.
26 override @property float scale()
27 {
28 return _scale;
29 }
30
31 /// Sets the scale in percent.
32 override @property void scale(float value)
33 {
34 _scale = value;
35 }
36
37 /// Gets the text.
38 override @property string text()
39 {
40 return _text;
41 }
42
43 /// Modifies the text.
44 override @property void text(string value)
45 {
46 if (_text != value)
47 {
48 _text = value;
49 redraw();
50 }
51 }
52
53 /// Returns if this text should be rendered multiline.
54 @property bool multiline()
55 {
56 return _multiline;
57 }
58
59 /// Sets if this text should be rendered multiline.
60 @property void multiline(bool value)
61 {
62 if (_multiline != value)
63 {
64 _multiline = value;
65 redraw();
66 }
67 }
68
69 /// Should get called automatically when something changed.
70 void redraw()
71 {
72 Bitmap bmp;
73 if (_multiline)
74 {
75 string[] lines = text.split('\n');
76 int maxWidth = 0;
77 foreach (string line; lines)
78 {
79 int w, h;
80 TTF_SizeText(_font.handle, line.toStringz(), &w, &h);
81 maxWidth = max(w, maxWidth);
82 }
83 bmp = Bitmap.fromSurface(TTF_RenderUTF8_Blended_Wrapped(_font.handle, text.toStringz(), Color.White.sdl_color, maxWidth));
84 }
85 else
86 {
87 bmp = Bitmap.fromSurface(TTF_RenderUTF8_Blended(_font.handle, text.toStringz(), Color.White.sdl_color));
88 }
89 if (!bmp.valid)
90 throw new Exception(cast(string) TTF_GetError().fromStringz());
91 texture.recreateFromBitmap(bmp, "Blended Text: \"" ~ text ~ "\"");
92 size = vec2(texture.width, texture.height);
93 create();
94 }
95
96 override void draw(IRenderTarget target, ShaderProgram shader = null)
97 {
98 matrixStack.push();
99 matrixStack.top = matrixStack.top * mat4.scaling(_scale, _scale, 1);
100 super.draw(target, shader);
101 matrixStack.pop();
102 }
103
104 override @property bool valid()
105 {
106 return super.valid;
107 }
108
109 override void dispose()
110 {
111 super.dispose();
112 }
113 }