version 1.5 | | version 1.6 |
---|
| | |
* Graphical routines for drawing fonts. | | * Graphical routines for drawing fonts. |
* | | * |
* $Log$ | | * $Log$ |
| | * Revision 1.6 1999/10/07 21:19:00 donut |
| | * new ogl font handling, single texture for entire font |
| | * |
* Revision 1.5 1999/09/30 23:02:26 donut | | * Revision 1.5 1999/09/30 23:02:26 donut |
* opengl direct support for ingame and normal menus, fonts as textures, and automap support | | * opengl direct support for ingame and normal menus, fonts as textures, and automap support |
* | | * |
| | |
int w,w2,s2; | | int w,w2,s2; |
| | |
for (w=0;*s!=0 && *s!='\n';s++) { | | for (w=0;*s!=0 && *s!='\n';s++) { |
if (*s<=0x06) | | if (*s<=0x06) { |
| | if (*s<=0x03) |
| | s++; |
continue;//skip color codes. | | continue;//skip color codes. |
| | } |
get_char_width(s[0],s[1],&w2,&s2); | | get_char_width(s[0],s[1],&w2,&s2); |
w += s2; | | w += s2; |
} | | } |
| | |
} | | } |
#endif | | #endif |
| | |
| | #ifndef OGL |
//a bitmap for the character | | //a bitmap for the character |
grs_bitmap char_bm = { | | grs_bitmap char_bm = { |
0,0,0,0, //x,y,w,h | | 0,0,0,0, //x,y,w,h |
| | |
return 0; | | return 0; |
} | | } |
| | |
#ifdef OGL | | #else //OGL |
#include "../main/inferno.h" | | #include "../main/inferno.h" |
#include "ogl_init.h" | | #include "ogl_init.h" |
//font handling routines for OpenGL - Added 9/25/99 Matthew Mueller - they are here instead of in arch/ogl because they use all these defines | | //font handling routines for OpenGL - Added 9/25/99 Matthew Mueller - they are here instead of in arch/ogl because they use all these defines |
| | |
| | int pow2ize(int x);//from ogl.c |
| | |
| | int get_font_total_width(grs_font * font){ |
| | if (font->ft_flags & FT_PROPORTIONAL){ |
| | int i,w=0,c=font->ft_minchar; |
| | for (i=0;c<=font->ft_maxchar;i++,c++){ |
| | if (font->ft_widths[i]<0) |
| | Error("heh?\n"); |
| | w+=font->ft_widths[i]; |
| | } |
| | return w; |
| | }else{ |
| | return font->ft_w*(font->ft_maxchar-font->ft_minchar+1); |
| | } |
| | } |
| | void ogl_font_choose_size(grs_font * font,int gap,int *rw,int *rh){ |
| | int nchars = font->ft_maxchar-font->ft_minchar+1; |
| | int r,x,y,nc=0,smallest=999999,smallr=-1,tries; |
| | int smallprop=10000; |
| | int h,w; |
| | for (h=32;h<=256;h*=2){ |
| | // h=pow2ize(font->ft_h*rows+gap*(rows-1)); |
| | if (font->ft_h>h)continue; |
| | r=(h/(font->ft_h+gap)); |
| | w=pow2ize((get_font_total_width(font)+(nchars-r)*gap)/r); |
| | tries=0; |
| | do { |
| | if (tries) |
| | w=pow2ize(w+1); |
| | if(tries>3){ |
| | mprintf((0,"failed to fit (%ix%i, %ic)\n",w,h,nc)); |
| | break; |
| | } |
| | nc=0; |
| | y=0; |
| | while(y+font->ft_h<=h){ |
| | x=0; |
| | while (x<w){ |
| | if (nc==nchars) |
| | break; |
| | if (font->ft_flags & FT_PROPORTIONAL){ |
| | if (x+font->ft_widths[nc]+gap>w)break; |
| | x+=font->ft_widths[nc++]+gap; |
| | }else{ |
| | if (x+font->ft_w+gap>w)break; |
| | x+=font->ft_w+gap; |
| | nc++; |
| | } |
| | } |
| | if (nc==nchars) |
| | break; |
| | y+=font->ft_h+gap; |
| | } |
| | |
| | tries++; |
| | }while(nc!=nchars); |
| | if (nc!=nchars) |
| | continue; |
| | mprintf((0,"fit: %ix%i %i tries\n",w,h,tries)); |
| | |
| | if (w*h==smallest){//this gives squarer sizes priority (ie, 128x128 would be better than 512*32) |
| | if (w>=h){ |
| | if (w/h<smallprop){ |
| | smallprop=w/h; |
| | smallest++;//hack |
| | } |
| | }else{ |
| | if (h/w<smallprop){ |
| | smallprop=h/w; |
| | smallest++;//hack |
| | } |
| | } |
| | } |
| | if (w*h<smallest){ |
| | smallr=1; |
| | smallest=w*h; |
| | *rw=w; |
| | *rh=h; |
| | } |
| | } |
| | if (smallr<=0) |
| | Error("couldn't fit font?\n"); |
| | mprintf((0,"using %ix%i\n",*rw,*rh)); |
| | |
| | } |
| | |
void ogl_init_font(grs_font * font){ | | void ogl_init_font(grs_font * font){ |
int nchars = font->ft_maxchar-font->ft_minchar+1; | | int nchars = font->ft_maxchar-font->ft_minchar+1; |
int i,w,h; | | int i,w,h,tw,th,x,y,curx=0,cury=0; |
char *fp; | | char *fp; |
// char data[32*32*4]; | | // char data[32*32*4]; |
char *data; | | char *data; |
| | int gap=1; |
// char s[2]; | | // char s[2]; |
| | ogl_font_choose_size(font,gap,&tw,&th); |
| | data=malloc(tw*th); |
| | gr_init_bitmap(&font->ft_parent_bitmap,BM_LINEAR,0,0,tw,th,tw,data); |
| | |
| | font->ft_parent_bitmap.gltexture=ogl_get_free_texture(); |
| | |
font->ft_bitmaps=(grs_bitmap*)malloc( nchars * sizeof(grs_bitmap)); | | font->ft_bitmaps=(grs_bitmap*)malloc( nchars * sizeof(grs_bitmap)); |
mprintf((0,"ogl_init_font %s, %s, nchars=%i\n",(font->ft_flags & FT_PROPORTIONAL)?"proportional":"fixedwidth",(font->ft_flags & FT_COLOR)?"color":"mono",nchars)); | | mprintf((0,"ogl_init_font %s, %s, nchars=%i, (%ix%i tex)\n",(font->ft_flags & FT_PROPORTIONAL)?"proportional":"fixedwidth",(font->ft_flags & FT_COLOR)?"color":"mono",nchars,tw,th)); |
// s[1]=0; | | // s[1]=0; |
h=font->ft_h; | | h=font->ft_h; |
| | // sleep(5); |
| | |
for(i=0;i<nchars;i++){ | | for(i=0;i<nchars;i++){ |
// s[0]=font->ft_minchar+i; | | // s[0]=font->ft_minchar+i; |
// gr_get_string_size(s,&w,&h,&aw); | | // gr_get_string_size(s,&w,&h,&aw); |
| | |
w=font->ft_widths[i]; | | w=font->ft_widths[i]; |
else | | else |
w=font->ft_w; | | w=font->ft_w; |
mprintf((0,"char %i(%ix%i): ",i,w,h)); | | // mprintf((0,"char %i(%ix%i): ",i,w,h)); |
if (w<1 || w>256){ | | if (w<1 || w>256){ |
mprintf((0,"grr\n"));continue; | | mprintf((0,"grr\n"));continue; |
} | | } |
| | if (curx+w+gap>tw){ |
| | cury+=h+gap; |
| | curx=0; |
| | } |
| | if (cury+h>th) |
| | Error("font doesn't really fit (%i/%i)?\n",i,nchars); |
if (font->ft_flags & FT_COLOR) { | | if (font->ft_flags & FT_COLOR) { |
if (font->ft_flags & FT_PROPORTIONAL) | | if (font->ft_flags & FT_PROPORTIONAL) |
fp = font->ft_chars[i]; | | fp = font->ft_chars[i]; |
else | | else |
fp = font->ft_data + i * w*h; | | fp = font->ft_data + i * w*h; |
| | for (y=0;y<h;y++) |
| | for (x=0;x<w;x++){ |
| | font->ft_parent_bitmap.bm_data[curx+x+(cury+y)*tw]=fp[x+y*w]; |
| | } |
| | |
// gr_init_bitmap(&font->ft_bitmaps[i],BM_LINEAR,0,0,w,h,w,font->); | | // gr_init_bitmap(&font->ft_bitmaps[i],BM_LINEAR,0,0,w,h,w,font->); |
}else{ | | }else{ |
int j,k,BitMask,bits=0,dofs=0,white=gr_find_closest_color(63,63,63); | | int BitMask,bits=0,white=gr_find_closest_color(63,63,63); |
// if (w*h>sizeof(data)) | | // if (w*h>sizeof(data)) |
// Error("ogl_init_font: toobig\n"); | | // Error("ogl_init_font: toobig\n"); |
data=malloc(w*h); | | |
if (font->ft_flags & FT_PROPORTIONAL) | | if (font->ft_flags & FT_PROPORTIONAL) |
fp = font->ft_chars[i]; | | fp = font->ft_chars[i]; |
else | | else |
fp = font->ft_data + i * BITS_TO_BYTES(w)*h; | | fp = font->ft_data + i * BITS_TO_BYTES(w)*h; |
for (k=0;k<h;k++){ | | for (y=0;y<h;y++){ |
BitMask=0; | | BitMask=0; |
for (j=0; j< w; j++ ) | | for (x=0; x< w; x++ ) |
{ | | { |
if (BitMask==0) { | | if (BitMask==0) { |
bits = *fp++; | | bits = *fp++; |
| | |
} | | } |
| | |
if (bits & BitMask) | | if (bits & BitMask) |
data[dofs++] = white; | | font->ft_parent_bitmap.bm_data[curx+x+(cury+y)*tw]=white; |
else | | else |
data[dofs++] = 255; | | font->ft_parent_bitmap.bm_data[curx+x+(cury+y)*tw]=255; |
BitMask >>= 1; | | BitMask >>= 1; |
} | | } |
} | | } |
fp=data; | | |
} | | } |
gr_init_bitmap(&font->ft_bitmaps[i],BM_LINEAR,0,0,w,h,w,fp); | | gr_init_sub_bitmap(&font->ft_bitmaps[i],&font->ft_parent_bitmap,curx,cury,w,h); |
ogl_loadbmtexture_m(&font->ft_bitmaps[i],0); | | |
// font->ft_bitmaps[i].bm_data=NULL;//no longer needed. | | curx+=w+gap; |
| | } |
| | if (!(font->ft_flags & FT_COLOR)) { |
| | //use GL_INTENSITY instead of GL_RGB |
| | font->ft_parent_bitmap.gltexture->handle=-2; |
| | font->ft_parent_bitmap.gltexture->internalformat=GL_LUMINANCE4_ALPHA4; |
| | font->ft_parent_bitmap.gltexture->format=GL_LUMINANCE_ALPHA; |
} | | } |
| | ogl_loadbmtexture_m(&font->ft_parent_bitmap,0); |
} | | } |
| | |
int ogl_internal_string(int x, int y, char *s ) | | int ogl_internal_string(int x, int y, char *s ) |
| | |
continue; | | continue; |
} | | } |
| | |
| | // ogl_ubitblt(FONT->ft_bitmaps[letter].bm_w,FONT->ft_bitmaps[letter].bm_h,xx,yy,0,0,&FONT->ft_bitmaps[letter],NULL); |
| | // if (*text_ptr>='0' && *text_ptr<='9'){ |
if (FFLAGS&FT_COLOR) | | if (FFLAGS&FT_COLOR) |
gr_ubitmapm(xx,yy,&FONT->ft_bitmaps[letter]); | | gr_ubitmapm(xx,yy,&FONT->ft_bitmaps[letter]); |
else{ | | else{ |
if (grd_curcanv->cv_bitmap.bm_type==BM_OGL) | | if (grd_curcanv->cv_bitmap.bm_type==BM_OGL) |
ogl_ubitmapm_c(xx,yy,&FONT->ft_bitmaps[letter],FG_COLOR); | | ogl_ubitmapm_c(xx,yy,&FONT->ft_bitmaps[letter],FG_COLOR); |
else | | else |
gr_ubitmapm(xx,yy,&FONT->ft_bitmaps[letter]);//ignores color.. | | Error("ogl_internal_string: non-color string to non-ogl dest\n"); |
| | // gr_ubitmapm(xx,yy,&FONT->ft_bitmaps[letter]);//ignores color.. |
} | | } |
| | //} |
| | |
xx += spacing; | | xx += spacing; |
| | |
| | |
} | | } |
return 0; | | return 0; |
} | | } |
| | int gr_internal_color_string(int x, int y, char *s ){ |
| | return ogl_internal_string(x,y,s); |
| | } |
#endif //OGL | | #endif //OGL |
| | |
int gr_string(int x, int y, char *s ) | | int gr_string(int x, int y, char *s ) |
| | |
} | | } |
// Partially clipped... | | // Partially clipped... |
#ifdef OGL | | #ifdef OGL |
| | if (TYPE==BM_OGL) |
return ogl_internal_string(x,y,s); | | return ogl_internal_string(x,y,s); |
#else | | #endif |
| | |
if (FFLAGS & FT_COLOR) | | if (FFLAGS & FT_COLOR) |
return gr_internal_color_string( x, y, s); | | return gr_internal_color_string( x, y, s); |
| | |
return gr_internal_string_clipped_m( x, y, s ); | | return gr_internal_string_clipped_m( x, y, s ); |
| | |
return gr_internal_string_clipped( x, y, s ); | | return gr_internal_string_clipped( x, y, s ); |
#endif | | |
} | | } |
| | |
int gr_ustring(int x, int y, char *s ) | | int gr_ustring(int x, int y, char *s ) |
{ | | { |
#ifdef OGL | | #ifdef OGL |
| | if (TYPE==BM_OGL) |
return ogl_internal_string(x,y,s); | | return ogl_internal_string(x,y,s); |
#else | | #endif |
| | |
if (FFLAGS & FT_COLOR) { | | if (FFLAGS & FT_COLOR) { |
| | |
return gr_internal_color_string(x,y,s); | | return gr_internal_color_string(x,y,s); |
| | |
#endif | | #endif |
} | | } |
return 0; | | return 0; |
#endif | | |
} | | } |
| | |
| | |
| | |
#ifdef OGL | | #ifdef OGL |
if (font->ft_bitmaps) | | if (font->ft_bitmaps) |
free( font->ft_bitmaps ); | | free( font->ft_bitmaps ); |
| | ogl_freebmtexture(&font->ft_parent_bitmap); |
#endif | | #endif |
free( font ); | | free( font ); |
} | | } |
| | |
memcpy(newfont,font,(ubyte*)&newfont->oldfont-(ubyte*)newfont);//fill in newfont data from oldfont struct | | memcpy(newfont,font,(ubyte*)&newfont->oldfont-(ubyte*)newfont);//fill in newfont data from oldfont struct |
mprintf((0,"%i %i %i\n",sizeof(grs_font),sizeof(old_grs_font),(ubyte*)&newfont->oldfont-(ubyte*)newfont)); | | mprintf((0,"%i %i %i\n",sizeof(grs_font),sizeof(old_grs_font),(ubyte*)&newfont->oldfont-(ubyte*)newfont)); |
| | |
#ifdef OGL | | |
ogl_init_font(newfont); | | |
#endif | | |
| | |
//set curcanv vars | | //set curcanv vars |
| | |
FONT = newfont; | | FONT = newfont; |
FG_COLOR = 0; | | FG_COLOR = 0; |
BG_COLOR = 0; | | BG_COLOR = 0; |
| | |
| | #ifdef OGL |
| | ogl_init_font(newfont); |
| | #endif |
| | |
return newfont; | | return newfont; |
| | |