2 * $RCSId: xc/lib/fontconfig/src/fclist.c,v 1.11tsi Exp $
4 * Copyright © 2000 Keith Packard
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)
48 int high, low, mid, c;
50 if (os->nobject == os->sobject)
54 objects = (const char **) realloc ((void *) os->objects,
55 s * sizeof (const char *));
57 objects = (const char **) malloc (s * sizeof (const char *));
61 FcMemFree (FC_MEM_OBJECTPTR, os->sobject * sizeof (const char *));
62 FcMemAlloc (FC_MEM_OBJECTPTR, s * sizeof (const char *));
63 os->objects = objects;
66 high = os->nobject - 1;
72 mid = (low + high) >> 1;
73 c = strcmp (os->objects[mid], object);
83 memmove (os->objects + mid + 1, os->objects + mid,
84 (os->nobject - mid) * sizeof (const char *));
85 os->objects[mid] = object;
91 FcObjectSetDestroy (FcObjectSet *os)
95 FcMemFree (FC_MEM_OBJECTPTR, os->sobject * sizeof (const char *));
96 free ((void *) os->objects);
98 FcMemFree (FC_MEM_OBJECTSET, sizeof (FcObjectSet));
103 FcObjectSetVaBuild (const char *first, va_list va)
107 FcObjectSetVapBuild (ret, first, va);
112 FcObjectSetBuild (const char *first, ...)
117 va_start (va, first);
118 FcObjectSetVapBuild (os, first, va);
124 * Font must have a containing value for every value in the pattern
127 FcListValueListMatchAny (FcValueList *patOrig, /* pattern */
128 FcValueList *fntOrig) /* font */
130 FcValueList *pat, *fnt;
132 for (pat = patOrig; pat; pat = pat->next)
134 for (fnt = fntOrig; fnt; fnt = fnt->next)
137 * make sure the font 'contains' the pattern.
138 * (OpListing is OpContains except for strings
139 * where it requires an exact match)
141 if (FcConfigCompareValue (fnt->value,
153 FcListValueListEqual (FcValueList *v1orig,
156 FcValueList *v1, *v2;
158 for (v1 = v1orig; v1; v1 = v1->next)
160 for (v2 = v2orig; v2; v2 = v2->next)
161 if (FcValueEqual (v1->value, v2->value))
166 for (v2 = v2orig; v2; v2 = v2->next)
168 for (v1 = v1orig; v1; v1 = v1->next)
169 if (FcValueEqual (v1->value, v2->value))
178 FcListPatternEqual (FcPattern *p1,
183 FcPatternElt *e1, *e2;
185 for (i = 0; i < os->nobject; i++)
187 e1 = FcPatternFindElt (p1, os->objects[i]);
188 e2 = FcPatternFindElt (p2, os->objects[i]);
193 if (!FcListValueListEqual (e1->values, e2->values))
200 * FcTrue iff all objects in "p" match "font"
204 FcListPatternMatchAny (const FcPattern *p,
205 const FcPattern *font)
210 for (i = 0; i < p->num; i++)
212 e = FcPatternFindElt (font, p->elts[i].object);
215 if (!FcListValueListMatchAny (p->elts[i].values, /* pat elts */
216 e->values)) /* font elts */
223 FcListStringHash (const FcChar8 *s)
231 h = ((h << 3) ^ (h >> 3)) ^ c;
237 FcListMatrixHash (const FcMatrix *m)
239 int xx = (int) (m->xx * 100),
240 xy = (int) (m->xy * 100),
241 yx = (int) (m->yx * 100),
242 yy = (int) (m->yy * 100);
244 return ((FcChar32) xx) ^ ((FcChar32) xy) ^ ((FcChar32) yx) ^ ((FcChar32) yy);
248 FcListValueHash (FcValue v)
254 return (FcChar32) v.u.i;
256 return (FcChar32) (int) v.u.d;
258 return FcListStringHash (v.u.s);
260 return (FcChar32) v.u.b;
262 return FcListMatrixHash (v.u.m);
264 return FcCharSetCount (v.u.c);
268 return FcLangSetHash (v.u.l);
274 FcListValueListHash (FcValueList *list)
280 h = h ^ FcListValueHash (list->value);
287 FcListPatternHash (FcPattern *font,
294 for (n = 0; n < os->nobject; n++)
296 e = FcPatternFindElt (font, os->objects[n]);
298 h = h ^ FcListValueListHash (e->values);
303 typedef struct _FcListBucket {
304 struct _FcListBucket *next;
309 #define FC_LIST_HASH_SIZE 4099
311 typedef struct _FcListHashTable {
313 FcListBucket *buckets[FC_LIST_HASH_SIZE];
317 FcListHashTableInit (FcListHashTable *table)
320 memset (table->buckets, '\0', sizeof (table->buckets));
324 FcListHashTableCleanup (FcListHashTable *table)
327 FcListBucket *bucket, *next;
329 for (i = 0; i < FC_LIST_HASH_SIZE; i++)
331 for (bucket = table->buckets[i]; bucket; bucket = next)
334 FcPatternDestroy (bucket->pattern);
335 FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket));
338 table->buckets[i] = 0;
344 FcListAppend (FcListHashTable *table,
352 FcListBucket **prev, *bucket;
354 hash = FcListPatternHash (font, os);
355 for (prev = &table->buckets[hash % FC_LIST_HASH_SIZE];
356 (bucket = *prev); prev = &(bucket->next))
358 if (bucket->hash == hash &&
359 FcListPatternEqual (bucket->pattern, font, os))
362 bucket = (FcListBucket *) malloc (sizeof (FcListBucket));
365 FcMemAlloc (FC_MEM_LISTBUCK, sizeof (FcListBucket));
368 bucket->pattern = FcPatternCreate ();
369 if (!bucket->pattern)
372 for (o = 0; o < os->nobject; o++)
374 e = FcPatternFindElt (font, os->objects[o]);
377 for (v = e->values; v; v = v->next)
379 if (!FcPatternAdd (bucket->pattern,
392 FcPatternDestroy (bucket->pattern);
394 FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket));
401 FcFontSetList (FcConfig *config,
411 FcListHashTable table;
413 FcListBucket *bucket;
417 if (!FcInitBringUptoDate ())
420 config = FcConfigGetCurrent ();
424 FcListHashTableInit (&table);
426 * Walk all available fonts adding those that
427 * match to the hash table
429 for (set = 0; set < nsets; set++)
434 for (f = 0; f < s->nfont; f++)
435 if (FcListPatternMatchAny (p, /* pattern */
436 s->fonts[f])) /* font */
437 if (!FcListAppend (&table, s->fonts[f], os))
446 for (i = 0; i < FC_LIST_HASH_SIZE; i++)
448 if ((bucket = table.buckets[i]))
451 for (; bucket; bucket = bucket->next)
461 printf ("used: %d max: %d avg: %g\n", full, max,
462 (double) ents / FC_LIST_HASH_SIZE);
466 * Walk the hash table and build
469 ret = FcFontSetCreate ();
472 for (i = 0; i < FC_LIST_HASH_SIZE; i++)
473 while ((bucket = table.buckets[i]))
475 if (!FcFontSetAdd (ret, bucket->pattern))
477 table.buckets[i] = bucket->next;
478 FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket));
485 FcFontSetDestroy (ret);
487 FcListHashTableCleanup (&table);
493 FcFontList (FcConfig *config,
502 config = FcConfigGetCurrent ();
507 if (config->fonts[FcSetSystem])
508 sets[nsets++] = config->fonts[FcSetSystem];
509 if (config->fonts[FcSetApplication])
510 sets[nsets++] = config->fonts[FcSetApplication];
511 return FcFontSetList (config, sets, nsets, p, os);