OpenGLEAN
OpenGLEAN gleanfonts User Support
Home page | Introduction | Documentation | Files | Examples | Proposals | Authors | Links


OpenGLEAN gleanfonts development
Summary | CVS | (discussion via home page) | (contact via home page) | (suggestion box) | License | Todo | Bugs

fonts.c File Reference

Include dependency graph for fonts.c:


Detailed Description

Draws a lighted, spinning planet with a flagpole. At the end of the flagpole are the words "Hello" and "World" on two separate lines. A menu lets you select any builtin gleanfonts font for the text.

This program shows the built-in bitmap fonts, selectable via a menu. Bitmapped fonts are positioned according to the current OpenGL raster position. Stroked fonts are positioned according to the current modelview matrix.

The old OpenGLUT fonts "demo" was a test program to verify the font bitmaps and to compare pixel-for-pixel with old GLUT. That program now resides as a test program in the "tests" directory.

This program primarily demonstrates:

Since this demo is included in the gleanfonts online documentation, which is indexed by Internet search engines, it is worth enumerating some other minor things demonstrated:

Author:
Copyright 2004-2005, the OpenGLEAN Project.

Copyright (C) 2004, the OpenGLUT project contributors.

openglean_fonts.png

OpenGLEAN Font Demonstration

#include <stdlib.h>

#include <GL/gleanfonts.h>
#include <GL/gleanshapes.h>
#include <GL/openglean.h>

#define NUMBEROF(a)   ((sizeof (a)) / sizeof (a [0]))

/*
 * Some lighting and material values.  Not particularly
 * of interest since this is not a lighting or material
 * demo.  If you must know, though: l0 refers to Light 0;
 * plan refers to the planet,  and pole refers to the flagpole.
 */
GLfloat l0_pos [] = {0, 0, 0, 1};
GLfloat l0_amb [] = {.05, .05, .1, 1};
GLfloat l0_diff [] = {.95, .95, .8, 1};

GLfloat plan_diff [] = {.15, .5, .7, 1};
GLfloat plan_spec [] = {.8, .9, 1, 1};

GLfloat pole_diff [] = {.8, .4, .4, 1};
GLfloat pole_spec [] = {1, 1, 1, 1};

/*
 * A handle on the main window.
 */
int main_window;

/*
 * The current font.  Can be any of the builtin fonts.
 */
GLUTfont font;

/*
 * Our text message is displayed at the top of a flag.  This
 * symbolic constant is the distance from the core of the planet
 * to the top of the flagpole.
 */
#ifndef FLAG_HEIGHT
#define FLAG_HEIGHT 5
#endif

/*
 * This structure is used to simplify associating a GLUT font
 * with a GLUT menu item.
 */
struct font_map
{
    GLUTfont   id;
    const char *const name;
};

struct font_map fixed_map [] =
{
    {GLUT_BITMAP_8_BY_13,      "Fixed 8x13"},
    {GLUT_BITMAP_8_BY_13_BOLD, "Fixed 8x13 (bold)"},
    {GLUT_BITMAP_9_BY_15,      "Fixed 9x15"},
    {GLUT_BITMAP_9_BY_15_BOLD, "Fixed 9x15 (bold)"},
};
struct font_map courier_map [] =
{
    {GLUT_BITMAP_COURIER_8,             "Courier 8"},
    {GLUT_BITMAP_COURIER_8_BOLD,        "Courier 8 (bold)"},
    {GLUT_BITMAP_COURIER_8_BOLD_ITALIC, "Courier 8 (bold italic)"},
    {GLUT_BITMAP_COURIER_8_ITALIC,      "Courier 8 (italic)"},

    {GLUT_BITMAP_COURIER_10,             "Courier 10"},
    {GLUT_BITMAP_COURIER_10_BOLD,        "Courier 10 (bold)"},
    {GLUT_BITMAP_COURIER_10_BOLD_ITALIC, "Courier 10 (bold italic)"},
    {GLUT_BITMAP_COURIER_10_ITALIC,      "Courier 10 (italic)"},

