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