FreeTypeGL-0.0.1: src/demo/makefont.c
/* ============================================================================
* Freetype GL - A C OpenGL Freetype engine
* Platform: Any
* WWW: http://code.google.com/p/freetype-gl/
* ----------------------------------------------------------------------------
* Copyright 2011,2012 Nicolas P. Rougier. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of Nicolas P. Rougier.
* ============================================================================
*/
#include "freetype-gl.h"
// ---------------------------------------------------------------- display ---
void display( void )
{
int viewport[4];
glGetIntegerv( GL_VIEWPORT, viewport );
GLuint width = viewport[2];
GLuint height = viewport[3];
glClearColor(1,1,1,1);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glEnable( GL_TEXTURE_2D );
glColor4f(0,0,0,1);
glBegin(GL_QUADS);
glTexCoord2f( 0, 1 ); glVertex2i( 0, 0 );
glTexCoord2f( 0, 0 ); glVertex2i( 0, height );
glTexCoord2f( 1, 0 ); glVertex2i( width, height );
glTexCoord2f( 1, 1 ); glVertex2i( width, 0 );
glEnd();
glutSwapBuffers( );
}
// ---------------------------------------------------------------- reshape ---
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, 0, height, -1, 1);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
// --------------------------------------------------------------- keyboard ---
void keyboard( unsigned char key, int x, int y )
{
if ( key == 27 )
{
exit( 1 );
}
}
// ------------------------------------------------------------------- main ---
int main( int argc, char **argv )
{
size_t i, j;
wchar_t * font_cache =
L" !\"#$%&'()*+,-./0123456789:;<=>?"
L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
L"`abcdefghijklmnopqrstuvwxyz{|}~";
float font_size = 16.0;
char * font_filename = "fonts/Arial.ttf";
char * header_filename = "arial-16.h";
texture_atlas_t * atlas = texture_atlas_new( 128, 128, 1 );
texture_font_t * font = texture_font_new( atlas, font_filename, font_size );
glutInit( &argc, argv );
glutInitWindowSize( atlas->width, atlas->height );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
glutCreateWindow( "Freetype OpenGL" );
glutReshapeFunc( reshape );
glutDisplayFunc( display );
glutKeyboardFunc( keyboard );
glBindTexture( GL_TEXTURE_2D, atlas->id );
int missed = !!texture_font_load_glyphs( font, font_cache );
wprintf( L"Font filename : %s\n", font_filename );
wprintf( L"Font size : %.1f\n", font_size );
wprintf( L"Number of glyphs : %ld\n", wcslen(font_cache) );
wprintf( L"Have missed glyphs : %d\n", missed );
wprintf( L"Texture size : %ldx%ldx%ld\n",
atlas->width, atlas->height, atlas->depth );
wprintf( L"Texture occupancy : %.2f%%\n",
100.0*atlas->used/(float)(atlas->width*atlas->height) );
wprintf( L"\n" );
wprintf( L"Header filename : %s\n", header_filename );
size_t texture_size = atlas->width * atlas->height *atlas->depth;
size_t glyph_count = font->glyphs->size;
size_t max_kerning_count = 1;
for( i=0; i < glyph_count; ++i )
{
texture_glyph_t *glyph = *(texture_glyph_t **) vector_get( font->glyphs, i );
if( vector_size(glyph->kerning) > max_kerning_count )
{
max_kerning_count = vector_size(glyph->kerning);
}
}
FILE *file = fopen( header_filename, "w" );
// -------------
// Header
// -------------
fwprintf( file,
L"/* ============================================================================\n"
L" * Freetype GL - A C OpenGL Freetype engine\n"
L" * Platform: Any\n"
L" * WWW: http://code.google.com/p/freetype-gl/\n"
L" * ----------------------------------------------------------------------------\n"
L" * Copyright 2011,2012 Nicolas P. Rougier. All rights reserved.\n"
L" *\n"
L" * Redistribution and use in source and binary forms, with or without\n"
L" * modification, are permitted provided that the following conditions are met:\n"
L" *\n"
L" * 1. Redistributions of source code must retain the above copyright notice,\n"
L" * this list of conditions and the following disclaimer.\n"
L" *\n"
L" * 2. Redistributions in binary form must reproduce the above copyright\n"
L" * notice, this list of conditions and the following disclaimer in the\n"
L" * documentation and/or other materials provided with the distribution.\n"
L" *\n"
L" * THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR\n"
L" * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
L" * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n"
L" * EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n"
L" * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n"
L" * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n"
L" * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n"
L" * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
L" * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n"
L" * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
L" *\n"
L" * The views and conclusions contained in the software and documentation are\n"
L" * those of the authors and should not be interpreted as representing official\n"
L" * policies, either expressed or implied, of Nicolas P. Rougier.\n"
L" * ===============================================================================\n"
L" */\n");
// ----------------------
// Structure declarations
// ----------------------
fwprintf( file,
L"#include <stddef.h>\n"
L"\n"
L"typedef struct\n"
L"{\n"
L" wchar_t charcode;\n"
L" float kerning;\n"
L"} kerning_t;\n\n" );
fwprintf( file,
L"typedef struct\n"
L"{\n"
L" wchar_t charcode;\n"
L" int width, height;\n"
L" int offset_x, offset_y;\n"
L" float advance_x, advance_y;\n"
L" float s0, t0, s1, t1;\n"
L" size_t kerning_count;\n"
L" kerning_t kerning[%d];\n"
L"} texture_glyph_t;\n\n", max_kerning_count );
fwprintf( file,
L"typedef struct\n"
L"{\n"
L" size_t tex_width;\n"
L" size_t tex_height;\n"
L" size_t tex_depth;\n"
L" char tex_data[%d];\n"
L" float size;\n"
L" float height;\n"
L" float linegap;\n"
L" float ascender;\n"
L" float descender;\n"
L" size_t glyphs_count;\n"
L" texture_glyph_t glyphs[%d];\n"
L"} texture_font_t;\n\n", texture_size, glyph_count );
fwprintf( file, L"texture_font_t font = {\n" );
// ------------
// Texture data
// ------------
fwprintf( file, L" %d, %d, %d, \n", atlas->width, atlas->height, atlas->depth );
fwprintf( file, L" {" );
for( i=0; i < texture_size; i+= 32 )
{
for( j=0; j < 32 && (j+i) < texture_size ; ++ j)
{
if( (j+i) < (texture_size-1) )
{
fwprintf( file, L"%d,", atlas->data[i+j] );
}
else
{
fwprintf( file, L"%d", atlas->data[i+j] );
}
}
if( (j+i) < texture_size )
{
fwprintf( file, L"\n " );
}
}
fwprintf( file, L"}, \n" );
// -------------------
// Texture information
// -------------------
fwprintf( file, L" %f, %f, %f, %f, %f, %d, \n",
font->size, font->height,
font->linegap,font->ascender, font->descender,
glyph_count );
// --------------
// Texture glyphs
// --------------
fwprintf( file, L" {\n" );
for( i=0; i < glyph_count; ++i )
{
texture_glyph_t * glyph = *(texture_glyph_t **) vector_get( font->glyphs, i );
/*
// Debugging information
wprintf( L"glyph : '%lc'\n",
glyph->charcode );
wprintf( L" size : %dx%d\n",
glyph->width, glyph->height );
wprintf( L" offset : %+d%+d\n",
glyph->offset_x, glyph->offset_y );
wprintf( L" advance : %f, %f\n",
glyph->advance_x, glyph->advance_y );
wprintf( L" tex coords.: %f, %f, %f, %f\n",
glyph->u0, glyph->v0, glyph->u1, glyph->v1 );
wprintf( L" kerning : " );
if( glyph->kerning_count )
{
for( j=0; j < glyph->kerning_count; ++j )
{
wprintf( L"('%lc', %f)",
glyph->kerning[j].charcode, glyph->kerning[j].kerning );
if( j < (glyph->kerning_count-1) )
{
wprintf( L", " );
}
}
}
else
{
wprintf( L"None" );
}
wprintf( L"\n\n" );
*/
// TextureFont
if( (glyph->charcode == L'\'' ) || (glyph->charcode == L'\\' ) )
{
fwprintf( file, L" {L'\\%lc', ", glyph->charcode );
//wprintf( L" {L'\\%lc', ", glyph->charcode );
}
else if( (glyph->charcode == (wchar_t)(-1) ) )
{
fwprintf( file, L" {L'\\0', " );
//wprintf( L" {L'\\0', " );
}
else
{
fwprintf( file, L" {L'%lc', ", glyph->charcode );
//wprintf( L" {L'%lc', ", glyph->charcode );
}
fwprintf( file, L"%d, %d, ", glyph->width, glyph->height );
fwprintf( file, L"%d, %d, ", glyph->offset_x, glyph->offset_y );
fwprintf( file, L"%f, %f, ", glyph->advance_x, glyph->advance_y );
fwprintf( file, L"%f, %f, %f, %f, ", glyph->s0, glyph->t0, glyph->s1, glyph->t1 );
fwprintf( file, L"%d, ", vector_size(glyph->kerning) );
fwprintf( file, L"{ " );
for( j=0; j < vector_size(glyph->kerning); ++j )
{
kerning_t *kerning = (kerning_t *) vector_get( glyph->kerning, j);
wchar_t charcode = kerning->charcode;
if( (charcode == L'\'' ) || (charcode == L'\\') )
{
fwprintf( file, L"{L'\\%lc', %f}", charcode, kerning->kerning );
}
else if( (charcode != (wchar_t)(-1) ) )
{
fwprintf( file, L"{L'%lc', %f}", charcode, kerning->kerning );
}
if( j < (vector_size(glyph->kerning)-1))
{
fwprintf( file, L", " );
}
}
fwprintf( file, L"} },\n" );
}
fwprintf( file, L" }\n};\n" );
return 0;
}