Index: /trunk/nv/gl/image.hh
===================================================================
--- /trunk/nv/gl/image.hh	(revision 20)
+++ /trunk/nv/gl/image.hh	(revision 21)
@@ -26,4 +26,5 @@
 	public:
 		image( glm::ivec2 size, size_t depth );
+		image( glm::ivec2 size, size_t depth, const uint8 * data, bool reversed = false );
 		void clear();
 		void fill( uint8 value );
Index: /trunk/nv/gl/texture_font.hh
===================================================================
--- /trunk/nv/gl/texture_font.hh	(revision 21)
+++ /trunk/nv/gl/texture_font.hh	(revision 21)
@@ -0,0 +1,57 @@
+// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+#ifndef NV_GL_TEXTURE_FONT_HH
+#define NV_GL_TEXTURE_FONT_HH
+
+#include <nv/common.hh>
+#include <nv/gl/texture_atlas.hh>
+#include <glm/glm.hpp>
+#include <unordered_map>
+
+namespace nv
+{
+	struct texture_gylph
+	{
+	    uint16 charcode;
+		glm::ivec2 size;
+	    glm::ivec2 offset;
+	    glm::vec2 advance;
+	    glm::vec2 tl;
+	    glm::vec2 br;
+		std::unordered_map< uint16, float > kerning;
+
+		texture_gylph();
+		float get_kerning( const uint16 charcode );
+	};
+
+	class texture_font
+	{
+	public:
+		texture_font( texture_atlas* atlas, const char * filename, float size );
+		const texture_gylph* get_gylph( uint16 charcode ) const;
+		bool load_glyphs( const std::string& codes );
+		~texture_font();
+	private:
+		void generate_kerning();
+	private:
+		std::unordered_map< uint16, texture_gylph > m_gylphs;
+		texture_atlas* m_atlas;
+		std::string m_filename;
+		float m_size;
+	    float m_height;
+	    float m_linegap;
+	    float m_ascender;
+	    float m_descender;
+		bool m_hinting;
+		bool m_filtering;
+		uint8 m_lcd_weights[5];
+		void* m_rlibrary;
+		void* m_rface;
+	};
+}
+
+#endif // NV_GL_TEXTURE_FONT_HH
Index: /trunk/nv/lib/gl.hh
===================================================================
--- /trunk/nv/lib/gl.hh	(revision 20)
+++ /trunk/nv/lib/gl.hh	(revision 21)
@@ -162,4 +162,5 @@
 #define GL_MAX_VIEWPORT_DIMS 0x0D3A
 #define GL_SUBPIXEL_BITS 0x0D50
+#define GL_TEXTURE_2D 0x0DE1
 #define GL_POLYGON_OFFSET_UNITS 0x2A00
 #define GL_POLYGON_OFFSET_POINT 0x2A01
@@ -501,6 +502,6 @@
 NV_GL_FUN( void , glScissor , ( GLint , GLint , GLsizei , GLsizei ) );
 NV_GL_FUN( void , glTexParameterf , ( GLenum , GLenum , GLfloat ) );
-NV_GL_FUN( void , glTexParameterfv , ( GLenum , GLenum , const GLint *) );
-NV_GL_FUN( void , glTexParameteri , ( GLenum , GLenum , GLfloat ) );
+NV_GL_FUN( void , glTexParameterfv , ( GLenum , GLenum , const GLfloat *) );
+NV_GL_FUN( void , glTexParameteri , ( GLenum , GLenum , GLint ) );
 NV_GL_FUN( void , glTexParameteriv , ( GLenum , GLenum , const GLint *) );
 NV_GL_FUN( void , glTexImage1D , ( GLenum , GLint , GLint , GLsizei , GLint , GLenum , GLenum , const GLvoid *) );
@@ -551,5 +552,5 @@
 NV_GL_FUN( void , glTexSubImage1D , ( GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *) );
 NV_GL_FUN( void , glTexSubImage2D , ( GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *) );
-NV_GL_FUN( void , glBindTexture , ( GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *) );
+NV_GL_FUN( void , glBindTexture , ( GLenum , GLuint ) );
 NV_GL_FUN( void , glDeleteTextures , ( GLsizei , const GLuint *) );
 NV_GL_FUN( void , glGenTextures , ( GLsizei , GLuint *) );
