/* This file is part of the Project Athena Zephyr Notification System. * It is one of the source files comprising zwgc, the Zephyr WindowGram * client. * * Created by: Marc Horowitz * * $Id$ * * Copyright (c) 1989 by the Massachusetts Institute of Technology. * For copying and distribution information, see the file * "mit-copyright.h". */ #include #if (!defined(lint) && !defined(SABER)) static const char rcsid_X_fonts_c[] = "$Id$"; #endif #include /****************************************************************************/ /* */ /* Code dealing with X fonts: */ /* */ /****************************************************************************/ #ifndef X_DISPLAY_MISSING #include "X_fonts.h" #include "new_memory.h" #include "new_string.h" #include "error.h" #include "pointer_dictionary.h" #include "zwgc.h" /* * font_dict - Lookup cache for fonts (the value pointers are XFontSet's) */ static pointer_dictionary family_dict = NULL; static pointer_dictionary fontname_dict = NULL; static pointer_dictionary fontst_dict = NULL; /* * {face,size}_to_string - lookup tables for converting {face,size} int * constants to ascii strings: */ static string face_to_string[] = { "roman", "bold", "italic", "bolditalic" }; static string size_to_string[] = { "small", "medium", "large" }; static char * get_family(char *style, char *substyle) { char *desc; pointer_dictionary_binding *binding; int exists; char *family; desc=string_Concat("style.",style); desc=string_Concat2(desc,".substyle."); desc=string_Concat2(desc,substyle); desc=string_Concat2(desc,".fontfamily"); if (!family_dict) family_dict = pointer_dictionary_Create(37); binding = pointer_dictionary_Define(family_dict,desc,&exists); if (exists) { free(desc); return((string) binding->value); } else { #define STYLE_CLASS "StyleKey.Style1.Style2.Style3.SubstyleKey.Substyle.FontfamilyKey" family=get_string_resource(desc,STYLE_CLASS); #undef STYLE_CLASS free(desc); if (family==NULL) pointer_dictionary_Delete(family_dict,binding); else binding->value=(pointer) family; return(family); /* If resource returns NULL, return NULL also */ } } static char * get_specific_fontname(char *family, int size, int face) { char *desc; pointer_dictionary_binding *binding; int exists; char *fontname; desc = string_Concat("fontfamily.",family); desc = string_Concat2(desc, "."); desc = string_Concat2(desc, size_to_string[size]); desc = string_Concat2(desc, "."); desc = string_Concat2(desc, face_to_string[face]); if (!fontname_dict) fontname_dict = pointer_dictionary_Create(37); binding = pointer_dictionary_Define(fontname_dict,desc,&exists); if (exists) { free(desc); return((string) binding->value); } else { #define FAMILY_CLASS "FontfamilyKey.Fontfamily.Size.Face" fontname=get_string_resource(desc,FAMILY_CLASS); free(desc); if (fontname==NULL) pointer_dictionary_Delete(fontname_dict,binding); else binding->value=(pointer) fontname; return(fontname); /* If resource returns NULL, return NULL also */ } } static XFontSet get_fontst(Display *dpy, char *fontname) { pointer_dictionary_binding *binding; int exists; XFontSet fontst; char **missing_list; int missing_count; char *def_string; if (!fontst_dict) fontst_dict = pointer_dictionary_Create(37); binding = pointer_dictionary_Define(fontst_dict, fontname, &exists); if (exists) { return((XFontSet)binding->value); } else { fontst = XCreateFontSet(dpy, fontname, &missing_list, &missing_count, &def_string); XFreeStringList(missing_list); if (fontst == NULL) pointer_dictionary_Delete(fontst_dict,binding); else binding->value = (pointer)fontst; return(fontst); /* If resource returns NULL, return NULL also */ } } static char * get_fontname(char *family, int size, int face) { char *fontname; if (!(fontname=get_specific_fontname(family,size,face))) if (!(fontname=get_specific_fontname(family,size,ROMAN_FACE))) if (!(fontname=get_specific_fontname(family,MEDIUM_SIZE,face))) fontname=get_specific_fontname(family,MEDIUM_SIZE,ROMAN_FACE); return(fontname); } static XFontSet complete_get_fontst(Display *dpy, string style, string substyle, int size, int face) { char *family,*fontname; XFontSet fontst; if ((family=get_family(style,substyle))) if ((fontname=get_fontname(family,size,face))) if ((fontst=get_fontst(dpy,fontname))) return(fontst); /* If any part fails, */ return(NULL); } /* * XFontSet get_font(string style, substyle; int size, face) * Requires: size is one of SMALL_SIZE, MEDIUM_SIZE, LARGE_SIZE and * face is one of ROMAN_FACE, BOLD_FACE, ITALIC_FACE, * BOLDITALIC_FACE. * Effects: unknown */ XFontSet get_font(Display *dpy, string style, string substyle, int size, int face) { char *family,*fontname; XFontSet fontst; if (size == SPECIAL_SIZE) { /* attempt to process @font explicitly */ if ((fontst = get_fontst(dpy, substyle))) return(fontst); } else { if ((family = get_family(style, substyle))) { if ((fontname = get_fontname(family, size,face))) if ((fontst = get_fontst(dpy, fontname))) return(fontst); } else { if ((fontname = get_fontname(substyle, size, face))) if ((fontst = get_fontst(dpy, fontname))) return(fontst); } /* At this point, the no-failure case didn't happen, and the case of substyle being the fontfamily didn't happen, either. */ fontst=NULL; if (!(fontst = complete_get_fontst(dpy,style,"text",size,face))) if (!(fontst = complete_get_fontst(dpy,"default",substyle,size,face))) if (!(fontst = complete_get_fontst(dpy,"default","text",size,face))) if ((fontname = get_fontname("default",size,face))) fontst = get_fontst(dpy,fontname); if (fontst) return(fontst); } /* If all else fails, try fixed */ if ((fontst=get_fontst(dpy,"fixed"))) return(fontst); /* No fonts available. Die. */ ERROR("Unable to open font \"fixed\". Aborting..."); #ifdef DEBUG abort(); #else exit(1); #endif } #endif /* X_DISPLAY_MISSING */