]> git.tdb.fi Git - libs/gl.git/blob - source/text.cpp
Add a class for easier text rendering
[libs/gl.git] / source / text.cpp
1 #include "meshbuilder.h"
2 #include "text.h"
3 #include "texture2d.h"
4
5 using namespace std;
6
7 namespace Msp {
8 namespace GL {
9
10 Text::Text(const Font &f, const Technique *tech):
11         font(f),
12         mesh((TEXCOORD2, VERTEX2)),
13         horz_align(0.0f),
14         vert_offset(0.0f)
15 {
16         object.set_mesh(&mesh);
17         if(tech)
18                 set_technique(tech);
19 }
20
21 void Text::set_technique(const Technique *tech)
22 {
23         if(tech)
24         {
25                 technique = *tech;
26                 technique.replace_texture("diffusemap", font.get_texture());
27                 object.set_technique(&technique);
28         }
29         else
30                 object.set_technique(0);
31 }
32
33 void Text::set_text(const string &text, StringCodec::Decoder &dec)
34 {
35         clear();
36         width = font.get_string_width(text, dec);
37         GL::MeshBuilder bld(mesh);
38         bld.matrix() *= Matrix::translation(Vector3(-horz_align*width, vert_offset, 0.0f));
39         font.build_string(text, dec, bld);
40 }
41
42 void Text::clear()
43 {
44         mesh.clear();
45         width = 0;
46 }
47
48 void Text::set_alignment(HorizontalAlign ha, VerticalAlign va)
49 {
50         float h;
51         switch(ha)
52         {
53         case LEFT: h = 0.0f; break;
54         case CENTER: h = 0.5f; break;
55         case RIGHT: h = 1.0f; break;
56         default: throw invalid_argument("Text::set_alignment");
57         }
58
59         float v;
60         switch(va)
61         {
62         case DESCENT: v = -font.get_descent(); break;
63         case BASELINE: v = 0.0f; break;
64         case MIDLINE: v = font.get_ascent()/2; break;  // XXX Midline should be cap height / 2
65         case ASCENT: v = font.get_ascent(); break;
66         default: throw invalid_argument("Text::set_alignment");
67         }
68
69         set_alignment(h, v);
70 }
71
72 void Text::set_alignment(float h, float v)
73 {
74         float horz_adjust = (horz_align-h)*width;
75         float vert_adjust = -v-vert_offset;
76         horz_align = h;
77         vert_offset = -v;
78
79         unsigned pos_offset = mesh.get_vertices().get_format().offset(VERTEX2);
80         unsigned n_vertices = mesh.get_n_vertices();
81         for(unsigned i=0; i<n_vertices; ++i)
82         {
83                 float *pos = mesh.modify_vertex(i)+pos_offset;
84                 pos[0] += horz_adjust;
85                 pos[1] += vert_adjust;
86         }
87 }
88
89 void Text::render(Renderer &renderer, const Tag &tag) const
90 {
91         object.render(renderer, tag);
92 }
93
94 } // namespace GL
95 } // namespace Msp