1 module des.gl.simple.textout; 2 3 import des.fonts.ftglyphrender; 4 5 import des.gl.simple; 6 import des.gl.simple.shader.text; 7 8 import std.traits; 9 10 wstring wformat(S,Args...)( S fmt, Args args ) 11 if( is( S == string ) || is( S == wstring ) ) 12 { return to!wstring( format( to!string(fmt), args ) ); } 13 14 class BaseLineTextBox : GLSimpleObject 15 { 16 private: 17 18 GLBuffer vert, uv; 19 20 GLTexture tex; 21 22 wstring output; 23 vec2 output_size; 24 25 vec2 pos; 26 27 BitmapFont font; 28 29 void repos() 30 { 31 vec2[] vert_data; 32 vec2[] uv_data; 33 34 output_size = vec2(0); 35 36 float offsetx = 0; 37 foreach( c; output ) 38 if( font.size[c].h > output_size.h ) 39 output_size.h = font.size[c].h; 40 41 foreach( c; output ) 42 { 43 output_size.w += font.size[c].w; 44 45 { 46 auto v1 = pos + vec2( font.bearing[c].x + offsetx, output_size.h + font.bearing[c].y ); 47 auto v2 = v1 + font.size[c]; 48 49 vert_data ~= vec2( v1.x, v2.y ); 50 vert_data ~= v1; 51 vert_data ~= vec2( v2.x, v1.y ); 52 53 vert_data ~= v2; 54 vert_data ~= vec2( v1.x, v2.y ); 55 vert_data ~= vec2( v2.x, v1.y ); 56 57 offsetx += font.size[c].x; 58 } 59 60 { 61 auto uvoffset = vec2( font.offset[c] ) / vec2( font.texture.size ); 62 auto uvsize = vec2( font.size[c] ) / vec2( font.texture.size ); 63 64 auto uv1 = uvoffset; 65 auto uv2 = uv1 + uvsize; 66 67 uv_data ~= vec2( uv1.x, uv2.y ); 68 uv_data ~= uv1; 69 uv_data ~= vec2( uv2.x, uv1.y ); 70 71 uv_data ~= uv2; 72 uv_data ~= vec2( uv1.x, uv2.y ); 73 uv_data ~= vec2( uv2.x, uv1.y ); 74 } 75 } 76 77 vert.setData( vert_data ); 78 uv.setData( uv_data ); 79 } 80 81 public: 82 this( string font_name, uint size=24u ) 83 { 84 super( SS_WIN_TEXT ); 85 86 vert = createArrayBuffer(); 87 setAttribPointer( vert, shader.getAttribLocation( "vert" ), 2, GLType.FLOAT ); 88 89 uv = createArrayBuffer(); 90 setAttribPointer( uv, shader.getAttribLocation( "uv" ), 2, GLType.FLOAT ); 91 92 tex = newEMM!GLTexture( GLTexture.Target.T2D ); 93 94 tex.setParameter( GLTexture.Parameter.MIN_FILTER, GLTexture.Filter.NEAREST ); 95 tex.setParameter( GLTexture.Parameter.MAG_FILTER, GLTexture.Filter.NEAREST ); 96 97 GlyphParam gparam; 98 gparam.height = size; 99 100 auto grender = FTGlyphRender.get( font_name ); 101 102 grender.setParams( gparam ); 103 104 font = grender.generateBitmapFont(); 105 106 tex.image( font.texture ); 107 108 text = "Default text"; 109 } 110 111 void draw( ivec2 win_size ) 112 { 113 shader.setUniform!ivec2( "win_size", win_size ); 114 tex.bind(); 115 glDisable(GL_DEPTH_TEST); 116 drawArrays( DrawMode.TRIANGLES ); 117 tex.unbind(); 118 } 119 120 @property 121 { 122 void text(T)( T t ) 123 if( isSomeString!T )//TODO is convertable to wstring 124 { 125 import std.conv; 126 output = to!wstring( t ); 127 repos(); 128 } 129 wstring text(){ return output; } 130 131 void position( vec2 pos ) 132 { 133 this.pos = pos; 134 repos(); 135 } 136 137 void color( col3 col ){ shader.setUniform!col3( "color", col ); } 138 139 vec2 size(){ return output_size; } 140 } 141 }