Actual source code: text.c

      1: #define PETSC_DLL

      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: PetscErrorCode XiInitFonts(PetscDraw_X *);
     12: PetscErrorCode XiMatchFontSize(XiFont*,int,int);
     13: PetscErrorCode 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: */
     23: PetscErrorCode XiFontFixed(PetscDraw_X *XBWin,int w,int h,XiFont **outfont)
     24: {
     25:   static XiFont *curfont = 0,*font;

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

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

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

     52: PetscErrorCode XiLoadFont(PetscDraw_X *XBWin,XiFont *font)
     53: {
     54:   char        font_name[100];
     55:   XFontStruct *FontInfo;
     56:   XGCValues   values ;

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

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

     67:   /* Storage leak; should probably just free FontInfo? */
     68:   /* XFreeFontInfo(FontInfo); */

     70:   /* Set the current font in the CG */
     71:   values.font = font->fnt ;
     72:   XChangeGC(XBWin->disp,XBWin->gc.set,GCFont,&values);
     73:   return(0);
     74: }

     76: /* Code to find fonts and their characteristics */
     79: PetscErrorCode XiInitFonts(PetscDraw_X *XBWin)
     80: {
     81:   char         **names;
     82:   int          cnt,i,j;
     83:   XFontStruct  *info;

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

    111:         PetscStrlen(names[i],&len);
    112:         if (len != 2) continue;
    113:         names[i][1]         = '\0';
    114:         nfonts[j].w         = info[i].max_bounds.width ;
    115:         /* nfonts[j].w         = info[i].max_bounds.lbearing +
    116:                                     info[i].max_bounds.rbearing; */
    117:         nfonts[j].h         = info[i].ascent + info[i].descent;
    118:         nfonts[j].descent   = info[i].descent;
    119:         if (nfonts[j].w <= 0 || nfonts[j].h <= 0) continue;
    120:         j++;
    121:         if (j >= NFONTS) break;
    122:     }
    123:     act_nfonts    = j;
    124:     XFreeFontInfo(names,info,cnt);
    125:   }
    126:   return(0);
    127: }

    131: PetscErrorCode XiMatchFontSize(XiFont *font,int w,int h)
    132: {
    133:   int i,max,imax,tmp;

    136:   for (i=0; i<act_nfonts; i++) {
    137:     if (nfonts[i].w == w && nfonts[i].h == h) {
    138:         font->font_w        = w;
    139:         font->font_h        = h;
    140:         font->font_descent  = nfonts[i].descent;
    141:         return(0);
    142:     }
    143:   }

    145:   /* determine closest fit,per max. norm */
    146:   imax = 0;
    147:   max  = PetscMax(PetscAbsInt(nfonts[0].w - w),PetscAbsInt(nfonts[0].h - h));
    148:   for (i=1; i<act_nfonts; i++) {
    149:     tmp = PetscMax(PetscAbsInt(nfonts[i].w - w),PetscAbsInt(nfonts[i].h - h));
    150:     if (tmp < max) {max = tmp; imax = i;}
    151:   }

    153:   /* should use font with closest match */
    154:   font->font_w        = nfonts[imax].w;
    155:   font->font_h        = nfonts[imax].h;
    156:   font->font_descent  = nfonts[imax].descent;
    157:   return(0);
    158: }