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: }