patcache.c revision 41c30155
123a0898aSmrg/*
223a0898aSmrg
323a0898aSmrgCopyright 1991, 1998  The Open Group
423a0898aSmrg
523a0898aSmrgPermission to use, copy, modify, distribute, and sell this software and its
623a0898aSmrgdocumentation for any purpose is hereby granted without fee, provided that
723a0898aSmrgthe above copyright notice appear in all copies and that both that
823a0898aSmrgcopyright notice and this permission notice appear in supporting
923a0898aSmrgdocumentation.
1023a0898aSmrg
1123a0898aSmrgThe above copyright notice and this permission notice shall be included in
1223a0898aSmrgall copies or substantial portions of the Software.
1323a0898aSmrg
1423a0898aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1523a0898aSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1623a0898aSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
1723a0898aSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1823a0898aSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1923a0898aSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2023a0898aSmrg
2123a0898aSmrgExcept as contained in this notice, the name of The Open Group shall not be
2223a0898aSmrgused in advertising or otherwise to promote the sale, use or other dealings
2323a0898aSmrgin this Software without prior written authorization from The Open Group.
2423a0898aSmrg
2523a0898aSmrg*/
2623a0898aSmrg
2723a0898aSmrg/*
2823a0898aSmrg * Author:  Keith Packard, MIT X Consortium
2923a0898aSmrg */
3023a0898aSmrg
3123a0898aSmrg#ifdef HAVE_CONFIG_H
3223a0898aSmrg#include <config.h>
3323a0898aSmrg#endif
3423a0898aSmrg#include    <X11/fonts/fontmisc.h>
3523a0898aSmrg#include    <X11/fonts/fontstruct.h>
3623a0898aSmrg
3723a0898aSmrg/*
3823a0898aSmrg * Static sized hash table for looking up font name patterns
3923a0898aSmrg *
4023a0898aSmrg * LRU entries, reusing old entries
4123a0898aSmrg */
4223a0898aSmrg
4323a0898aSmrg#define NBUCKETS	16
4423a0898aSmrg#define NENTRIES	64
4523a0898aSmrg
4623a0898aSmrg#define UNSET		(NENTRIES+1)
4723a0898aSmrg
4823a0898aSmrgtypedef unsigned char	EntryPtr;
4923a0898aSmrg
5023a0898aSmrgtypedef struct _FontPatternCacheEntry {
5123a0898aSmrg    struct _FontPatternCacheEntry   *next, **prev;
5223a0898aSmrg    short			    patlen;
5323a0898aSmrg    char			    *pattern;
5423a0898aSmrg    int				    hash;
5523a0898aSmrg    FontPtr			    pFont;	/* associated font */
5623a0898aSmrg} FontPatternCacheEntryRec, *FontPatternCacheEntryPtr;
5723a0898aSmrg
5823a0898aSmrgtypedef struct _FontPatternCache {
5923a0898aSmrg    FontPatternCacheEntryPtr	buckets[NBUCKETS];
6023a0898aSmrg    FontPatternCacheEntryRec	entries[NENTRIES];
6123a0898aSmrg    FontPatternCacheEntryPtr	free;
6223a0898aSmrg} FontPatternCacheRec;
6323a0898aSmrg
6423a0898aSmrg/* Empty cache (for rehash) */
6523a0898aSmrgvoid
6623a0898aSmrgEmptyFontPatternCache (FontPatternCachePtr cache)
6723a0898aSmrg{
6823a0898aSmrg    int	    i;
6941c30155Smrg
7023a0898aSmrg    for (i = 0; i < NBUCKETS; i++)
7123a0898aSmrg	cache->buckets[i] = 0;
7223a0898aSmrg    for (i = 0; i < NENTRIES; i++)
7323a0898aSmrg    {
7423a0898aSmrg	cache->entries[i].next = &cache->entries[i+1];
7523a0898aSmrg	cache->entries[i].prev = 0;
7623a0898aSmrg	cache->entries[i].pFont = 0;
777f7f5e4eSmrg	free (cache->entries[i].pattern);
7823a0898aSmrg	cache->entries[i].pattern = 0;
7923a0898aSmrg	cache->entries[i].patlen = 0;
8023a0898aSmrg    }
8123a0898aSmrg    cache->free = &cache->entries[0];
8223a0898aSmrg    cache->entries[NENTRIES - 1].next = 0;
8323a0898aSmrg}
8423a0898aSmrg
8523a0898aSmrg/* Create and initialize cache */
8623a0898aSmrgFontPatternCachePtr
8723a0898aSmrgMakeFontPatternCache (void)
8823a0898aSmrg{
8923a0898aSmrg    FontPatternCachePtr	cache;
9023a0898aSmrg    int			i;
917f7f5e4eSmrg    cache = malloc (sizeof *cache);
9223a0898aSmrg    if (!cache)
9323a0898aSmrg	return 0;
9423a0898aSmrg    for (i = 0; i < NENTRIES; i++) {
9523a0898aSmrg	cache->entries[i].patlen = 0;
9623a0898aSmrg	cache->entries[i].pattern = 0;
9723a0898aSmrg	cache->entries[i].pFont = 0;
9823a0898aSmrg    }
9923a0898aSmrg    EmptyFontPatternCache (cache);
10023a0898aSmrg    return cache;
10123a0898aSmrg}
10223a0898aSmrg
10323a0898aSmrg/* toss cache */
10423a0898aSmrgvoid
10523a0898aSmrgFreeFontPatternCache (FontPatternCachePtr cache)
10623a0898aSmrg{
10723a0898aSmrg    int	    i;
10823a0898aSmrg
10923a0898aSmrg    for (i = 0; i < NENTRIES; i++)
1107f7f5e4eSmrg	free (cache->entries[i].pattern);
1117f7f5e4eSmrg    free (cache);
11223a0898aSmrg}
11323a0898aSmrg
11423a0898aSmrg/* compute id for string */
11523a0898aSmrgstatic int
11623a0898aSmrgHash (const char *string, int len)
11723a0898aSmrg{
11823a0898aSmrg    int	hash;
11923a0898aSmrg
12023a0898aSmrg    hash = 0;
12123a0898aSmrg    while (len--)
12223a0898aSmrg	hash = (hash << 1) ^ *string++;
12323a0898aSmrg    if (hash < 0)
12423a0898aSmrg	hash = -hash;
12523a0898aSmrg    return hash;
12623a0898aSmrg}
12723a0898aSmrg
12823a0898aSmrg/* add entry */
12923a0898aSmrgvoid
13041c30155SmrgCacheFontPattern (FontPatternCachePtr cache,
13141c30155Smrg		  char *pattern,
13241c30155Smrg		  int patlen,
13323a0898aSmrg		  FontPtr pFont)
13423a0898aSmrg{
13523a0898aSmrg    FontPatternCacheEntryPtr	e;
13623a0898aSmrg    char			*newpat;
13723a0898aSmrg    int				i;
13823a0898aSmrg
1397f7f5e4eSmrg    newpat = malloc (patlen);
14023a0898aSmrg    if (!newpat)
14123a0898aSmrg	return;
14223a0898aSmrg    if (cache->free)
14323a0898aSmrg    {
14423a0898aSmrg	e = cache->free;
14523a0898aSmrg	cache->free = e->next;
14623a0898aSmrg    }
14723a0898aSmrg    else
14823a0898aSmrg    {
14923a0898aSmrg    	i = rand ();
15023a0898aSmrg    	if (i < 0)
15123a0898aSmrg	    i = -i;
15223a0898aSmrg    	i %= NENTRIES;
15323a0898aSmrg	e = &cache->entries[i];
15423a0898aSmrg	if (e->next)
15523a0898aSmrg	    e->next->prev = e->prev;
15623a0898aSmrg	*e->prev = e->next;
1577f7f5e4eSmrg	free (e->pattern);
15823a0898aSmrg    }
15923a0898aSmrg    /* set pattern */
16023a0898aSmrg    memcpy (newpat, pattern, patlen);
16123a0898aSmrg    e->pattern = newpat;
16223a0898aSmrg    e->patlen = patlen;
16323a0898aSmrg    /* link to new hash chain */
16423a0898aSmrg    e->hash = Hash (pattern, patlen);
16523a0898aSmrg    i = e->hash % NBUCKETS;
16623a0898aSmrg    e->next = cache->buckets[i];
16723a0898aSmrg    if (e->next)
16823a0898aSmrg	e->next->prev = &(e->next);
16923a0898aSmrg    cache->buckets[i] = e;
17023a0898aSmrg    e->prev = &(cache->buckets[i]);
17123a0898aSmrg    e->pFont = pFont;
17223a0898aSmrg}
17323a0898aSmrg
17423a0898aSmrg/* find matching entry */
17523a0898aSmrgFontPtr
17641c30155SmrgFindCachedFontPattern (FontPatternCachePtr cache,
17741c30155Smrg		       char *pattern,
17823a0898aSmrg		       int patlen)
17923a0898aSmrg{
18023a0898aSmrg    int				hash;
18123a0898aSmrg    int				i;
18223a0898aSmrg    FontPatternCacheEntryPtr	e;
18323a0898aSmrg
18423a0898aSmrg    hash = Hash (pattern, patlen);
18523a0898aSmrg    i = hash % NBUCKETS;
18623a0898aSmrg    for (e = cache->buckets[i]; e; e = e->next)
18723a0898aSmrg    {
18823a0898aSmrg	if (e->patlen == patlen && e->hash == hash &&
18923a0898aSmrg	    !memcmp (e->pattern, pattern, patlen))
19023a0898aSmrg	{
19123a0898aSmrg	    return e->pFont;
19223a0898aSmrg	}
19323a0898aSmrg    }
19423a0898aSmrg    return 0;
19523a0898aSmrg}
19623a0898aSmrg
19723a0898aSmrgvoid
19841c30155SmrgRemoveCachedFontPattern (FontPatternCachePtr cache,
19923a0898aSmrg			 FontPtr pFont)
20023a0898aSmrg{
20123a0898aSmrg    FontPatternCacheEntryPtr	e;
20223a0898aSmrg    int				i;
20323a0898aSmrg
20423a0898aSmrg    for (i = 0; i < NENTRIES; i++)
20523a0898aSmrg    {
20623a0898aSmrg	if ((e = &cache->entries[i])->pFont == pFont)
20723a0898aSmrg	{
20823a0898aSmrg	    e->pFont = 0;
20923a0898aSmrg	    if (e->next)
21023a0898aSmrg		e->next->prev = e->prev;
21123a0898aSmrg	    *e->prev = e->next;
21223a0898aSmrg	    e->next = cache->free;
21323a0898aSmrg	    cache->free = e;
2147f7f5e4eSmrg	    free (e->pattern);
21523a0898aSmrg	    e->pattern = 0;
21623a0898aSmrg	}
21723a0898aSmrg    }
21823a0898aSmrg}
219