]> git.tdb.fi Git - libs/gl.git/blob - source/font.cpp
Make the use of DevIL optional
[libs/gl.git] / source / font.cpp
1 /* $Id$
2
3 This file is part of libmspgl
4 Copyright © 2007  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include "gl.h"
9 #include "font.h"
10 #include "primitivetype.h"
11 #include "texture2d.h"
12
13 using namespace std;
14
15 namespace Msp {
16 namespace GL {
17
18 Font::Font():
19         tex(0),
20         default_size(1),
21         ascent(1),
22         descent(0)
23 { }
24
25 void Font::set_texture(const Texture2D &t)
26 {
27         tex=&t;
28 }
29
30 void Font::add_glyph(unsigned code, float x1, float y1, float x2, float y2, float w, float h, float ox, float oy, float adv)
31 {
32         Glyph glyph;
33         glyph.code=code;
34         glyph.x1=x1;
35         glyph.y1=y1;
36         glyph.x2=x2;
37         glyph.y2=y2;
38         glyph.w=w;
39         glyph.h=h;
40         glyph.off_x=ox;
41         glyph.off_y=oy;
42         glyph.advance=adv;
43         glyphs.insert(GlyphMap::value_type(code, glyph));
44 }
45
46 float Font::get_string_width(const string &str, Codecs::Decoder &dec) const
47 {
48         float x=0;
49
50         for(string::const_iterator i=str.begin(); i!=str.end();)
51                 x+=get_glyph_advance(dec.decode_char(str, i));
52
53         return x;
54 }
55
56 void Font::draw_string(const string &str, Codecs::Decoder &dec) const
57 {
58         tex->bind();
59
60         VertexArray va((TEXCOORD2, VERTEX2));
61         va.reserve(str.size()*4);
62         RefPtr<VertexArrayBuilder> vab=va.modify();
63         float x=0;
64         unsigned count=0;
65         for(string::const_iterator i=str.begin(); i!=str.end();)
66         {
67                 GlyphMap::const_iterator j=glyphs.find(dec.decode_char(str, i));
68                 if(j==glyphs.end())
69                         continue;
70
71                 create_glyph_vertices(j->second, *vab, x);
72                 x+=j->second.advance;
73                 count+=4;
74         }
75         vab=0;
76         va.apply();
77         glDrawArrays(QUADS, 0, count);
78 }
79
80 void Font::create_glyph_vertices(const Glyph &glyph, VertexBuilder &vbuilder, float x) const
81 {
82         vbuilder.texcoord(glyph.x1, glyph.y1);
83         vbuilder.vertex(x+glyph.off_x, glyph.off_y);
84         vbuilder.texcoord(glyph.x2, glyph.y1);
85         vbuilder.vertex(x+glyph.off_x+glyph.w, glyph.off_y);
86         vbuilder.texcoord(glyph.x2, glyph.y2);
87         vbuilder.vertex(x+glyph.off_x+glyph.w, glyph.off_y+glyph.h);
88         vbuilder.texcoord(glyph.x1, glyph.y2);
89         vbuilder.vertex(x+glyph.off_x, glyph.off_y+glyph.h);
90 }
91
92 float Font::get_glyph_advance(unsigned code) const
93 {
94         GlyphMap::const_iterator i=glyphs.find(code);
95         if(i==glyphs.end())
96                 return 0;
97
98         return i->second.advance;
99 }
100
101
102 Font::Loader::Loader(Font &f):
103         font(f),
104         coll(0)
105 {
106         init();
107 }
108
109 Font::Loader::Loader(Font &f, Collection &c):
110         font(f),
111         coll(&c)
112 {
113         init();
114 }
115
116 DataFile::Collection &Font::Loader::get_collection()
117 {
118         if(!coll)
119                 throw InvalidState("No collection");
120         return *coll;
121 }
122
123 void Font::Loader::init()
124 {
125         add("default_size", &Font::default_size);
126         add("ascent",  &Font::ascent);
127         add("descent", &Font::descent);
128         add("texture", &Font::tex);
129         add("glyph",   &Loader::glyph);
130 }
131
132 void Font::Loader::glyph(unsigned c)
133 {
134         Glyph gl;
135         gl.code=c;
136         load_sub(gl);
137         font.glyphs.insert(GlyphMap::value_type(c, gl));
138 }
139
140
141 Font::Glyph::Loader::Loader(Glyph &g):
142         glyph(g)
143 {
144         add("texcoords", &Loader::texcoords);
145         add("size",      &Glyph::w,     &Glyph::h);
146         add("offset",    &Glyph::off_x, &Glyph::off_y);
147         add("advance",   &Glyph::advance);
148 }
149
150 void Font::Glyph::Loader::texcoords(float x1, float y1, float x2, float y2)
151 {
152         glyph.x1=x1;
153         glyph.y1=y1;
154         glyph.x2=x2;
155         glyph.y2=y2;
156 }
157
158 } // namespace GL
159 } // namespace Msp