]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - zephyr/zwgc/X_fonts.c
93583838831338ebdce6f0a0681f09a7d4837656
[1ts-debian.git] / zephyr / zwgc / X_fonts.c
1 /* This file is part of the Project Athena Zephyr Notification System.
2  * It is one of the source files comprising zwgc, the Zephyr WindowGram
3  * client.
4  *
5  *      Created by:     Marc Horowitz <marc@athena.mit.edu>
6  *
7  *      $Id$
8  *
9  *      Copyright (c) 1989 by the Massachusetts Institute of Technology.
10  *      For copying and distribution information, see the file
11  *      "mit-copyright.h".
12  */
13
14 #include <sysdep.h>
15
16 #if (!defined(lint) && !defined(SABER))
17 static const char rcsid_X_fonts_c[] = "$Id$";
18 #endif
19
20 #include <zephyr/mit-copyright.h>
21
22 /****************************************************************************/
23 /*                                                                          */
24 /*                          Code dealing with X fonts:                      */
25 /*                                                                          */
26 /****************************************************************************/
27
28 #ifndef X_DISPLAY_MISSING
29
30 #include "X_fonts.h"
31 #include "new_memory.h"
32 #include "new_string.h"
33 #include "error.h"
34 #include "pointer_dictionary.h"
35 #include "zwgc.h"
36
37 /*
38  * font_dict - Lookup cache for fonts (the value pointers are XFontStruct *'s)
39  */
40
41 static pointer_dictionary family_dict = NULL;
42 static pointer_dictionary fontname_dict = NULL;
43 static pointer_dictionary fontst_dict = NULL;
44 static pointer_dictionary fidst_dict = NULL;
45
46 /*
47  * {face,size}_to_string - lookup tables for converting {face,size} int
48  *                         constants to ascii strings:
49  */
50
51 static string face_to_string[] = { "roman", "bold", "italic", "bolditalic" };
52 static string size_to_string[] = { "small", "medium", "large" };
53
54 extern char *get_string_resources();
55
56 static char *get_family(style,substyle)
57      char *style;
58      char *substyle;
59 {
60    char *desc;
61    pointer_dictionary_binding *binding;
62    int exists;
63    char *family;
64
65    desc=string_Concat("style.",style);
66    desc=string_Concat2(desc,".substyle.");
67    desc=string_Concat2(desc,substyle);
68    desc=string_Concat2(desc,".fontfamily");
69
70    if (!family_dict)
71       family_dict = pointer_dictionary_Create(37);
72    binding = pointer_dictionary_Define(family_dict,desc,&exists);
73
74    if (exists) {
75       free(desc);
76       return((string) binding->value);
77    } else {
78 #define STYLE_CLASS "StyleKey.Style1.Style2.Style3.SubstyleKey.Substyle.FontfamilyKey"
79       family=get_string_resource(desc,STYLE_CLASS);
80 #undef STYLE_CLASS
81       free(desc);
82       if (family==NULL)
83          pointer_dictionary_Delete(family_dict,binding);
84       else
85          binding->value=(pointer) family;
86       return(family);  /* If resource returns NULL, return NULL also */
87    }
88 }
89
90 static char *get_specific_fontname(family,size,face)
91      char *family;
92      int size;
93      int face;
94 {
95    char *desc;
96    pointer_dictionary_binding *binding;
97    int exists;
98    char *fontname;
99
100    desc = string_Concat("fontfamily.",family);
101    desc = string_Concat2(desc, ".");
102    desc = string_Concat2(desc, size_to_string[size]);
103    desc = string_Concat2(desc, ".");
104    desc = string_Concat2(desc, face_to_string[face]);
105
106    if (!fontname_dict)
107       fontname_dict = pointer_dictionary_Create(37);
108    binding = pointer_dictionary_Define(fontname_dict,desc,&exists);
109
110    if (exists) {
111       free(desc);
112       return((string) binding->value);
113    } else {
114 #define FAMILY_CLASS "FontfamilyKey.Fontfamily.Size.Face"
115       fontname=get_string_resource(desc,FAMILY_CLASS);
116       free(desc);
117       if (fontname==NULL)
118          pointer_dictionary_Delete(fontname_dict,binding);
119       else
120          binding->value=(pointer) fontname;
121       return(fontname);  /* If resource returns NULL, return NULL also */
122    }
123 }
124
125 /* fast function to convert Font to hex.  Return value
126  * is on the heap and must be freed.  I'm cheating in
127  * that I know that Font us really an unsigned long. */
128
129 static char hexdigits[] = {"0123456789ABCDEF"};
130 static char *Font_to_hex(num)
131      Font num;
132 {
133    char *temp;
134    int i;
135
136    temp=(char *) malloc((sizeof(Font)<<1)+2);
137
138    for (i=0;i<((sizeof(Font)<<1)+1);i++)
139       temp[i] = hexdigits[(num>>(i*4))&0x0f];
140    temp[i] = '\0';
141
142    return(temp);
143 }
144
145 void add_fid(font)
146      XFontStruct *font;
147 {
148    
149    char *fidstr;
150    pointer_dictionary_binding *binding;
151    int exists;
152
153    if (!fidst_dict)
154       fidst_dict = pointer_dictionary_Create(37);
155    fidstr=Font_to_hex(font->fid);
156    binding = pointer_dictionary_Define(fidst_dict,fidstr,&exists);
157    free(fidstr);
158
159    if (!exists)
160       binding->value=(pointer) font;
161 }
162
163 /* requires that the font already be cached. */
164 XFontStruct *get_fontst_from_fid(fid)
165      Font fid;
166 {
167    char *fidstr;
168    pointer_dictionary_binding *binding;
169    int exists;
170
171    fidstr=Font_to_hex(fid);
172
173    binding = pointer_dictionary_Define(fidst_dict,fidstr,&exists);
174    free(fidstr);
175 #ifdef DEBUG
176    if (exists) {
177       return((XFontStruct *) binding->value);
178    } else {
179       printf("Font fid=0x%s not cached.  Oops.\n",fidstr);
180       abort();
181    }
182 #else
183    return((XFontStruct *) binding->value);
184 #endif
185 }
186
187 static XFontStruct *get_fontst(dpy,fontname)
188      Display *dpy;
189      char *fontname;
190 {
191    pointer_dictionary_binding *binding;
192    int exists;
193    XFontStruct *fontst;
194
195    if (!fontst_dict)
196       fontst_dict = pointer_dictionary_Create(37);
197    binding = pointer_dictionary_Define(fontst_dict,fontname,&exists);
198
199    if (exists) {
200       return((XFontStruct *) binding->value);
201    } else {
202       fontst=XLoadQueryFont(dpy,fontname);
203       if (fontst==NULL) {
204          pointer_dictionary_Delete(fontst_dict,binding);
205       } else {
206          binding->value=(pointer) fontst;
207          add_fid(fontst);
208       } return(fontst);  /* If resource returns NULL, return NULL also */
209    }
210 }
211
212 static char *get_fontname(family,size,face)
213      char *family;
214      int size;
215      int face;
216 {
217    char *fontname;
218
219    if (!(fontname=get_specific_fontname(family,size,face)))
220     if (!(fontname=get_specific_fontname(family,size,ROMAN_FACE)))
221      if (!(fontname=get_specific_fontname(family,MEDIUM_SIZE,face)))
222       fontname=get_specific_fontname(family,MEDIUM_SIZE,ROMAN_FACE);
223    return(fontname);
224 }
225
226 static XFontStruct *complete_get_fontst(dpy,style,substyle,size,face)
227      Display *dpy;
228      string style;
229      string substyle;
230      int size;
231      int face;
232 {
233    char *family,*fontname;
234    XFontStruct *fontst;
235
236    if (family=get_family(style,substyle))
237      if (fontname=get_fontname(family,size,face))
238        if (fontst=get_fontst(dpy,fontname))
239          return(fontst);
240    /* If any part fails, */
241    return(NULL);
242 }
243
244 /*
245  *    XFontStruct *get_font(string style, substyle; int size, face)
246  *         Requires: size is one of SMALL_SIZE, MEDIUM_SIZE, LARGE_SIZE and
247  *                   face is one of ROMAN_FACE, BOLD_FACE, ITALIC_FACE,
248  *                   BOLDITALIC_FACE.
249  *          Effects: unknown
250  */
251
252 XFontStruct *get_font(dpy,style,substyle,size,face)
253      Display *dpy;
254      string style;
255      string substyle;
256      int size;
257      int face;
258 {
259    char *family,*fontname;
260    XFontStruct *fontst;
261
262    if (size == SPECIAL_SIZE) {
263       /* attempt to process @font explicitly */
264       if (fontst=get_fontst(dpy,substyle))
265         return(fontst);
266    } else {
267       if (family=get_family(style,substyle)) {
268          if (fontname=get_fontname(family,size,face))
269            if (fontst=get_fontst(dpy,fontname))
270              return(fontst);
271       } else {
272          if (fontname=get_fontname(substyle,size,face))
273            if (fontst=get_fontst(dpy,fontname))
274              return(fontst);
275       }
276
277       /* At this point, the no-failure case didn't happen, and the case
278       of substyle being the fontfamily didn't happen, either. */
279
280       fontst=NULL;
281       if (!(fontst=complete_get_fontst(dpy,style,"text",size,face)))
282         if (!(fontst=complete_get_fontst(dpy,"default",substyle,size,face)))
283           if (!(fontst=complete_get_fontst(dpy,"default","text",size,face)))
284             if (fontname=get_fontname("default",size,face))
285               fontst=get_fontst(dpy,fontname);
286       if (fontst) return(fontst);
287    }
288
289    /* If all else fails, try fixed */
290
291    if (fontst=get_fontst(dpy,"fixed")) return(fontst);
292
293    /* No fonts available.  Die. */
294
295    ERROR("Unable to open font \"fixed\".  Aborting...");
296 #ifdef DEBUG
297    abort();
298 #else
299    exit(1);
300 #endif
301 }
302
303 #endif /* X_DISPLAY_MISSING */
304