Index: /trunk/src/gl/image.cc
===================================================================
--- /trunk/src/gl/image.cc	(revision 20)
+++ /trunk/src/gl/image.cc	(revision 21)
@@ -13,4 +13,23 @@
 {
 	m_data = new uint8[ m_size.x * m_size.y * m_depth ];
+}
+
+image::image( glm::ivec2 size, size_t depth, const uint8 * data, bool reversed )
+	: m_size( size ), m_depth( depth ), m_data( nullptr )
+{
+	m_data = new uint8[ m_size.x * m_size.y * m_depth ];
+
+	if ( reversed )
+	{
+		for( size_t i = 0; i < size.y; ++i )
+		{
+			memcpy( m_data + size.x * ( size.y - i - 1) * m_depth, data + i * size.x * m_depth, m_size.x * m_depth );
+		}
+
+	}
+	else 
+	{
+		memcpy( m_data, data, m_size.x * m_size.y * m_depth );
+	}
 }
 
@@ -36,2 +55,3 @@
 }
 
+
Index: /trunk/src/gl/texture_font.cc
===================================================================
--- /trunk/src/gl/texture_font.cc	(revision 21)
+++ /trunk/src/gl/texture_font.cc	(revision 21)
@@ -0,0 +1,149 @@
+// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+#include "nv/gl/texture_font.hh"
+
+#include "nv/lib/freetype2.hh"
+
+using namespace nv;
+
+texture_gylph::texture_gylph()
+	: charcode(0), size(0,0), offset(0,0), advance(0.f,0.f), tl(0.f,0.f), br(0.f,0.f)
+{
+}
+
+float texture_gylph::get_kerning( const uint16 charcode )
+{
+	auto i = kerning.find( charcode );
+	return i != kerning.end() ? i->second : 0.0f;
+}
+
+texture_font::texture_font( texture_atlas* atlas, const char * filename, float size )
+	: m_atlas( atlas ), m_filename(filename), m_size( size ), 
+	m_height(0), m_linegap(0), m_ascender(0), m_descender(0),
+	m_rlibrary( nullptr ), m_rface( nullptr ), m_hinting( true ), m_filtering( true )
+{
+	size_t hres = 64;
+	FT_Error error;
+	FT_Matrix matrix = { 
+		(int)((1.0/hres) * 0x10000L),
+		(int)((0.0)      * 0x10000L),
+		(int)((0.0)      * 0x10000L),
+		(int)((1.0)      * 0x10000L) 
+	};
+
+	m_lcd_weights[0] = 0x10;
+	m_lcd_weights[1] = 0x40;
+	m_lcd_weights[2] = 0x70;
+	m_lcd_weights[3] = 0x40;
+	m_lcd_weights[4] = 0x10;
+	 
+	error = FT_Init_FreeType( (FT_Library*)(&m_rlibrary) );
+	if ( error ) throw std::runtime_error( "FT_Error" );
+
+	error = FT_New_Face( (FT_Library)(m_rlibrary), filename, 0, (FT_Face*)(&m_rface) );
+	if ( error ) throw std::runtime_error( "FT_Error" );
+
+	error = FT_Set_Char_Size( (FT_Face)(m_rface), (int)(size*64), 0, 72*64, 72 ); 
+	if ( error ) throw std::runtime_error( "FT_Error" );
+
+    FT_Set_Transform( (FT_Face)(m_rface), &matrix, NULL );
+
+    FT_Size_Metrics metrics = ((FT_Face)(m_rface))->size->metrics; 
+    m_ascender = (metrics.ascender >> 6) / 100.0;
+    m_descender = (metrics.descender >> 6) / 100.0;
+    m_height = (metrics.height >> 6) / 100.0;
+    m_linegap = m_height - m_ascender + m_descender; 
+}
+
+const texture_gylph* texture_font::get_gylph( uint16 charcode ) const
+{
+	auto i = m_gylphs.find( charcode );
+	if ( i == m_gylphs.end() )
+	{
+		return nullptr;
+	}
+	return &(i->second);
+}
+
+bool texture_font::load_glyphs( const std::string& codes )
+{
+	FT_Face face     = (FT_Face)(m_rface);
+	size_t depth     = m_atlas->get_depth();
+	glm::ivec2 asize = m_atlas->get_size();
+	FT_Int32 flags = 0; 
+	flags |= FT_LOAD_RENDER; 
+	if( !m_hinting )
+	{
+		flags |= FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT;
+	}
+	else
+	{
+		flags |= FT_LOAD_FORCE_AUTOHINT;
+	} 
+
+	if( m_atlas->get_depth() == 3 )
+	{
+		FT_Library_SetLcdFilter( (FT_Library)(m_rlibrary), FT_LCD_FILTER_LIGHT );
+		flags |= FT_LOAD_TARGET_LCD;
+		if ( m_filtering )
+		{
+			FT_Library_SetLcdFilterWeights( (FT_Library)(m_rlibrary), m_lcd_weights );
+		}
+	} 
+
+	for ( char c : codes )
+	{
+		FT_UInt glyph_index = FT_Get_Char_Index( face, c ); 
+		FT_Error error = FT_Load_Glyph( face, glyph_index, flags ); 
+		if ( error ) throw std::runtime_error( "FT_Error while loading gylphs" );
+
+		FT_GlyphSlot slot   = face->glyph;
+		FT_Bitmap ft_bitmap = slot->bitmap;
+		int ft_bitmap_width = slot->bitmap.width;
+		int ft_bitmap_rows  = slot->bitmap.rows;
+		int ft_glyph_top    = slot->bitmap_top;
+		int ft_glyph_left   = slot->bitmap_left;
+
+		glm::ivec2 gsize( ft_bitmap_width/depth + 1, ft_bitmap_rows + 1 ); 
+		region r = m_atlas->get_region( gsize );
+		if ( r.pos.x < 0 ) 
+		{
+			throw std::runtime_error( "Atlas full while loading gylphs" );
+		}
+		r.size.x -= 1;
+		r.size.y -= 1;
+		m_atlas->set_region( r, ft_bitmap.buffer, ft_bitmap.pitch );
+
+		m_gylphs[ c ] = texture_gylph();
+		texture_gylph* g = &(m_gylphs.find( c )->second);
+
+		g->charcode = c;
+		g->size     = gsize;
+		g->offset   = glm::ivec2( ft_glyph_left, ft_glyph_top );
+		g->tl       = glm::vec2( r.pos.x/(float)asize.x, r.pos.y/(float)asize.y );
+		g->br       = glm::vec2( ( r.pos.x + gsize.x )/(float)asize.x, (r.pos.y + gsize.y )/(float)asize.y );
+
+		// Discard hinting to get advance
+		FT_Load_Glyph( face, glyph_index, FT_LOAD_RENDER | FT_LOAD_NO_HINTING);
+		slot = face->glyph;
+		g->advance = glm::ivec2( slot->advance.x/64.0, slot->advance.y/64.0 );
+	}
+	generate_kerning();
+	return true;
+}
+
+texture_font::~texture_font()
+{
+	if ( m_rface )    FT_Done_Face( (FT_Face)(m_rface) );
+	if ( m_rlibrary ) FT_Done_FreeType( (FT_Library)(m_rlibrary) );
+}
+
+void texture_font::generate_kerning()
+{
+
+}
+
Index: /trunk/src/lib/freetype2.cc
===================================================================
--- /trunk/src/lib/freetype2.cc	(revision 20)
+++ /trunk/src/lib/freetype2.cc	(revision 21)
Index: /trunk/src/lib/gl.cc
===================================================================
--- /trunk/src/lib/gl.cc	(revision 20)
+++ /trunk/src/lib/gl.cc	(revision 21)
@@ -25,6 +25,6 @@
 void (NV_GL_APIENTRY *glScissor) ( GLint , GLint , GLsizei , GLsizei ) = nullptr;
 void (NV_GL_APIENTRY *glTexParameterf) ( GLenum , GLenum , GLfloat ) = nullptr;
