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" };
55 get_family(char *style,
59 pointer_dictionary_binding *binding;
63 desc=string_Concat("style.",style);
64 desc=string_Concat2(desc,".substyle.");
65 desc=string_Concat2(desc,substyle);
66 desc=string_Concat2(desc,".fontfamily");
69 family_dict = pointer_dictionary_Create(37);
70 binding = pointer_dictionary_Define(family_dict,desc,&exists);
74 return((string) binding->value);
76 #define STYLE_CLASS "StyleKey.Style1.Style2.Style3.SubstyleKey.Substyle.FontfamilyKey"
77 family=get_string_resource(desc,STYLE_CLASS);
81 pointer_dictionary_Delete(family_dict,binding);
83 binding->value=(pointer) family;
84 return(family); /* If resource returns NULL, return NULL also */
89 get_specific_fontname(char *family,
94 pointer_dictionary_binding *binding;
98 desc = string_Concat("fontfamily.",family);
99 desc = string_Concat2(desc, ".");
100 desc = string_Concat2(desc, size_to_string[size]);
101 desc = string_Concat2(desc, ".");
102 desc = string_Concat2(desc, face_to_string[face]);
105 fontname_dict = pointer_dictionary_Create(37);
106 binding = pointer_dictionary_Define(fontname_dict,desc,&exists);
110 return((string) binding->value);
112 #define FAMILY_CLASS "FontfamilyKey.Fontfamily.Size.Face"
113 fontname=get_string_resource(desc,FAMILY_CLASS);
116 pointer_dictionary_Delete(fontname_dict,binding);
118 binding->value=(pointer) fontname;
119 return(fontname); /* If resource returns NULL, return NULL also */
123 /* fast function to convert Font to hex. Return value
124 * is on the heap and must be freed. I'm cheating in
125 * that I know that Font us really an unsigned long. */
127 static char hexdigits[] = {"0123456789ABCDEF"};
129 Font_to_hex(Font num)
134 temp=(char *) malloc((sizeof(Font)<<1)+2);
136 for (i=0;i<((sizeof(Font)<<1)+1);i++)
137 temp[i] = hexdigits[(num>>(i*4))&0x0f];
144 add_fid(XFontStruct *font)
148 pointer_dictionary_binding *binding;
152 fidst_dict = pointer_dictionary_Create(37);
153 fidstr=Font_to_hex(font->fid);
154 binding = pointer_dictionary_Define(fidst_dict,fidstr,&exists);
158 binding->value=(pointer) font;
161 /* requires that the font already be cached. */
163 get_fontst_from_fid(Font fid)
166 pointer_dictionary_binding *binding;
169 fidstr=Font_to_hex(fid);
171 binding = pointer_dictionary_Define(fidst_dict,fidstr,&exists);
175 return((XFontStruct *) binding->value);
177 printf("Font fid=0x%s not cached. Oops.\n",fidstr);
181 return((XFontStruct *) binding->value);
186 get_fontst(Display *dpy,
189 pointer_dictionary_binding *binding;
194 fontst_dict = pointer_dictionary_Create(37);
195 binding = pointer_dictionary_Define(fontst_dict,fontname,&exists);
198 return((XFontStruct *) binding->value);
200 fontst=XLoadQueryFont(dpy,fontname);
202 pointer_dictionary_Delete(fontst_dict,binding);
204 binding->value=(pointer) fontst;
206 } return(fontst); /* If resource returns NULL, return NULL also */
211 get_fontname(char *family,
217 if (!(fontname=get_specific_fontname(family,size,face)))
218 if (!(fontname=get_specific_fontname(family,size,ROMAN_FACE)))
219 if (!(fontname=get_specific_fontname(family,MEDIUM_SIZE,face)))
220 fontname=get_specific_fontname(family,MEDIUM_SIZE,ROMAN_FACE);
225 complete_get_fontst(Display *dpy,
231 char *family,*fontname;
234 if (family=get_family(style,substyle))
235 if (fontname=get_fontname(family,size,face))
236 if (fontst=get_fontst(dpy,fontname))
238 /* If any part fails, */
243 * XFontStruct *get_font(string style, substyle; int size, face)
244 * Requires: size is one of SMALL_SIZE, MEDIUM_SIZE, LARGE_SIZE and
245 * face is one of ROMAN_FACE, BOLD_FACE, ITALIC_FACE,
251 get_font(Display *dpy,
257 char *family,*fontname;
260 if (size == SPECIAL_SIZE) {
261 /* attempt to process @font explicitly */
262 if (fontst=get_fontst(dpy,substyle))
265 if (family=get_family(style,substyle)) {
266 if (fontname=get_fontname(family,size,face))
267 if (fontst=get_fontst(dpy,fontname))
270 if (fontname=get_fontname(substyle,size,face))
271 if (fontst=get_fontst(dpy,fontname))
275 /* At this point, the no-failure case didn't happen, and the case
276 of substyle being the fontfamily didn't happen, either. */
279 if (!(fontst=complete_get_fontst(dpy,style,"text",size,face)))
280 if (!(fontst=complete_get_fontst(dpy,"default",substyle,size,face)))
281 if (!(fontst=complete_get_fontst(dpy,"default","text",size,face)))
282 if (fontname=get_fontname("default",size,face))
283 fontst=get_fontst(dpy,fontname);
284 if (fontst) return(fontst);
287 /* If all else fails, try fixed */
289 if (fontst=get_fontst(dpy,"fixed")) return(fontst);
291 /* No fonts available. Die. */
293 ERROR("Unable to open font \"fixed\". Aborting...");
301 #endif /* X_DISPLAY_MISSING */