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