fontconfig/src/fclist.c

608 lines
13 KiB
C
Raw Normal View History

2002-02-15 00:34:13 +01:00
/*
2008-08-12 22:34:24 +02:00
* fontconfig/src/fclist.c
2002-02-15 00:34:13 +01:00
*
2004-12-07 02:14:46 +01:00
* Copyright © 2000 Keith Packard
2002-02-15 00:34:13 +01:00
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, 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 the author(s) not be used in
2002-02-15 00:34:13 +01:00
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. The authors make no
2002-02-15 00:34:13 +01:00
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
2002-02-15 00:34:13 +01:00
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
2002-02-15 00:34:13 +01:00
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "fcint.h"
#include <stdlib.h>
2002-02-15 00:34:13 +01:00
FcObjectSet *
FcObjectSetCreate (void)
{
FcObjectSet *os;
os = (FcObjectSet *) malloc (sizeof (FcObjectSet));
if (!os)
return 0;
os->nobject = 0;
os->sobject = 0;
os->objects = 0;
return os;
}
FcBool
FcObjectSetAdd (FcObjectSet *os, const char *object)
{
int s;
const char **objects;
int high, low, mid, c;
2010-04-12 18:18:50 +02:00
2002-02-15 00:34:13 +01:00
if (os->nobject == os->sobject)
{
s = os->sobject + 4;
if (os->objects)
objects = (const char **) realloc ((void *) os->objects,
s * sizeof (const char *));
2002-02-15 00:34:13 +01:00
else
objects = (const char **) malloc (s * sizeof (const char *));
2002-02-15 00:34:13 +01:00
if (!objects)
return FcFalse;
os->objects = objects;
os->sobject = s;
}
high = os->nobject - 1;
low = 0;
mid = 0;
c = 1;
2013-01-02 09:06:15 +01:00
object = strdup (object);
while (low <= high)
{
mid = (low + high) >> 1;
c = os->objects[mid] - object;
if (c == 0)
{
2013-01-02 09:06:15 +01:00
FcFree (object);
return FcTrue;
}
if (c < 0)
low = mid + 1;
else
high = mid - 1;
}
if (c < 0)
mid++;
2010-04-12 18:18:50 +02:00
memmove (os->objects + mid + 1, os->objects + mid,
(os->nobject - mid) * sizeof (const char *));
os->objects[mid] = object;
os->nobject++;
2002-02-15 00:34:13 +01:00
return FcTrue;
}
void
FcObjectSetDestroy (FcObjectSet *os)
{
int i;
2002-02-15 00:34:13 +01:00
if (os->objects)
{
for (i = 0; i < os->nobject; i++)
2013-01-02 09:06:15 +01:00
FcFree (os->objects[i]);
2002-02-15 00:34:13 +01:00
free ((void *) os->objects);
}
free (os);
}
FcObjectSet *
FcObjectSetVaBuild (const char *first, va_list va)
{
FcObjectSet *ret;
FcObjectSetVapBuild (ret, first, va);
return ret;
}
FcObjectSet *
FcObjectSetBuild (const char *first, ...)
{
va_list va;
FcObjectSet *os;
va_start (va, first);
FcObjectSetVapBuild (os, first, va);
va_end (va);
return os;
}
/*
* Font must have a containing value for every value in the pattern
*/
2002-02-15 00:34:13 +01:00
static FcBool
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
FcListValueListMatchAny (FcValueListPtr patOrig, /* pattern */
FcValueListPtr fntOrig) /* font */
2002-02-15 00:34:13 +01:00
{
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
FcValueListPtr pat, fnt;
2002-02-15 00:34:13 +01:00
for (pat = patOrig; pat != NULL; pat = FcValueListNext(pat))
{
for (fnt = fntOrig; fnt != NULL; fnt = FcValueListNext(fnt))
{
/*
* make sure the font 'contains' the pattern.
* (OpListing is OpContains except for strings
* where it requires an exact match)
*/
if (FcConfigCompareValue (&fnt->value,
FC_OP (FcOpListing, FcOpFlagIgnoreBlanks),
2010-04-12 18:18:50 +02:00
&pat->value))
break;
}
if (fnt == NULL)
return FcFalse;
}
return FcTrue;
2002-02-15 00:34:13 +01:00
}
static FcBool
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
FcListValueListEqual (FcValueListPtr v1orig,
FcValueListPtr v2orig)
2002-02-15 00:34:13 +01:00
{
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
FcValueListPtr v1, v2;
2002-02-15 00:34:13 +01:00
for (v1 = v1orig; v1 != NULL; v1 = FcValueListNext(v1))
2002-02-15 00:34:13 +01:00
{
for (v2 = v2orig; v2 != NULL; v2 = FcValueListNext(v2))
if (FcValueEqual (FcValueCanonicalize(&(v1)->value),
FcValueCanonicalize(&(v2)->value)))
2002-02-15 00:34:13 +01:00
break;
if (v2 == NULL)
2002-02-15 00:34:13 +01:00
return FcFalse;
}
for (v2 = v2orig; v2 != NULL; v2 = FcValueListNext(v2))
2002-02-15 00:34:13 +01:00
{
for (v1 = v1orig; v1 != NULL; v1 = FcValueListNext(v1))
if (FcValueEqual (FcValueCanonicalize(&v1->value),
FcValueCanonicalize(&v2->value)))
2002-02-15 00:34:13 +01:00
break;
if (v1 == NULL)
2002-02-15 00:34:13 +01:00
return FcFalse;
}
return FcTrue;
}
static FcBool
FcListPatternEqual (FcPattern *p1,
FcPattern *p2,
FcObjectSet *os)
2002-02-15 00:34:13 +01:00
{
int i;
FcPatternElt *e1, *e2;
2002-02-15 00:34:13 +01:00
for (i = 0; i < os->nobject; i++)
2002-02-15 00:34:13 +01:00
{
e1 = FcPatternObjectFindElt (p1, FcObjectFromName (os->objects[i]));
e2 = FcPatternObjectFindElt (p2, FcObjectFromName (os->objects[i]));
if (!e1 && !e2)
continue;
if (!e1 || !e2)
2002-02-15 00:34:13 +01:00
return FcFalse;
if (!FcListValueListEqual (FcPatternEltValues(e1),
FcPatternEltValues(e2)))
2002-02-15 00:34:13 +01:00
return FcFalse;
}
return FcTrue;
}
/*
* FcTrue iff all objects in "p" match "font"
*/
FcBool
FcListPatternMatchAny (const FcPattern *p,
const FcPattern *font)
2002-02-15 00:34:13 +01:00
{
int i;
if (!p)
return FcFalse;
for (i = 0; i < p->num; i++)
2002-02-15 00:34:13 +01:00
{
FcPatternElt *pe = &FcPatternElts(p)[i];
FcPatternElt *fe;
if (pe->object == FC_NAMELANG_OBJECT)
{
/* "namelang" object is the alias object to change "familylang",
* "stylelang" and "fullnamelang" object alltogether. it won't be
* available on the font pattern. so checking its availability
* causes no results. we should ignore it here.
*/
continue;
}
fe = FcPatternObjectFindElt (font, pe->object);
if (!fe)
2002-02-15 00:34:13 +01:00
return FcFalse;
if (!FcListValueListMatchAny (FcPatternEltValues(pe), /* pat elts */
FcPatternEltValues(fe))) /* font elts */
2002-02-15 00:34:13 +01:00
return FcFalse;
}
return FcTrue;
}
static FcChar32
FcListMatrixHash (const FcMatrix *m)
{
2010-04-12 18:18:50 +02:00
int xx = (int) (m->xx * 100),
xy = (int) (m->xy * 100),
2002-02-15 00:34:13 +01:00
yx = (int) (m->yx * 100),
yy = (int) (m->yy * 100);
return ((FcChar32) xx) ^ ((FcChar32) xy) ^ ((FcChar32) yx) ^ ((FcChar32) yy);
}
static FcChar32
FcListValueHash (FcValue *value)
2002-02-15 00:34:13 +01:00
{
FcValue v = FcValueCanonicalize(value);
2002-02-15 00:34:13 +01:00
switch (v.type) {
case FcTypeUnknown:
2002-02-15 00:34:13 +01:00
case FcTypeVoid:
return 0;
case FcTypeInteger:
return (FcChar32) v.u.i;
case FcTypeDouble:
return (FcChar32) (int) v.u.d;
case FcTypeString:
return FcStrHashIgnoreCase (v.u.s);
2002-02-15 00:34:13 +01:00
case FcTypeBool:
return (FcChar32) v.u.b;
case FcTypeMatrix:
return FcListMatrixHash (v.u.m);
2002-02-15 00:34:13 +01:00
case FcTypeCharSet:
return FcCharSetCount (v.u.c);
case FcTypeFTFace:
2002-09-18 19:11:46 +02:00
return (long) v.u.f;
case FcTypeLangSet:
return FcLangSetHash (v.u.l);
2002-02-15 00:34:13 +01:00
}
return 0;
}
static FcChar32
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
FcListValueListHash (FcValueListPtr list)
2002-02-15 00:34:13 +01:00
{
FcChar32 h = 0;
2010-04-12 18:18:50 +02:00
while (list != NULL)
2002-02-15 00:34:13 +01:00
{
h = h ^ FcListValueHash (&list->value);
list = FcValueListNext(list);
2002-02-15 00:34:13 +01:00
}
return h;
}
static FcChar32
FcListPatternHash (FcPattern *font,
FcObjectSet *os)
{
int n;
FcPatternElt *e;
FcChar32 h = 0;
for (n = 0; n < os->nobject; n++)
{
e = FcPatternObjectFindElt (font, FcObjectFromName (os->objects[n]));
2002-02-15 00:34:13 +01:00
if (e)
h = h ^ FcListValueListHash (FcPatternEltValues(e));
2002-02-15 00:34:13 +01:00
}
return h;
}
typedef struct _FcListBucket {
struct _FcListBucket *next;
FcChar32 hash;
FcPattern *pattern;
} FcListBucket;
#define FC_LIST_HASH_SIZE 4099
typedef struct _FcListHashTable {
int entries;
FcListBucket *buckets[FC_LIST_HASH_SIZE];
} FcListHashTable;
2010-04-12 18:18:50 +02:00
2002-02-15 00:34:13 +01:00
static void
FcListHashTableInit (FcListHashTable *table)
{
table->entries = 0;
memset (table->buckets, '\0', sizeof (table->buckets));
}
static void
FcListHashTableCleanup (FcListHashTable *table)
{
int i;
FcListBucket *bucket, *next;
for (i = 0; i < FC_LIST_HASH_SIZE; i++)
{
for (bucket = table->buckets[i]; bucket; bucket = next)
{
next = bucket->next;
FcPatternDestroy (bucket->pattern);
free (bucket);
}
table->buckets[i] = 0;
}
table->entries = 0;
}
static int
FcGetDefaultObjectLangIndex (FcPattern *font, FcObject object, const FcChar8 *lang)
{
FcPatternElt *e = FcPatternObjectFindElt (font, object);
FcValueListPtr v;
FcValue value;
int idx = -1;
int defidx = -1;
int i;
if (e)
{
for (v = FcPatternEltValues(e), i = 0; v; v = FcValueListNext(v), ++i)
{
value = FcValueCanonicalize (&v->value);
if (value.type == FcTypeString)
{
FcLangResult res = FcLangCompare (value.u.s, lang);
if (res == FcLangEqual)
return i;
if (res == FcLangDifferentCountry && idx < 0)
idx = i;
if (defidx < 0)
{
/* workaround for fonts that has non-English value
* at the head of values.
*/
res = FcLangCompare (value.u.s, (FcChar8 *)"en");
if (res == FcLangEqual)
defidx = i;
}
}
}
}
return (idx > 0) ? idx : (defidx > 0) ? defidx : 0;
}
2002-02-15 00:34:13 +01:00
static FcBool
FcListAppend (FcListHashTable *table,
FcPattern *font,
FcObjectSet *os,
const FcChar8 *lang)
2002-02-15 00:34:13 +01:00
{
int o;
FcPatternElt *e;
Add functionality to allow fontconfig data structure serialization. This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
2005-06-28 05:41:02 +02:00
FcValueListPtr v;
2002-02-15 00:34:13 +01:00
FcChar32 hash;
FcListBucket **prev, *bucket;
int familyidx = -1;
int fullnameidx = -1;
int styleidx = -1;
int defidx = 0;
int idx;
2002-02-15 00:34:13 +01:00
hash = FcListPatternHash (font, os);
for (prev = &table->buckets[hash % FC_LIST_HASH_SIZE];
(bucket = *prev); prev = &(bucket->next))
{
2010-04-12 18:18:50 +02:00
if (bucket->hash == hash &&
2002-02-15 00:34:13 +01:00
FcListPatternEqual (bucket->pattern, font, os))
return FcTrue;
}
bucket = (FcListBucket *) malloc (sizeof (FcListBucket));
if (!bucket)
goto bail0;
bucket->next = 0;
bucket->hash = hash;
bucket->pattern = FcPatternCreate ();
if (!bucket->pattern)
goto bail1;
2010-04-12 18:18:50 +02:00
2002-02-15 00:34:13 +01:00
for (o = 0; o < os->nobject; o++)
{
if (!strcmp (os->objects[o], FC_FAMILY) || !strcmp (os->objects[o], FC_FAMILYLANG))
{
if (familyidx < 0)
familyidx = FcGetDefaultObjectLangIndex (font, FC_FAMILYLANG_OBJECT, lang);
defidx = familyidx;
}
else if (!strcmp (os->objects[o], FC_FULLNAME) || !strcmp (os->objects[o], FC_FULLNAMELANG))
{
if (fullnameidx < 0)
fullnameidx = FcGetDefaultObjectLangIndex (font, FC_FULLNAMELANG_OBJECT, lang);
defidx = fullnameidx;
}
else if (!strcmp (os->objects[o], FC_STYLE) || !strcmp (os->objects[o], FC_STYLELANG))
{
if (styleidx < 0)
styleidx = FcGetDefaultObjectLangIndex (font, FC_STYLELANG_OBJECT, lang);
defidx = styleidx;
}
else
defidx = 0;
e = FcPatternObjectFindElt (font, FcObjectFromName (os->objects[o]));
2002-02-15 00:34:13 +01:00
if (e)
{
for (v = FcPatternEltValues(e), idx = 0; v;
v = FcValueListNext(v), ++idx)
2002-02-15 00:34:13 +01:00
{
2010-04-12 18:18:50 +02:00
if (!FcPatternAdd (bucket->pattern,
os->objects[o],
FcValueCanonicalize(&v->value), defidx != idx))
2002-02-15 00:34:13 +01:00
goto bail2;
}
}
}
*prev = bucket;
++table->entries;
return FcTrue;
2010-04-12 18:18:50 +02:00
2002-02-15 00:34:13 +01:00
bail2:
FcPatternDestroy (bucket->pattern);
bail1:
free (bucket);
bail0:
return FcFalse;
}
FcFontSet *
FcFontSetList (FcConfig *config,
FcFontSet **sets,
int nsets,
FcPattern *p,
FcObjectSet *os)
2002-02-15 00:34:13 +01:00
{
FcFontSet *ret;
FcFontSet *s;
int f;
int set;
2002-02-15 00:34:13 +01:00
FcListHashTable table;
int i;
FcListBucket *bucket;
int destroy_os = 0;
2002-02-15 00:34:13 +01:00
if (!config)
{
if (!FcInitBringUptoDate ())
goto bail0;
2002-02-15 00:34:13 +01:00
config = FcConfigGetCurrent ();
if (!config)
goto bail0;
}
FcListHashTableInit (&table);
if (!os)
{
os = FcObjectGetSet ();
destroy_os = 1;
}
2002-02-15 00:34:13 +01:00
/*
* Walk all available fonts adding those that
* match to the hash table
*/
for (set = 0; set < nsets; set++)
2002-02-15 00:34:13 +01:00
{
s = sets[set];
2002-02-15 00:34:13 +01:00
if (!s)
continue;
for (f = 0; f < s->nfont; f++)
if (FcListPatternMatchAny (p, /* pattern */
s->fonts[f])) /* font */
{
FcChar8 *lang;
if (FcPatternObjectGetString (p, FC_NAMELANG_OBJECT, 0, &lang) != FcResultMatch)
{
lang = FcGetDefaultLang ();
}
if (!FcListAppend (&table, s->fonts[f], os, lang))
2002-02-15 00:34:13 +01:00
goto bail1;
}
2002-02-15 00:34:13 +01:00
}
#if 0
{
int max = 0;
int full = 0;
int ents = 0;
int len;
for (i = 0; i < FC_LIST_HASH_SIZE; i++)
{
if ((bucket = table.buckets[i]))
{
len = 0;
for (; bucket; bucket = bucket->next)
{
ents++;
len++;
}
if (len > max)
max = len;
full++;
}
}
2010-04-12 18:18:50 +02:00
printf ("used: %d max: %d avg: %g\n", full, max,
2002-02-15 00:34:13 +01:00
(double) ents / FC_LIST_HASH_SIZE);
}
#endif
/*
* Walk the hash table and build
* a font set
*/
ret = FcFontSetCreate ();
if (!ret)
goto bail0;
for (i = 0; i < FC_LIST_HASH_SIZE; i++)
while ((bucket = table.buckets[i]))
{
if (!FcFontSetAdd (ret, bucket->pattern))
goto bail2;
table.buckets[i] = bucket->next;
free (bucket);
}
2010-04-12 18:18:50 +02:00
2002-02-15 00:34:13 +01:00
return ret;
bail2:
FcFontSetDestroy (ret);
bail1:
FcListHashTableCleanup (&table);
bail0:
if (destroy_os)
FcObjectSetDestroy (os);
2002-02-15 00:34:13 +01:00
return 0;
}
FcFontSet *
FcFontList (FcConfig *config,
FcPattern *p,
FcObjectSet *os)
{
FcFontSet *sets[2];
int nsets;
if (!config)
{
if (!FcInitBringUptoDate ())
return 0;
config = FcConfigGetCurrent ();
if (!config)
return 0;
}
nsets = 0;
if (config->fonts[FcSetSystem])
sets[nsets++] = config->fonts[FcSetSystem];
if (config->fonts[FcSetApplication])
sets[nsets++] = config->fonts[FcSetApplication];
return FcFontSetList (config, sets, nsets, p, os);
}
#define __fclist__
#include "fcaliastail.h"
#undef __fclist__