-void (NV_GL_APIENTRY *glTexParameterfv) ( GLenum , GLenum , const GLint *) = nullptr;
-void (NV_GL_APIENTRY *glTexParameteri) ( GLenum , GLenum , GLfloat ) = nullptr;
+void (NV_GL_APIENTRY *glTexParameterfv) ( GLenum , GLenum , const GLfloat *) = nullptr;
+void (NV_GL_APIENTRY *glTexParameteri) ( GLenum , GLenum , GLint ) = nullptr;
 void (NV_GL_APIENTRY *glTexParameteriv) ( GLenum , GLenum , const GLint *) = nullptr;
 void (NV_GL_APIENTRY *glTexImage1D) ( GLenum , GLint , GLint , GLsizei , GLint , GLenum , GLenum , const GLvoid *) = nullptr;
@@ -75,5 +75,5 @@
 void (NV_GL_APIENTRY *glTexSubImage1D) ( GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *) = nullptr;
 void (NV_GL_APIENTRY *glTexSubImage2D) ( GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *) = nullptr;
-void (NV_GL_APIENTRY *glBindTexture) ( GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *) = nullptr;
+void (NV_GL_APIENTRY *glBindTexture) ( GLenum , GLuint ) = nullptr;
 void (NV_GL_APIENTRY *glDeleteTextures) ( GLsizei , const GLuint *) = nullptr;
 void (NV_GL_APIENTRY *glGenTextures) ( GLsizei , GLuint *) = nullptr;
