/* Copyright (c) Mark J. Kilgard, 1994, 1998. This program is freely distributable without licensing fees and is provided without guarantee or warrantee expressed or implied. This program is -not- in the public domain. */ #include "internal.h" #include "font.h" #if defined(_WIN32) || defined (GLUT_IMPORT_LIB) static inline void* __glutFont( void *font ) { switch((long)font) { case (long)GLUT_STROKE_ROMAN: return &glutStrokeRoman; case (long)GLUT_STROKE_MONO_ROMAN: return &glutStrokeMonoRoman; case (long)GLUT_BITMAP_9_BY_15: return &glutBitmap9By15; case (long)GLUT_BITMAP_8_BY_13: return &glutBitmap8By13; case (long)GLUT_BITMAP_TIMES_ROMAN_10: return &glutBitmapTimesRoman10; case (long)GLUT_BITMAP_TIMES_ROMAN_24: return &glutBitmapTimesRoman24; case (long)GLUT_BITMAP_HELVETICA_10: return &glutBitmapHelvetica10; case (long)GLUT_BITMAP_HELVETICA_12: return &glutBitmapHelvetica12; case (long)GLUT_BITMAP_HELVETICA_18: return &glutBitmapHelvetica18; } return NULL; } #else static inline void* __glutFont( void *font ) { return font; } #endif void GLUTAPIENTRY glutBitmapCharacter( GLUTbitmapFont font, int c ) { const BitmapCharRec *ch; BitmapFontPtr fontinfo; GLint swapbytes, lsbfirst, rowlength; GLint skiprows, skippixels, alignment; fontinfo = (BitmapFontPtr) __glutFont( font ); if (!fontinfo || c < fontinfo->first || c >= fontinfo->first + fontinfo->num_chars) return; ch = fontinfo->ch[c - fontinfo->first]; if (ch) { /* Save current modes. */ glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes); glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst); glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength); glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows); glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels); glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); /* Little endian machines (DEC Alpha for example) could benefit from setting GL_UNPACK_LSB_FIRST to GL_TRUE instead of GL_FALSE, but this would require changing the generated bitmaps too. */ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glBitmap(ch->width, ch->height, ch->xorig, ch->yorig, ch->advance, 0, ch->bitmap); /* Restore saved modes. */ glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes); glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst); glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength); glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows); glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels); glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); } } int GLUTAPIENTRY glutBitmapWidth( GLUTbitmapFont font, int c ) { BitmapFontPtr fontinfo; const BitmapCharRec *ch; fontinfo = (BitmapFontPtr) __glutFont( font ); if (!fontinfo || c < fontinfo->first || c >= fontinfo->first + fontinfo->num_chars) return 0; ch = fontinfo->ch[c - fontinfo->first]; if (ch) return ch->advance; return 0; } int GLUTAPIENTRY glutBitmapLength( GLUTbitmapFont font, const unsigned char *string ) { int c, length; BitmapFontPtr fontinfo; const BitmapCharRec *ch; fontinfo = (BitmapFontPtr) __glutFont( font ); if (!fontinfo) return 0; for (length = 0; *string != '\0'; string++) { c = *string; if (c >= fontinfo->first && c < fontinfo->first + fontinfo->num_chars) { ch = fontinfo->ch[c - fontinfo->first]; if (ch) length += ch->advance; } } return length; } void GLUTAPIENTRY glutStrokeCharacter( GLUTstrokeFont font, int c ) { const StrokeCharRec *ch; const StrokeRec *stroke; const CoordRec *coord; StrokeFontPtr fontinfo; int i, j; fontinfo = (StrokeFontPtr) __glutFont( font ); if (!fontinfo || c < 0 || c >= fontinfo->num_chars) return; ch = &(fontinfo->ch[c]); if (ch) { for (i = ch->num_strokes, stroke = ch->stroke; i > 0; i--, stroke++) { glBegin(GL_LINE_STRIP); for (j = stroke->num_coords, coord = stroke->coord; j > 0; j--, coord++) { glVertex2f(coord->x, coord->y); } glEnd(); } glTranslatef(ch->right, 0.0, 0.0); } } int GLUTAPIENTRY glutStrokeWidth( GLUTstrokeFont font, int c ) { StrokeFontPtr fontinfo; const StrokeCharRec *ch; fontinfo = (StrokeFontPtr) __glutFont( font ); if (!fontinfo || c < 0 || c >= fontinfo->num_chars) return 0; ch = &(fontinfo->ch[c]); if (ch) return ch->right; return 0; } int GLUTAPIENTRY glutStrokeLength( GLUTstrokeFont font, const unsigned char *string ) { int c, length; StrokeFontPtr fontinfo; const StrokeCharRec *ch; fontinfo = (StrokeFontPtr) __glutFont( font ); if (!fontinfo) return 0; for (length = 0; *string != '\0'; string++) { c = *string; if (c >= 0 && c < fontinfo->num_chars) { ch = &(fontinfo->ch[c]); if (ch) length += ch->right; } } return length; }