Actual source code: xtext.c

petsc-3.7.3 2016-08-01
Report Typos and Errors
  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: static PetscErrorCode PetscDrawXiInitFonts(PetscDraw_X*);
 10: static PetscErrorCode PetscDrawXiLoadFont(PetscDraw_X*,PetscDrawXiFont*);
 11: static PetscErrorCode PetscDrawXiMatchFontSize(PetscDrawXiFont*,int,int);

 13: /*
 14:     PetscDrawXiFontFixed - Return a pointer to the selected font.

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

 28:   if (!curfont) { PetscDrawXiInitFonts(XBWin);}
 29:   PetscNew(&font);
 30:   PetscDrawXiMatchFontSize(font,w,h);
 31:   PetscDrawXiLoadFont(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: static PetscErrorCode PetscDrawXiLoadFont(PetscDraw_X *XBWin,PetscDrawXiFont *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;
 66:   font->font_w       = FontInfo->max_bounds.rbearing - FontInfo->min_bounds.lbearing;
 67:   font->font_h       = FontInfo->max_bounds.ascent + FontInfo->max_bounds.descent;

 69:   XFreeFontInfo(0,FontInfo,1);

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

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

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

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 + info[i].max_bounds.rbearing; */
116:       nfonts[j].h       = info[i].ascent + info[i].descent;
117:       nfonts[j].descent = info[i].descent;
118:       if (nfonts[j].w <= 0 || nfonts[j].h <= 0) continue;
119:       j++;
120:       if (j >= NFONTS) break;
121:     }
122:     act_nfonts = j;
123:     XFreeFontInfo(names,info,cnt);
124:   }
125:   return(0);
126: }

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

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

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

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