Mercurial > kinput2.yaz
diff lib/cachedfont.c @ 0:92745d501b9a
initial import from kinput2-v3.1
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 08 Mar 2010 04:44:30 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/cachedfont.c Mon Mar 08 04:44:30 2010 +0900 @@ -0,0 +1,271 @@ +#ifndef lint +static char *rcsid = "$Id: cachedfont.c,v 1.13 1994/05/17 10:51:54 ishisone Rel $"; +#endif +/* + * Copyright (c) 1991 Software Research Associates, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Software Research Associates not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Software Research + * Associates makes no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + * + * Author: Makoto Ishisone, Software Research Associates, Inc., Japan + */ + +#include <X11/Intrinsic.h> +#include <X11/Xatom.h> +#include <X11/Xmu/CharSet.h> +#include "CachedAtom.h" +#include "CachedFont.h" +#include "AsyncErr.h" + +#define DEBUG_VAR debug_cachedfont +#include "DebugPrint.h" + +typedef struct _fontrec_ { + Display *dpy; + String *names; /* full name or aliases... (in lower case) */ + Cardinal num_names; + Atom fontprop; /* 'FONT' property value */ + XFontStruct *font; + int refcnt; + struct _fontrec_ *next; +} FontRec; + +static FontRec *FRP = NULL; + +static FontRec * +LookupByAtom(dpy, atom) +Display *dpy; +Atom atom; +{ + register FontRec *frp; + + for (frp = FRP; frp != NULL; frp = frp->next) { + if (frp->dpy == dpy && frp->fontprop == atom) return frp; + } + return NULL; +} + +static FontRec * +LookupByName(dpy, name) +Display *dpy; +String name; +{ + register FontRec *frp; + register String *names; + register Cardinal i; + + for (frp = FRP; frp != NULL; frp = frp->next) { + if (frp->dpy != dpy) continue; + + for (i = frp->num_names, names = frp->names; i > 0; i--, names++) { + if (!strcmp(*names, name)) return frp; + } + } + return NULL; +} + +static void +AddName(frp, name) +register FontRec *frp; +String name; +{ + String dup = XtNewString(name); + + if (frp->num_names++ == 0) { + frp->names = (String *)XtMalloc(sizeof(String)); + } else { + frp->names = (String *)XtRealloc((char *)frp->names, + sizeof(String) * frp->num_names); + } + frp->names[frp->num_names - 1] = dup; +} + +static void +LoadFont(frp) +register FontRec *frp; +{ + if (frp->font->fid == None) { + frp->font->fid = XLoadFont(frp->dpy, frp->names[0]); + frp->refcnt = 0; /* reset */ + } +} + +static XFontStruct * +AddFont(dpy, name) +Display *dpy; +char *name; +{ + FontRec *frp; + XFontStruct *font; + Atom fontprop; + + font = XLoadQueryFont(dpy, name); + if (font == NULL) return NULL; + + if (!XGetFontProperty(font, XA_FONT, (unsigned long *)&fontprop)) { + /* well, make it by myself */ + DPRINT(("AddFont(): %s doesn't have FONT property\n", name)); + fontprop = CachedInternAtom(dpy, name, False); + } + + if ((frp = LookupByAtom(dpy, fontprop)) != NULL) { + /* already loaded. use it */ + TRACE(("\tfound in the cache (alias name?)\n")); + AddName(frp, name); + frp->refcnt++; + if (frp->font->fid == None) { + frp->font->fid = font->fid; + XFreeFontInfo((char **)NULL, font, 1); + } else { + XFreeFont(dpy, font); + } + return frp->font; + } + + TRACE(("\tnot found in the cache\n")); + frp = XtNew(FontRec); + frp->dpy = dpy; + frp->num_names = 0; + AddName(frp, name); + frp->fontprop = fontprop; + frp->font = font; + frp->refcnt = 1; + frp->next = FRP; + FRP = frp; + + return frp->font; +} + + +/* + * Public functions + */ + +XFontStruct * +CachedLoadQueryFontByName(dpy, name) +Display *dpy; +String name; +{ + FontRec *frp; + XFontStruct *font; + char buf[256]; + char *loweredname = buf; + int len = strlen(name) + 1; + + if (len > sizeof(buf)) loweredname = XtMalloc(len); + + XmuCopyISOLatin1Lowered(loweredname, name); + + TRACE(("CachedLoadQueryFontByName(name=%s)\n", name)); + if ((frp = LookupByName(dpy, loweredname)) != NULL) { + TRACE(("\tfound in the cache\n")); + LoadFont(frp); + frp->refcnt++; + if (loweredname != buf) XtFree(loweredname); + return frp->font; + } + + font = AddFont(dpy, loweredname); + if (loweredname != buf) XtFree(loweredname); + return font; +} + +XFontStruct * +CachedLoadQueryFontByProp(dpy, atom) +Display *dpy; +Atom atom; +{ + FontRec *frp; + XFontStruct *font; + String name; + XAEHandle h; + + TRACE(("CachedLoadQueryFontByProp(atom=%ld)\n", atom)); + if ((frp = LookupByAtom(dpy, atom)) != NULL) { + TRACE(("\tfound in the cache\n")); + LoadFont(frp); + frp->refcnt++; + return frp->font; + } + + /* get fontname */ + /* make it safe... */ + h = XAESetIgnoreErrors(dpy); + name = CachedGetAtomName(dpy, atom); + XAEUnset(h); + + TRACE(("\tnot found. got font name: %s\n", name ? name : "<null>")); + + if (name == NULL) { + font = NULL; + } else { + char buf[256]; + char *loweredname = buf; + int len = strlen(name) + 1; + + if (len > sizeof(buf)) loweredname = XtMalloc(len); + XmuCopyISOLatin1Lowered(loweredname, name); + font = AddFont(dpy, loweredname); + if (loweredname != buf) XtFree(loweredname); + } + return font; +} + +/* ARGSUSED */ +XFontStruct * +CachedLoadFontByFontStruct(dpy, font) +Display *dpy; +XFontStruct *font; +{ + register FontRec *frp; + + TRACE(("CachedLoadFontByFontStruct(fid=%08lx)\n", font->fid)); + for (frp = FRP; frp != NULL; frp = frp->next) { + if (frp->font == font) { + if (frp->refcnt++ == 0) { + /* load it */ + TRACE(("\trefcnt == 0. loading %s again...\n", frp->names[0])); + frp->font->fid = XLoadFont(frp->dpy, frp->names[0]); + } + return font; + } + } + + /* not found */ + TRACE(("\tfont not found in the cache\n")); + return NULL; +} + +/* ARGSUSED */ +void +CachedFreeFont(dpy, font) +Display *dpy; +XFontStruct *font; +{ + register FontRec *frp; + + TRACE(("CachedFreeFont(fid=%08lx)\n", font->fid)); + for (frp = FRP; frp != NULL; frp = frp->next) { + if (frp->font == font) { + if (--frp->refcnt == 0) { + /* unload it, but not free its structure for later use */ + TRACE(("\trefcnt == 0. unloading...\n")); + XUnloadFont(frp->dpy, frp->font->fid); + frp->font->fid = None; + } + return; + } + } + + /* not found. free anyway... */ + TRACE(("\tfont not found in the cache. free anyway...\n")); + XFreeFont(dpy, font); +}