diff options
author | Marc Horowitz <marc@mit.edu> | 1989-11-01 20:02:01 +0000 |
---|---|---|
committer | Marc Horowitz <marc@mit.edu> | 1989-11-01 20:02:01 +0000 |
commit | d13d8a046838ce3d0e2643bb5b49f2ff77d679ca (patch) | |
tree | 05737bc11e3461836ce817939b9129ed58545ac7 /zwgc/X_fonts.c | |
parent | fd994e4099ad66fb3bf26cd636ca5d5cae72da68 (diff) |
Initial revision
Diffstat (limited to 'zwgc/X_fonts.c')
-rw-r--r-- | zwgc/X_fonts.c | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/zwgc/X_fonts.c b/zwgc/X_fonts.c new file mode 100644 index 0000000..501c674 --- /dev/null +++ b/zwgc/X_fonts.c @@ -0,0 +1,278 @@ +/****************************************************************************/ +/* */ +/* Code dealing with X fonts: */ +/* */ +/****************************************************************************/ + +#include <stdio.h> +#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 XFontStruct *'s) + */ + +static pointer_dictionary family_dict = NULL; +static pointer_dictionary fontname_dict = NULL; +static pointer_dictionary fontst_dict = NULL; +static pointer_dictionary fidst_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" }; + +extern char *get_string_resources(); + +static char *get_family(style,substyle) + char *style; + char *substyle; +{ + char *desc; + pointer_dictionary_binding *binding; + int exists; + char *family; + + desc=string_Concat("style.",style); + desc=string_Concat2(desc,".fontfamily."); + desc=string_Concat2(desc,substyle); + + 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 "Style.Style1.Style2.Style3.Fontfamily.Substyle" + 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(family,size,face) + 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 "Fontfamily.FontfamilyName.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 */ + } +} + +/* fast function to convert Font to hex. Return value + * is on the heap and must be freed. I'm cheating in + * that I know that Font us really an unsigned long. */ + +static char hexdigits[] = {"0123456789ABCDEF"}; +static char *Font_to_hex(num) + Font num; +{ + char *temp; + int i; + + temp=(char *) malloc((sizeof(Font)<<1)+1); + + for (i=0;i<((sizeof(Font)<<1)+1);i++) + temp[i] = hexdigits[(num>>(i*4))&0x0f]; + temp[i] = '\0'; + + return(temp); +} + +void add_fid(font) + XFontStruct *font; +{ + + char *fidstr; + pointer_dictionary_binding *binding; + int exists; + + if (!fidst_dict) + fidst_dict = pointer_dictionary_Create(37); + fidstr=Font_to_hex(font->fid); + binding = pointer_dictionary_Define(fidst_dict,fidstr,&exists); + free(fidstr); + + if (!exists) + binding->value=(pointer) font; +} + +/* requires that the font already be cached. */ +XFontStruct *get_fontst_from_fid(fid) + Font fid; +{ + char *fidstr; + pointer_dictionary_binding *binding; + int exists; + + fidstr=Font_to_hex(fid); + + binding = pointer_dictionary_Define(fidst_dict,fidstr,&exists); + free(fidstr); +#ifdef DEBUG + if (exists) { + return((XFontStruct *) binding->value); + } else { + printf("Font fid=0x%s not cached. Oops.\n",fidstr); + abort(); + } +#else + return((XFontStruct *) binding->value); +#endif +} + +static XFontStruct *get_fontst(dpy,fontname) + Display *dpy; + char *fontname; +{ + pointer_dictionary_binding *binding; + int exists; + XFontStruct *fontst; + + if (!fontst_dict) + fontst_dict = pointer_dictionary_Create(37); + binding = pointer_dictionary_Define(fontst_dict,fontname,&exists); + + if (exists) { + return((XFontStruct *) binding->value); + } else { + fontst=XLoadQueryFont(dpy,fontname); + if (fontst==NULL) { + pointer_dictionary_Delete(fontst_dict,binding); + } else { + binding->value=(pointer) fontst; + add_fid(fontst); + } return(fontst); /* If resource returns NULL, return NULL also */ + } +} + +static char *get_fontname(family,size,face) + 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 XFontStruct *complete_get_fontst(dpy,style,substyle,size,face) + Display *dpy; + string style; + string substyle; + int size; + int face; +{ + char *family,*fontname; + XFontStruct *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); +} + +/* + * XFontStruct *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 + */ + +XFontStruct *get_font(dpy,style,substyle,size,face) + Display *dpy; + string style; + string substyle; + int size; + int face; +{ + char *family,*fontname; + XFontStruct *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 +} |