    {GLUT_BITMAP_COURIER_12,             "Courier 12"},
    {GLUT_BITMAP_COURIER_12_BOLD,        "Courier 12 (bold)"},
    {GLUT_BITMAP_COURIER_12_BOLD_ITALIC, "Courier 12 (bold italic)"},
    {GLUT_BITMAP_COURIER_12_ITALIC,      "Courier 12 (italic)"},

    {GLUT_BITMAP_COURIER_14,             "Courier 14"},
    {GLUT_BITMAP_COURIER_14_BOLD,        "Courier 14 (bold)"},
    {GLUT_BITMAP_COURIER_14_BOLD_ITALIC, "Courier 14 (bold italic)"},
    {GLUT_BITMAP_COURIER_14_ITALIC,      "Courier 14 (italic)"},

    {GLUT_BITMAP_COURIER_18,             "Courier 18"},
    {GLUT_BITMAP_COURIER_18_BOLD,        "Courier 18 (bold)"},
    {GLUT_BITMAP_COURIER_18_BOLD_ITALIC, "Courier 18 (bold italic)"},
    {GLUT_BITMAP_COURIER_18_ITALIC,      "Courier 18 (italic)"},

    {GLUT_BITMAP_COURIER_24,             "Courier 24"},
    {GLUT_BITMAP_COURIER_24_BOLD,        "Courier 24 (bold)"},
    {GLUT_BITMAP_COURIER_24_BOLD_ITALIC, "Courier 24 (bold italic)"},
    {GLUT_BITMAP_COURIER_24_ITALIC,      "Courier 24 (italic)"},
};
struct font_map helvetica_map [] =
{
    {GLUT_BITMAP_HELVETICA_8,             "Helvetica 8"},
    {GLUT_BITMAP_HELVETICA_8_BOLD,        "Helvetica 8 (bold)"},
    {GLUT_BITMAP_HELVETICA_8_BOLD_ITALIC, "Helvetica 8 (bold italic)"},
    {GLUT_BITMAP_HELVETICA_8_ITALIC,      "Helvetica 8 (italic)"},

    {GLUT_BITMAP_HELVETICA_10,             "Helvetica 10"},
    {GLUT_BITMAP_HELVETICA_10_BOLD,        "Helvetica 10 (bold)"},
    {GLUT_BITMAP_HELVETICA_10_BOLD_ITALIC, "Helvetica 10 (bold italic)"},
    {GLUT_BITMAP_HELVETICA_10_ITALIC,      "Helvetica 10 (italic)"},

    {GLUT_BITMAP_HELVETICA_12,             "Helvetica 12"},
    {GLUT_BITMAP_HELVETICA_12_BOLD,        "Helvetica 12 (bold)"},
    {GLUT_BITMAP_HELVETICA_12_BOLD_ITALIC, "Helvetica 12 (bold italic)"},
    {GLUT_BITMAP_HELVETICA_12_ITALIC,      "Helvetica 12 (italic)"},

    {GLUT_BITMAP_HELVETICA_14,             "Helvetica 14"},
    {GLUT_BITMAP_HELVETICA_14_BOLD,        "Helvetica 14 (bold)"},
    {GLUT_BITMAP_HELVETICA_14_BOLD_ITALIC, "Helvetica 14 (bold italic)"},
    {GLUT_BITMAP_HELVETICA_14_ITALIC,      "Helvetica 14 (italic)"},

    {GLUT_BITMAP_HELVETICA_18,             "Helvetica 18"},
    {GLUT_BITMAP_HELVETICA_18_BOLD,        "Helvetica 18 (bold)"},
    {GLUT_BITMAP_HELVETICA_18_BOLD_ITALIC, "Helvetica 18 (bold italic)"},
    {GLUT_BITMAP_HELVETICA_18_ITALIC,      "Helvetica 18 (italic)"},

