2 * $XFree86: xc/lib/fontconfig/src/fclist.c,v 1.2 2002/02/28 16:51:48 keithp Exp $
4 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of Keith Packard not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. Keith Packard makes no
13 * representations about the suitability of this software for any purpose. It
14 * is provided "as is" without express or implied warranty.
16 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
29 FcObjectSetCreate (void)
33 os = (FcObjectSet *) malloc (sizeof (FcObjectSet));
36 FcMemAlloc (FC_MEM_OBJECTSET, sizeof (FcObjectSet));
44 FcObjectSetAdd (FcObjectSet *os, const char *object)
49 if (os->nobject == os->sobject)
53 objects = (const char **) realloc ((void *) os->objects,
54 s * sizeof (const char *));
56 objects = (const char **) malloc (s * sizeof (const char *));
60 FcMemFree (FC_MEM_OBJECTPTR, os->sobject * sizeof (const char *));
61 FcMemAlloc (FC_MEM_OBJECTPTR, s * sizeof (const char *));
62 os->objects = objects;
65 os->objects[os->nobject++] = object;
70 FcObjectSetDestroy (FcObjectSet *os)
74 FcMemFree (FC_MEM_OBJECTPTR, os->sobject * sizeof (const char *));
75 free ((void *) os->objects);
77 FcMemFree (FC_MEM_OBJECTSET, sizeof (FcObjectSet));
82 FcObjectSetVaBuild (const char *first, va_list va)
86 FcObjectSetVapBuild (ret, first, va);
91 FcObjectSetBuild (const char *first, ...)
97 FcObjectSetVapBuild (os, first, va);
103 FcListValueListMatchAny (FcValueList *v1orig,
106 FcValueList *v1, *v2;
108 for (v1 = v1orig; v1; v1 = v1->next)
109 for (v2 = v2orig; v2; v2 = v2->next)
110 if (FcConfigCompareValue (v2->value, FcOpContains, v1->value))
116 FcListValueListEqual (FcValueList *v1orig,
119 FcValueList *v1, *v2;
121 for (v1 = v1orig; v1; v1 = v1->next)
123 for (v2 = v2orig; v2; v2 = v2->next)
124 if (FcConfigCompareValue (v1->value, FcOpEqual, v2->value))
129 for (v2 = v2orig; v2; v2 = v2->next)
131 for (v1 = v1orig; v1; v1 = v1->next)
132 if (FcConfigCompareValue (v1->value, FcOpEqual, v2->value))
141 * FcTrue iff all objects in "p" match "font"
145 FcListPatternMatchAny (FcPattern *p,
151 for (i = 0; i < p->num; i++)
153 e = FcPatternFind (font, p->elts[i].object, FcFalse);
156 if (!FcListValueListMatchAny (p->elts[i].values, e->values))
163 FcListPatternEqual (FcPattern *p1,
168 FcPatternElt *e1, *e2;
170 for (i = 0; i < os->nobject; i++)
172 e1 = FcPatternFind (p1, os->objects[i], FcFalse);
173 e2 = FcPatternFind (p2, os->objects[i], FcFalse);
178 if (!FcListValueListEqual (e1->values, e2->values))
185 FcListStringHash (const FcChar8 *s)
193 h = ((h << 3) ^ (h >> 3)) ^ c;
199 FcListMatrixHash (const FcMatrix *m)
201 int xx = (int) (m->xx * 100),
202 xy = (int) (m->xy * 100),
203 yx = (int) (m->yx * 100),
204 yy = (int) (m->yy * 100);
206 return ((FcChar32) xx) ^ ((FcChar32) xy) ^ ((FcChar32) yx) ^ ((FcChar32) yy);
210 FcListValueHash (FcValue v)
216 return (FcChar32) v.u.i;
218 return (FcChar32) (int) v.u.d;
220 return FcListStringHash (v.u.s);
222 return (FcChar32) v.u.b;
224 return FcListMatrixHash (v.u.m);
226 return FcCharSetCount (v.u.c);
232 FcListValueListHash (FcValueList *list)
238 h = h ^ FcListValueHash (list->value);
245 FcListPatternHash (FcPattern *font,
252 for (n = 0; n < os->nobject; n++)
254 e = FcPatternFind (font, os->objects[n], FcFalse);
256 h = h ^ FcListValueListHash (e->values);
261 typedef struct _FcListBucket {
262 struct _FcListBucket *next;
267 #define FC_LIST_HASH_SIZE 4099
269 typedef struct _FcListHashTable {
271 FcListBucket *buckets[FC_LIST_HASH_SIZE];
275 FcListHashTableInit (FcListHashTable *table)
278 memset (table->buckets, '\0', sizeof (table->buckets));
282 FcListHashTableCleanup (FcListHashTable *table)
285 FcListBucket *bucket, *next;
287 for (i = 0; i < FC_LIST_HASH_SIZE; i++)
289 for (bucket = table->buckets[i]; bucket; bucket = next)
292 FcPatternDestroy (bucket->pattern);
293 FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket));
296 table->buckets[i] = 0;
302 FcListAppend (FcListHashTable *table,
310 FcListBucket **prev, *bucket;
312 hash = FcListPatternHash (font, os);
313 for (prev = &table->buckets[hash % FC_LIST_HASH_SIZE];
314 (bucket = *prev); prev = &(bucket->next))
316 if (bucket->hash == hash &&
317 FcListPatternEqual (bucket->pattern, font, os))
320 bucket = (FcListBucket *) malloc (sizeof (FcListBucket));
323 FcMemAlloc (FC_MEM_LISTBUCK, sizeof (FcListBucket));
326 bucket->pattern = FcPatternCreate ();
327 if (!bucket->pattern)
330 for (o = 0; o < os->nobject; o++)
332 e = FcPatternFind (font, os->objects[o], FcFalse);
335 for (v = e->values; v; v = v->next)
337 if (!FcPatternAdd (bucket->pattern,
350 FcPatternDestroy (bucket->pattern);
352 FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket));
359 FcFontSetList (FcConfig *config,
369 FcListHashTable table;
371 FcListBucket *bucket;
375 if (!FcInitBringUptoDate ())
378 config = FcConfigGetCurrent ();
382 FcListHashTableInit (&table);
384 * Walk all available fonts adding those that
385 * match to the hash table
387 for (set = 0; set < nsets; set++)
392 for (f = 0; f < s->nfont; f++)
393 if (FcListPatternMatchAny (p, s->fonts[f]))
394 if (!FcListAppend (&table, s->fonts[f], os))
403 for (i = 0; i < FC_LIST_HASH_SIZE; i++)
405 if ((bucket = table.buckets[i]))
408 for (; bucket; bucket = bucket->next)
418 printf ("used: %d max: %d avg: %g\n", full, max,
419 (double) ents / FC_LIST_HASH_SIZE);
423 * Walk the hash table and build
426 ret = FcFontSetCreate ();
429 for (i = 0; i < FC_LIST_HASH_SIZE; i++)
430 while ((bucket = table.buckets[i]))
432 if (!FcFontSetAdd (ret, bucket->pattern))
434 table.buckets[i] = bucket->next;
435 FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket));
442 FcFontSetDestroy (ret);
444 FcListHashTableCleanup (&table);
450 FcFontList (FcConfig *config,
459 config = FcConfigGetCurrent ();
464 if (config->fonts[FcSetSystem])
465 sets[nsets++] = config->fonts[FcSetSystem];
466 if (config->fonts[FcSetApplication])
467 sets[nsets++] = config->fonts[FcSetApplication];
468 return FcFontSetList (config, sets, nsets, p, os);