Date: 2013-07-02T14:38:23+00:00

Actual source code: text.c
petsc-3.4.2 2013-07-02

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

      7: #include <../src/sys/classes/draw/impls/x/ximpl.h>

      9: PetscErrorCode PetscDrawXiInitFonts(PetscDraw_X*);
     10: PetscErrorCode PetscDrawXiMatchFontSize(PetscDrawXiFont*,int,int);
     11: PetscErrorCode PetscDrawXiLoadFont(PetscDraw_X*,PetscDrawXiFont*);
     12: /*
     13:     PetscDrawXiFontFixed - Return a pointer to the selected font.

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

     27:   if (!curfont) { PetscDrawXiInitFonts(XBWin);}
     28:   PetscNew(PetscDrawXiFont,&font);
     29:   PetscDrawXiMatchFontSize(font,w,h);
     30:   PetscDrawXiLoadFont(XBWin,font);

     32:   curfont  = font;
     33:   *outfont = curfont;
     34:   return(0);
     35: }

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

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

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

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

     61:   /* The font->descent may not have been set correctly; get it now that
     62:       the font has been loaded */
     63:   FontInfo           = XQueryFont(XBWin->disp,font->fnt);
     64:   font->font_descent = FontInfo->descent;
     65:   font->font_w       = FontInfo->max_bounds.rbearing - FontInfo->min_bounds.lbearing;
     66:   font->font_h       = FontInfo->max_bounds.ascent + FontInfo->max_bounds.descent;

     68:   XFreeFontInfo(0,FontInfo,1);

     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 PetscDrawXiInitFonts(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) XFreeFontInfo(names,info,cnt);

    101:   /* If the above fails,try this: */
    102:   if (!act_nfonts) {
    103:     /* This just gets the most basic fixed-width fonts */
    104:     names = XListFontsWithInfo(XBWin->disp,"?x",NFONTS,&cnt,&info);
    105:     j     = 0;
    106:     for (i=0; i<cnt; i++) {
    108:       size_t         len;

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

    129: PetscErrorCode PetscDrawXiMatchFontSize(PetscDrawXiFont *font,int w,int h)
    130: {
    131:   int i,max,imax,tmp;

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

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

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