    {GLUT_BITMAP_HELVETICA_24,             "Helvetica 24"},
    {GLUT_BITMAP_HELVETICA_24_BOLD,        "Helvetica 24 (bold)"},
    {GLUT_BITMAP_HELVETICA_24_BOLD_ITALIC, "Helvetica 24 (bold italic)"},
    {GLUT_BITMAP_HELVETICA_24_ITALIC,      "Helvetica 24 (italic)"},
};
struct font_map times_roman_map [] =
{
    {GLUT_BITMAP_TIMES_ROMAN_8,             "Times Roman 8"},
    {GLUT_BITMAP_TIMES_ROMAN_8_BOLD,        "Times Roman 8 (bold)"},
    {GLUT_BITMAP_TIMES_ROMAN_8_BOLD_ITALIC, "Times Roman 8 (bold italic)"},
    {GLUT_BITMAP_TIMES_ROMAN_8_ITALIC,      "Times Roman 8 (italic)"},

    {GLUT_BITMAP_TIMES_ROMAN_10,             "Times Roman 10"},
    {GLUT_BITMAP_TIMES_ROMAN_10_BOLD,        "Times Roman 10 (bold)"},
    {GLUT_BITMAP_TIMES_ROMAN_10_BOLD_ITALIC, "Times Roman 10 (bold italic)"},
    {GLUT_BITMAP_TIMES_ROMAN_10_ITALIC,      "Times Roman 10 (italic)"},

    {GLUT_BITMAP_TIMES_ROMAN_12,             "Times Roman 12"},
    {GLUT_BITMAP_TIMES_ROMAN_12_BOLD,        "Times Roman 12 (bold)"},
    {GLUT_BITMAP_TIMES_ROMAN_12_BOLD_ITALIC, "Times Roman 12 (bold italic)"},
    {GLUT_BITMAP_TIMES_ROMAN_12_ITALIC,      "Times Roman 12 (italic)"},

    {GLUT_BITMAP_TIMES_ROMAN_14,             "Times Roman 14"},
    {GLUT_BITMAP_TIMES_ROMAN_14_BOLD,        "Times Roman 14 (bold)"},
    {GLUT_BITMAP_TIMES_ROMAN_14_BOLD_ITALIC, "Times Roman 14 (bold italic)"},
    {GLUT_BITMAP_TIMES_ROMAN_14_ITALIC,      "Times Roman 14 (italic)"},

    {GLUT_BITMAP_TIMES_ROMAN_18,             "Times Roman 18"},
    {GLUT_BITMAP_TIMES_ROMAN_18_BOLD,        "Times Roman 18 (bold)"},
    {GLUT_BITMAP_TIMES_ROMAN_18_BOLD_ITALIC, "Times Roman 18 (bold italic)"},
    {GLUT_BITMAP_TIMES_ROMAN_18_ITALIC,      "Times Roman 18 (italic)"},

    {GLUT_BITMAP_TIMES_ROMAN_24,             "Times Roman 24"},
    {GLUT_BITMAP_TIMES_ROMAN_24_BOLD,        "Times Roman 24 (bold)"},
    {GLUT_BITMAP_TIMES_ROMAN_24_BOLD_ITALIC, "Times Roman 24 (bold italic)"},
    {GLUT_BITMAP_TIMES_ROMAN_24_ITALIC,      "Times Roman 24 (italic)"},
};
struct font_map symbol_map [] =
{
    {GLUT_BITMAP_SYMBOL_8,  "Symbol 8"},
    {GLUT_BITMAP_SYMBOL_10, "Symbol 10"},
    {GLUT_BITMAP_SYMBOL_12, "Symbol 12"},
    {GLUT_BITMAP_SYMBOL_14, "Symbol 14"},
    {GLUT_BITMAP_SYMBOL_18, "Symbol 18"},
    {GLUT_BITMAP_SYMBOL_24, "Symbol 24"},
};
struct font_map stroked_roman_map [] =
{
    {GLUT_STROKE_ROMAN,      "Stroked Roman"},
    {GLUT_STROKE_MONO_ROMAN, "Stroked Mono Roman"}
};


