]> git.tdb.fi Git - libs/gl.git/commitdiff
Add kerning support to Font
authorMikko Rasa <tdb@tdb.fi>
Sat, 7 Sep 2013 14:09:39 +0000 (17:09 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 9 Sep 2013 15:52:39 +0000 (18:52 +0300)
scripts/makefont.py
source/font.cpp
source/font.h

index 84e9c6099dedcf5c0d18e2a02c068f110d4cc813..11d83794205cebad76b5526e088aa16d0d022df5 100755 (executable)
@@ -23,6 +23,9 @@ def convert_def(fn):
                        result += "\toffset %.3f %.3f;\n"%(float(ox)/fh, float(oy)/fh)
                        result += "\tadvance %.3f;\n"%(float(a)/fh)
                        result += "};\n"
+               elif parts[0]=="kern":
+                       l, r, d = map(int, parts[1:])
+                       result += "kerning %d %d %.3f;\n"%(l, r, float(d)/fh)
 
        return result
 
index abfe631ef82dae0336bfb49f631023197c7d1b26..069ecf0fa40db27feeaca1e592204fd1a3934408 100644 (file)
@@ -40,12 +40,24 @@ void Font::add_glyph(const Glyph &g)
        insert_unique(glyphs, g.code, g);
 }
 
+void Font::set_kerning(unsigned l, unsigned r, float d)
+{
+       kerning[KerningKey(l, r)] = d;
+}
+
 float Font::get_string_width(const string &str, StringCodec::Decoder &dec) const
 {
        float x = 0;
 
+       unsigned prev = 0;
        for(string::const_iterator i=str.begin(); i!=str.end();)
-               x += get_glyph_advance(dec.decode_char(str, i));
+       {
+               unsigned c = dec.decode_char(str, i);
+               if(prev)
+                       x += get_glyph_advance(prev, c);
+               prev = c;
+       }
+       x += get_glyph_advance(prev);
 
        return x;
 }
@@ -63,14 +75,19 @@ void Font::build_string(const string &str, StringCodec::Decoder &dec, PrimitiveB
        MatrixStack::Push push_mtx(bld.matrix());
 
        bld.begin(QUADS);
+       unsigned prev = 0;
        for(string::const_iterator i=str.begin(); i!=str.end();)
        {
-               GlyphMap::const_iterator j = glyphs.find(dec.decode_char(str, i));
+               unsigned c = dec.decode_char(str, i);
+               GlyphMap::const_iterator j = glyphs.find(c);
                if(j==glyphs.end())
                        continue;
 
+               if(prev)
+                       bld.matrix() *= Matrix::translation(get_glyph_advance(prev, c), 0, 0);
+
                create_glyph_vertices(j->second, bld);
-               bld.matrix() *= Matrix::translation(j->second.advance, 0, 0);
+               prev = c;
        }
        bld.end();
 }
@@ -87,13 +104,22 @@ void Font::create_glyph_vertices(const Glyph &glyph, VertexBuilder &bld) const
        bld.vertex(glyph.off_x, glyph.off_y+glyph.h);
 }
 
-float Font::get_glyph_advance(unsigned code) const
+float Font::get_glyph_advance(unsigned code, unsigned next) const
 {
        GlyphMap::const_iterator i = glyphs.find(code);
        if(i==glyphs.end())
                return 0;
 
-       return i->second.advance;
+       float advance = i->second.advance;
+
+       if(next)
+       {
+               KerningMap::const_iterator j = kerning.find(KerningKey(code, next));
+               if(j!=kerning.end())
+                       advance += j->second;
+       }
+
+       return advance;
 }
 
 
@@ -117,6 +143,7 @@ void Font::Loader::init()
        add("texture",     &Loader::texture);
        add("texture",     &Loader::texture_ref);
        add("glyph",       &Loader::glyph);
+       add("kerning",     &Loader::kerning);
 }
 
 void Font::Loader::glyph(unsigned c)
@@ -127,6 +154,11 @@ void Font::Loader::glyph(unsigned c)
        obj.glyphs.insert(GlyphMap::value_type(c, gl));
 }
 
+void Font::Loader::kerning(unsigned l, unsigned r, float d)
+{
+       obj.kerning[KerningKey(l, r)] = d;
+}
+
 void Font::Loader::texture()
 {
        RefPtr<Texture2D> tex = new Texture2D;
index fe5a9b34d2355b386e2f891be38e2b71df48ff4c..5fcc63c4414dee39064c7a63fcd92bd35497d4a2 100644 (file)
@@ -25,6 +25,7 @@ public:
        private:
                void init();
                void glyph(unsigned);
+               void kerning(unsigned, unsigned, float);
                void texture();
                void texture_ref(const std::string &);
        };
@@ -49,12 +50,15 @@ public:
 
 private:
        typedef std::map<unsigned, Glyph> GlyphMap;
+       typedef std::pair<unsigned, unsigned> KerningKey;
+       typedef std::map<KerningKey, float> KerningMap;
 
        RefPtr<const Texture2D> texture;
        float native_size;
        float ascent;
        float descent;
        GlyphMap glyphs;
+       KerningMap kerning;
 
 public:
        Font();
@@ -63,6 +67,7 @@ public:
        void set_texture(const Texture2D &);
        const Texture2D &get_texture() const;
        void add_glyph(const Glyph &);
+       void set_kerning(unsigned, unsigned, float);
        float get_native_size() const { return native_size; }
        float get_ascent() const { return ascent; }
        float get_descent() const { return descent; }
@@ -110,7 +115,7 @@ public:
 
 private:
        void create_glyph_vertices(const Glyph &, VertexBuilder &) const;
-       float get_glyph_advance(unsigned) const;
+       float get_glyph_advance(unsigned, unsigned = 0) const;
 };
 
 } // namespace GL