1 #include <msp/core/maputils.h>
2 #include <msp/datafile/collection.h>
7 #include "primitivetype.h"
21 // Avoid synthesizing ~RefPtr in files including font.h
25 void Font::set_texture(const Texture2D &t)
31 const Texture2D &Font::get_texture() const
34 throw logic_error("No texture");
38 void Font::add_glyph(const Glyph &g)
40 insert_unique(glyphs, g.code, g);
43 void Font::set_kerning(unsigned l, unsigned r, float d)
45 kerning[KerningKey(l, r)] = d;
48 float Font::get_string_width(const string &str, StringCodec::Decoder &dec) const
53 for(string::const_iterator i=str.begin(); i!=str.end();)
55 unsigned c = dec.decode_char(str, i);
57 x += get_glyph_advance(prev, c);
60 x += get_glyph_advance(prev);
65 void Font::draw_string(const string &str, StringCodec::Decoder &dec, const Color &color) const
67 Bind bind_tex(get_texture(), true);
68 Immediate imm((TEXCOORD2, COLOR4_UBYTE, VERTEX2));
70 build_string(str, dec, imm);
73 void Font::build_string(const string &str, StringCodec::Decoder &dec, PrimitiveBuilder &bld) const
75 MatrixStack::Push push_mtx(bld.matrix());
79 for(string::const_iterator i=str.begin(); i!=str.end();)
81 unsigned c = dec.decode_char(str, i);
82 GlyphMap::const_iterator j = glyphs.find(c);
87 bld.matrix() *= Matrix::translation(get_glyph_advance(prev, c), 0, 0);
89 create_glyph_vertices(j->second, bld);
95 void Font::create_glyph_vertices(const Glyph &glyph, VertexBuilder &bld) const
97 bld.texcoord(glyph.x1, glyph.y1);
98 bld.vertex(glyph.off_x, glyph.off_y);
99 bld.texcoord(glyph.x2, glyph.y1);
100 bld.vertex(glyph.off_x+glyph.w, glyph.off_y);
101 bld.texcoord(glyph.x2, glyph.y2);
102 bld.vertex(glyph.off_x+glyph.w, glyph.off_y+glyph.h);
103 bld.texcoord(glyph.x1, glyph.y2);
104 bld.vertex(glyph.off_x, glyph.off_y+glyph.h);
107 float Font::get_glyph_advance(unsigned code, unsigned next) const
109 GlyphMap::const_iterator i = glyphs.find(code);
113 float advance = i->second.advance;
117 KerningMap::const_iterator j = kerning.find(KerningKey(code, next));
119 advance += j->second;
126 Font::Loader::Loader(Font &f):
127 DataFile::CollectionObjectLoader<Font>(f, 0)
132 Font::Loader::Loader(Font &f, Collection &c):
133 DataFile::CollectionObjectLoader<Font>(f, &c)
138 void Font::Loader::init()
140 add("native_size", &Font::native_size);
141 add("ascent", &Font::ascent);
142 add("descent", &Font::descent);
143 add("texture", &Loader::texture);
144 add("texture", &Loader::texture_ref);
145 add("glyph", &Loader::glyph);
146 add("kerning", &Loader::kerning);
149 void Font::Loader::glyph(unsigned c)
154 obj.glyphs.insert(GlyphMap::value_type(c, gl));
157 void Font::Loader::kerning(unsigned l, unsigned r, float d)
159 obj.kerning[KerningKey(l, r)] = d;
162 void Font::Loader::texture()
164 RefPtr<Texture2D> tex = new Texture2D;
169 void Font::Loader::texture_ref(const string &name)
171 obj.texture = &get_collection().get<Texture2D>(name);
176 Font::Glyph::Loader::Loader(Glyph &g):
177 DataFile::ObjectLoader<Glyph>(g)
179 add("texcoords", &Loader::texcoords);
180 add("size", &Glyph::w, &Glyph::h);
181 add("offset", &Glyph::off_x, &Glyph::off_y);
182 add("advance", &Glyph::advance);
185 void Font::Glyph::Loader::texcoords(float x1_, float y1_, float x2_, float y2_)