packages feed

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;
}