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
5 * Created by: Marc Horowitz <marc@athena.mit.edu>
9 * Copyright (c) 1989 by the Massachusetts Institute of Technology.
10 * For copying and distribution information, see the file
16 #if (!defined(lint) && !defined(SABER))
17 static const char rcsid_X_fonts_c[] = "$Id$";
20 #include <zephyr/mit-copyright.h>
22 /****************************************************************************/
24 /* Code dealing with X fonts: */
26 /****************************************************************************/
28 #ifndef X_DISPLAY_MISSING
31 #include "new_memory.h"
32 #include "new_string.h"
34 #include "pointer_dictionary.h"
38 * font_dict - Lookup cache for fonts (the value pointers are XFontStruct *'s)
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;
47 * {face,size}_to_string - lookup tables for converting {face,size} int
48 * constants to ascii strings:
51 static string face_to_string[] = { "roman", "bold", "italic", "bolditalic" };
52 static string size_to_string[] = { "small", "medium", "large" };
54 extern char *get_string_resources();
56 static char *get_family(style,substyle)
61 pointer_dictionary_binding *binding;
65 desc=string_Concat("style.",style);
66 desc=string_Concat2(desc,".substyle.");
67 desc=string_Concat2(desc,substyle);
68 desc=string_Concat2(desc,".fontfamily");
71 family_dict = pointer_dictionary_Create(37);
72 binding = pointer_dictionary_Define(family_dict,desc,&exists);
76 return((string) binding->value);
78 #define STYLE_CLASS "StyleKey.Style1.Style2.Style3.SubstyleKey.Substyle.FontfamilyKey"
79 family=get_string_resource(desc,STYLE_CLASS);
83 pointer_dictionary_Delete(family_dict,binding);
85 binding->value=(pointer) family;
86 return(family); /* If resource returns NULL, return NULL also */
90 static char *get_specific_fontname(family,size,face)
96 pointer_dictionary_binding *binding;
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]);
107 fontname_dict = pointer_dictionary_Create(37);
108 binding = pointer_dictionary_Define(fontname_dict,desc,&exists);
112 return((string) binding->value);
114 #define FAMILY_CLASS "FontfamilyKey.Fontfamily.Size.Face"
115 fontname=get_string_resource(desc,FAMILY_CLASS);
118 pointer_dictionary_Delete(fontname_dict,binding);
120 binding->value=(pointer) fontname;
121 return(fontname); /* If resource returns NULL, return NULL also */
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. */
129 static char hexdigits[] = {"0123456789ABCDEF"};
130 static char *Font_to_hex(num)
136 temp=(char *) malloc((sizeof(Font)<<1)+2);
138 for (i=0;i<((sizeof(Font)<<1)+1);i++)
139 temp[i] = hexdigits[(num>>(i*4))&0x0f];
150 pointer_dictionary_binding *binding;
154 fidst_dict = pointer_dictionary_Create(37);
155 fidstr=Font_to_hex(font->fid);
156 binding = pointer_dictionary_Define(fidst_dict,fidstr,&exists);
160 binding->value=(pointer) font;
163 /* requires that the font already be cached. */
164 XFontStruct *get_fontst_from_fid(fid)
168 pointer_dictionary_binding *binding;
171 fidstr=Font_to_hex(fid);
173 binding = pointer_dictionary_Define(fidst_dict,fidstr,&exists);
177 return((XFontStruct *) binding->value);
179 printf("Font fid=0x%s not cached. Oops.\n",fidstr);
183 return((XFontStruct *) binding->value);
187 static XFontStruct *get_fontst(dpy,fontname)
191 pointer_dictionary_binding *binding;
196 fontst_dict = pointer_dictionary_Create(37);
197 binding = pointer_dictionary_Define(fontst_dict,fontname,&exists);
200 return((XFontStruct *) binding->value);
202 fontst=XLoadQueryFont(dpy,fontname);
204 pointer_dictionary_Delete(fontst_dict,binding);
206 binding->value=(pointer) fontst;
208 } return(fontst); /* If resource returns NULL, return NULL also */
212 static char *get_fontname(family,size,face)
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);
226 static XFontStruct *complete_get_fontst(dpy,style,substyle,size,face)
233 char *family,*fontname;
236 if (family=get_family(style,substyle))
237 if (fontname=get_fontname(family,size,face))
238 if (fontst=get_fontst(dpy,fontname))
240 /* If any part fails, */
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,
252 XFontStruct *get_font(dpy,style,substyle,size,face)
259 char *family,*fontname;
262 if (size == SPECIAL_SIZE) {
263 /* attempt to process @font explicitly */
264 if (fontst=get_fontst(dpy,substyle))
267 if (family=get_family(style,substyle)) {
268 if (fontname=get_fontname(family,size,face))
269 if (fontst=get_fontst(dpy,fontname))
272 if (fontname=get_fontname(substyle,size,face))
273 if (fontst=get_fontst(dpy,fontname))
277 /* At this point, the no-failure case didn't happen, and the case
278 of substyle being the fontfamily didn't happen, either. */
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);
289 /* If all else fails, try fixed */
291 if (fontst=get_fontst(dpy,"fixed")) return(fontst);
293 /* No fonts available. Die. */
295 ERROR("Unable to open font \"fixed\". Aborting...");
303 #endif /* X_DISPLAY_MISSING */