/*
 * Writes a given string in the current( global ){font}.
 * The string is drawn at the location corresponding to the modelspace
 * origin, providing a somewhat unified interface for the 2 classes
 * of fonts.
 */
void write_string (const char *s)
{
    glDisable (GL_LIGHTING);
    glColor3d (1, 1, 1);

    if ((GLUT_STROKE_ROMAN == font) || (GLUT_STROKE_MONO_ROMAN == font))
    {
        /*
         * Stroked fonts are about 100 model units tall.
         * This scales the font down to something usable in the current
         * context.
         */
        static GLfloat  f = 1.0 / 64;

        glScalef (f, f, f);
        glutStrokeString (font, (const GLubyte *) s);
        glScalef (1 / f, 1 / f, 1 / f);
    }
    else
    {
        glRasterPos3f (0, 0, 0);
        glutBitmapString (font, (const GLubyte *) s);
    }
    glEnable (GL_LIGHTING);
}


/*
 * The main window's display callback renders a small bluish world
 * with a flagpole, flying an eerily familiar banner.
 */
void cb_display (void)
{
    int msec = glutGet (GLUT_ELAPSED_TIME);

    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPushMatrix ();
    glRotated (msec / 50.0, 0, 1, 0);
    glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, plan_diff);
    glMateriali (GL_FRONT, GL_SHININESS, 100);
    glMaterialfv (GL_FRONT, GL_SPECULAR, plan_spec);
    glutSolidSphere (3, 20, 20);
    glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, pole_diff);
    glMaterialfv (GL_FRONT, GL_SPECULAR, pole_spec);
    glutSolidCylinder (.1, FLAG_HEIGHT, 6, 3);
    glTranslated (0, 0, FLAG_HEIGHT);
    write_string ("Hello\nWorld!");
    glPopMatrix ();

    glutSwapBuffers ();
}

/*
 * All your shape belong to us.
 *
 * Err, sorry.  Nothing especially font-oriented here.
 */
