Actual source code: text.c

  1: /*$Id: text.c,v 1.42 2001/09/07 20:08:05 bsmith Exp $*/

  3: /*
  4:    This file contains simple code to manage access to fonts, insuring that
  5:    library routines access/load fonts only once
  6:  */

 8:  #include src/sys/src/draw/impls/x/ximpl.h


 11: int XiInitFonts(PetscDraw_X *);
 12: int XiMatchFontSize(XiFont*,int,int);
 13: int XiLoadFont(PetscDraw_X*,XiFont*);
 14: /*
 15:     XiFontFixed - Return a pointer to the selected font.

 17:     Warning: Loads a new font for each window. This should be 
 18:    ok because there will never be many windows and the graphics
 19:    are not intended to be high performance.
 20: */
 21: int XiFontFixed(PetscDraw_X *XBWin,int w,int h,XiFont **outfont)
 22: {
 23:   static XiFont *curfont = 0,*font;
 24:   int           ierr;

 27:   if (!curfont) { XiInitFonts(XBWin);}
 28:   PetscNew(XiFont,&font);
 29:   XiMatchFontSize(font,w,h);
 30:   XiLoadFont(XBWin,font);
 31:   curfont = font;
 32:   *outfont = curfont;
 33:   return(0);
 34: }

 36: /* this is set by XListFonts at startup */
 37: #define NFONTS 20
 38: static struct {
 39:     int w,h,descent;
 40: } nfonts[NFONTS];
 41: static int act_nfonts = 0;

 43: /*
 44:   These routines determine the font to be used based on the requested size,
 45:   and load it if necessary
 46: */

 48: int XiLoadFont(PetscDraw_X *XBWin,XiFont *font)
 49: {
 50:   char        font_name[100];
 51:   XFontStruct *FontInfo;
 52:   XGCValues   values ;

 55:   (void) sprintf(font_name,"%dx%d",font->font_w,font->font_h);
 56:   font->fnt  = XLoadFont(XBWin->disp,font_name);

 58:   /* The font->descent may not have been set correctly; get it now that
 59:       the font has been loaded */
 60:   FontInfo   = XQueryFont(XBWin->disp,font->fnt);
 61:   font->font_descent   = FontInfo->descent;

 63:   /* Storage leak; should probably just free FontInfo? */
 64:   /* XFreeFontInfo(FontInfo); */

 66:   /* Set the current font in the CG */
 67:   values.font = font->fnt ;
 68:   XChangeGC(XBWin->disp,XBWin->gc.set,GCFont,&values) ;
 69:   return(0);
 70: }

 72: /* Code to find fonts and their characteristics */
 73: int XiInitFonts(PetscDraw_X *XBWin)
 74: {
 75:   char         **names;
 76:   int          cnt,i,j;
 77:   XFontStruct  *info;

 80:   /* This just gets the most basic fixed-width fonts */
 81:   names   = XListFontsWithInfo(XBWin->disp,"?x??",NFONTS,&cnt,&info);
 82:   j       = 0;
 83:   for (i=0; i<cnt; i++) {
 84:     names[i][1]         = '0';
 85:     nfonts[j].w         = info[i].max_bounds.width ;
 86:     nfonts[j].h         = info[i].ascent + info[i].descent;
 87:     nfonts[j].descent   = info[i].descent;
 88:     if (nfonts[j].w <= 0 || nfonts[j].h <= 0) continue;
 89:     j++;
 90:     if (j >= NFONTS) break;
 91:   }
 92:   act_nfonts    = j;
 93:   if (cnt > 0)  {
 94:     XFreeFontInfo(names,info,cnt);
 95:   }
 96:   /* If the above fails,try this: */
 97:   if (!act_nfonts) {
 98:     /* This just gets the most basic fixed-width fonts */
 99:     names   = XListFontsWithInfo(XBWin->disp,"?x",NFONTS,&cnt,&info);
100:     j       = 0;
101:     for (i=0; i<cnt; i++) {
102:         int ierr,len;

104:         PetscStrlen(names[i],&len);
105:         if (len != 2) continue;
106:         names[i][1]         = '0';
107:         nfonts[j].w         = info[i].max_bounds.width ;
108:         /* nfonts[j].w         = info[i].max_bounds.lbearing +
109:                                     info[i].max_bounds.rbearing; */
110:         nfonts[j].h         = info[i].ascent + info[i].descent;
111:         nfonts[j].descent   = info[i].descent;
112:         if (nfonts[j].w <= 0 || nfonts[j].h <= 0) continue;
113:         j++;
114:         if (j >= NFONTS) break;
115:     }
116:     act_nfonts    = j;
117:     XFreeFontInfo(names,info,cnt);
118:   }
119:   return(0);
120: }

122: int XiMatchFontSize(XiFont *font,int w,int h)
123: {
124:   int i,max,imax,tmp;

127:   for (i=0; i<act_nfonts; i++) {
128:     if (nfonts[i].w == w && nfonts[i].h == h) {
129:         font->font_w        = w;
130:         font->font_h        = h;
131:         font->font_descent  = nfonts[i].descent;
132:         return(0);
133:     }
134:   }

136:   /* determine closest fit,per max. norm */
137:   imax = 0;
138:   max  = PetscMax(PetscAbsInt(nfonts[0].w - w),PetscAbsInt(nfonts[0].h - h));
139:   for (i=1; i<act_nfonts; i++) {
140:     tmp = PetscMax(PetscAbsInt(nfonts[i].w - w),PetscAbsInt(nfonts[i].h - h));
141:     if (tmp < max) {max = tmp; imax = i;}
142:   }

144:   /* should use font with closest match */
145:   font->font_w        = nfonts[imax].w;
146:   font->font_h        = nfonts[imax].h;
147:   font->font_descent  = nfonts[imax].descent;
148:   return(0);
149: }