1 // Written in the D programming language. 2 /++ 3 + Authors: KanzakiKino 4 + Copyright: KanzakiKino 2018 5 + License: LGPL-3.0 6 ++/ 7 module g4d.ft.texture; 8 import g4d.ft.font, 9 g4d.ft.lib, 10 g4d.gl.buffer, 11 g4d.gl.texture, 12 g4d.math.rational, 13 g4d.util.bitmap; 14 import gl3n.linalg; 15 import std.algorithm, 16 std.array, 17 std.conv; 18 19 /// A texture of text. 20 class TextTexture : Tex2D 21 { 22 /// A metrics data of characters. 23 struct Metrics 24 { 25 /// Size in pixel. 26 vec2i size; 27 /// UV coordinates. 28 /// [left,top, right,top, right,bottom, left,bottom,] 29 float[8] uv; 30 31 /// Width of collision. 32 ulong horiAdvance; 33 /// Size of moving from origin. 34 vec2i horiBearing; 35 } 36 37 protected Metrics[dchar] _chars; 38 /// Metrics data of characters drawn this texture. 39 const @property chars () { return _chars; } 40 41 /// Creates text texture from FontFace and text. 42 this ( FontFace face, dstring text ) 43 { 44 text = text.uniq.array; 45 super( renderBitmap( face, text ), true ); 46 } 47 48 protected BitmapA renderBitmap ( FontFace face, dstring text ) 49 { 50 auto size = vec2i( face.size ); 51 size.x *= text.length; 52 53 auto result = new BitmapA( size ); 54 55 size.x = size.x.nextPower2; 56 size.y = size.y.nextPower2; 57 58 Glyph g; 59 Metrics m; 60 int pos = 0; 61 float left, top, right, bottom; 62 63 foreach ( c; text ) { 64 g = face.render( c ); 65 66 result.overwrite( vec2i(pos,0), g.bmp ); 67 68 m.size = g.bmp.size; 69 m.horiBearing = g.bearing; 70 m.horiAdvance = g.advance; 71 72 left = pos*1f / size.x; 73 top = 0; 74 pos += m.size.x; 75 right = pos*1f / size.x; 76 bottom = m.size.y*1f / size.y; 77 78 m.uv = [ 79 left,top, right,top, right,bottom, left,bottom, 80 ]; 81 82 _chars[c] = m; 83 g.bmp.dispose(); 84 } 85 return result; 86 } 87 }