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 }