void cb_reshape (int w, int h)
{
    GLdouble        r = w * 1.0 / h;

    glViewport (0, 0, w, h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    if (r < 1)
        glFrustum (-1, 1, -1 / r, 1 / r, 3, 100);
    else
        glFrustum (-r, r, -1, 1, 3, 100);

    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity ();

    glEnable (GL_CULL_FACE);
    glEnable (GL_DEPTH_TEST);
    glEnable (GL_LIGHTING);
    glEnable (GL_LIGHT0);
    glLightfv (GL_LIGHT0, GL_POSITION, l0_pos);
    glLightfv (GL_LIGHT0, GL_AMBIENT, l0_amb);
    glLightfv (GL_LIGHT0, GL_DIFFUSE, l0_pos);
    glTranslated (0, 0, -30);

    glutPostRedisplay ();
}

/*
 * Idle functions are covered elsewhere.  We just use this one
 * to keep the window updating when nothing else is happening.
 */
void cb_idle (void)
{
    glutSetWindow (main_window);
    glutPostRedisplay ();
}


/*
 * To avoid having approximately 90 fonts listed in one huge menu,
 * the fonts are broken up by category.  The various category-specific
 * font menus are all very similar, so we use a macro to generate the
 * callback functions.
 */
#define CB_MENU(FONT)                \
void cb_ ## FONT ## _menu (int item) \
{                                    \
    font = FONT ## _map [item].id;   \
}
CB_MENU(fixed)
CB_MENU(courier)
CB_MENU(helvetica)
CB_MENU(stroked_roman)
CB_MENU(symbol)
CB_MENU(times_roman)

/*
 * These really don't have anything to do, but it seems
 * better than re-using another menu even for a NOP.
 * These menus are simply placeholders for other menus.
 */
void cb_bitmapped_menu (int item)
{
    (void) item;
}
void cb_stroked_menu (int item)
{
    (void) item;
}

#define MAIN_MENU_QUIT 'Q'
void cb_main_menu (int item)
{
    switch (item)
    {
    case MAIN_MENU_QUIT:
        exit (0);
        break;
    default:
        // fprintf (stderr, "You should never see this.\n");
        exit (1);
        break;
    }
}

int main (int argc, char **argv)
{
    unsigned int i;
    int main_menu;
    int bitmapped_menu;
    int stroked_menu;

    int courier_menu;
    int fixed_menu;
    int helvetica_menu;
    int stroked_roman_menu;
    int symbol_menu;
    int times_roman_menu;

    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_DEPTH | GLUT_DOUBLE);
    main_window = glutCreateWindow ("OpenGLEAN fonts");
    glutDisplayFunc (cb_display);
    glutReshapeFunc (cb_reshape);
    glutIdleFunc (cb_idle);

    main_menu = glutCreateMenu (cb_main_menu);
    bitmapped_menu = glutCreateMenu (cb_bitmapped_menu);

    courier_menu = glutCreateMenu (cb_courier_menu);
    for (i = 0; i < NUMBEROF (courier_map); ++i)
        glutAddMenuEntry (courier_map [i].name, i);
    glutSetMenu (bitmapped_menu);
    glutAddSubMenu ("Courier", courier_menu);

    fixed_menu = glutCreateMenu (cb_fixed_menu);
    for (i = 0; i < NUMBEROF (fixed_map); ++i)
        glutAddMenuEntry (fixed_map [i].name, i);
    glutSetMenu (bitmapped_menu);
    glutAddSubMenu ("Fixed", fixed_menu);

    helvetica_menu = glutCreateMenu (cb_helvetica_menu);
    for (i = 0; i < NUMBEROF (helvetica_map); ++i)
        glutAddMenuEntry (helvetica_map [i].name, i);
    glutSetMenu (bitmapped_menu);
    glutAddSubMenu ("Helvetica", helvetica_menu);

    symbol_menu = glutCreateMenu (cb_symbol_menu);
    for (i = 0; i < NUMBEROF (symbol_map); ++i)
        glutAddMenuEntry (symbol_map [i].name, i);
    glutSetMenu (bitmapped_menu);
    glutAddSubMenu ("Symbol", symbol_menu);

    times_roman_menu = glutCreateMenu (cb_times_roman_menu);
    for (i = 0; i < NUMBEROF (times_roman_map); ++i)
        glutAddMenuEntry (times_roman_map [i].name, i);
    glutSetMenu (bitmapped_menu);
    glutAddSubMenu ("Times Roman", times_roman_menu);

    stroked_menu = glutCreateMenu (cb_stroked_menu);

    stroked_roman_menu = glutCreateMenu (cb_stroked_roman_menu);
    for (i = 0; i < NUMBEROF (stroked_roman_map); ++i)
        glutAddMenuEntry (stroked_roman_map [i].name, i);
    glutSetMenu (stroked_menu);
    glutAddSubMenu ("Stroked Roman", stroked_roman_menu);

    glutSetMenu (main_menu);    
    glutAddSubMenu ("Bitmapped", bitmapped_menu);
    glutAddSubMenu ("Stroked", stroked_menu);
    glutAddMenuEntry ("Quit", MAIN_MENU_QUIT);
    glutAttachMenu (2);

    font = GLUT_BITMAP_8_BY_13;
    glutMainLoop ();

    return EXIT_SUCCESS;
}




SourceForge.net Logo Supported in part by SourceForge.net.

Generated on Sun Sep 18 12:47:18 2005 for gleanfonts by doxygen 1.4.3
The OpenGLEAN Fonts project is hosted by SourceForge.