Difference for 2d/font.c from version 1.5 to 1.6


version 1.5 version 1.6
Line 18
 
Line 18
  * 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
  *   *
Line 230
 
Line 233
  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;
  }   }
Line 819
 
Line 825
 }  }
 #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
Line 893
 
Line 900
  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);
Line 915
 
Line 1018
  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++;
Line 944
 
Line 1057
  }   }
   
  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 )
Line 1004
 
Line 1123
  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;
   
Line 1021
 
Line 1144
  }   }
  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 )
Line 1065
 
Line 1191
  }   }
  // 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);
Line 1075
 
Line 1202
  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);
Line 1112
 
Line 1240
 #endif  #endif
  }   }
  return 0;   return 0;
 #endif  
 }  }
   
   
Line 1186
 
Line 1313
 #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 );
  }   }
Line 1288
 
Line 1416
  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;
   

Legend:
line(s) removed in v.1.5 
line(s) changed
 line(s) added in v.1.6