]> git.tdb.fi Git - libs/gl.git/blob - source/font.cpp
Drop Id tags and copyright notices from files
[libs/gl.git] / source / font.cpp
1 #include <msp/datafile/collection.h>
2 #include "bindable.h"
3 #include "gl.h"
4 #include "font.h"
5 #include "immediate.h"
6 #include "primitivetype.h"
7 #include "texture2d.h"
8
9 using namespace std;
10
11 namespace Msp {
12 namespace GL {
13
14 Font::Font():
15         native_size(1),
16         ascent(1),
17         descent(0)
18 { }
19
20 void Font::set_texture(const Texture2D &t)
21 {
22         texture = &t;
23         texture.keep();
24 }
25
26 const Texture2D &Font::get_texture() const
27 {
28         if(!texture)
29                 throw InvalidState("No texture");
30         return *texture;
31 }
32
33 void Font::add_glyph(unsigned code, float x1, float y1, float x2, float y2, float w, float h, float ox, float oy, float adv)
34 {
35         Glyph glyph;
36         glyph.code = code;
37         glyph.x1 = x1;
38         glyph.y1 = y1;
39         glyph.x2 = x2;
40         glyph.y2 = y2;
41         glyph.w = w;
42         glyph.h = h;
43         glyph.off_x = ox;
44         glyph.off_y = oy;
45         glyph.advance = adv;
46         glyphs.insert(GlyphMap::value_type(code, glyph));
47 }
48
49 float Font::get_string_width(const string &str, Codecs::Decoder &dec) const
50 {
51         float x = 0;
52
53         for(string::const_iterator i=str.begin(); i!=str.end();)
54                 x += get_glyph_advance(dec.decode_char(str, i));
55
56         return x;
57 }
58
59 void Font::draw_string(const string &str, Codecs::Decoder &dec) const
60 {
61         Immediate imm((TEXCOORD2, COLOR4_UBYTE, VERTEX2));
62         draw_string(str, dec, imm);
63 }
64
65 void Font::draw_string(const string &str, Codecs::Decoder &dec, PrimitiveBuilder &bld) const
66 {
67         MatrixStack::Push push_mtx(bld.matrix());
68         Bind bind_tex(get_texture(), true);
69
70         bld.begin(QUADS);
71         for(string::const_iterator i=str.begin(); i!=str.end();)
72         {
73                 GlyphMap::const_iterator j = glyphs.find(dec.decode_char(str, i));
74                 if(j==glyphs.end())
75                         continue;
76
77                 create_glyph_vertices(j->second, bld);
78                 bld.matrix() *= Matrix::translation(j->second.advance, 0, 0);
79         }
80         bld.end();
81 }
82
83 void Font::create_glyph_vertices(const Glyph &glyph, VertexBuilder &bld) const
84 {
85         bld.texcoord(glyph.x1, glyph.y1);
86         bld.vertex(glyph.off_x, glyph.off_y);
87         bld.texcoord(glyph.x2, glyph.y1);
88         bld.vertex(glyph.off_x+glyph.w, glyph.off_y);
89         bld.texcoord(glyph.x2, glyph.y2);
90         bld.vertex(glyph.off_x+glyph.w, glyph.off_y+glyph.h);
91         bld.texcoord(glyph.x1, glyph.y2);
92         bld.vertex(glyph.off_x, glyph.off_y+glyph.h);
93 }
94
95 float Font::get_glyph_advance(unsigned code) const
96 {
97         GlyphMap::const_iterator i = glyphs.find(code);
98         if(i==glyphs.end())
99                 return 0;
100
101         return i->second.advance;
102 }
103
104
105 Font::Loader::Loader(Font &f):
106         DataFile::CollectionObjectLoader<Font>(f, 0)
107 {
108         init();
109 }
110
111 Font::Loader::Loader(Font &f, Collection &c):
112         DataFile::CollectionObjectLoader<Font>(f, &c)
113 {
114         init();
115 }
116
117 void Font::Loader::init()
118 {
119         add("native_size", &Font::native_size);
120         add("ascent",      &Font::ascent);
121         add("descent",     &Font::descent);
122         add("texture",     &Loader::texture);
123         add("texture",     &Loader::texture_ref);
124         add("glyph",       &Loader::glyph);
125
126         // Deprecated aliases
127         add("default_size",   &Font::native_size);
128         add("texture_inline", &Loader::texture);
129 }
130
131 void Font::Loader::glyph(unsigned c)
132 {
133         Glyph gl;
134         gl.code = c;
135         load_sub(gl);
136         obj.glyphs.insert(GlyphMap::value_type(c, gl));
137 }
138
139 void Font::Loader::texture()
140 {
141         RefPtr<Texture2D> tex = new Texture2D;
142         load_sub(*tex);
143         obj.texture = tex;
144 }
145
146 void Font::Loader::texture_ref(const string &name)
147 {
148         obj.texture = get_collection().get<Texture2D>(name);
149         obj.texture.keep();
150 }
151
152
153 Font::Glyph::Loader::Loader(Glyph &g):
154         DataFile::ObjectLoader<Glyph>(g)
155 {
156         add("texcoords", &Loader::texcoords);
157         add("size",      &Glyph::w,     &Glyph::h);
158         add("offset",    &Glyph::off_x, &Glyph::off_y);
159         add("advance",   &Glyph::advance);
160 }
161
162 void Font::Glyph::Loader::texcoords(float x1, float y1, float x2, float y2)
163 {
164         obj.x1 = x1;
165         obj.y1 = y1;
166         obj.x2 = x2;
167         obj.y2 = y2;
168 }
169
170 } // namespace GL
171 } // namespace Msp