/*
- * $XFree86: xc/lib/fontconfig/src/fclist.c,v 1.2 2002/02/28 16:51:48 keithp Exp $
+ * $RCSId: xc/lib/fontconfig/src/fclist.c,v 1.11tsi Exp $
*
- * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ * Copyright © 2000 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* PERFORMANCE OF THIS SOFTWARE.
*/
-#include <stdlib.h>
#include "fcint.h"
+#include <stdlib.h>
FcObjectSet *
FcObjectSetCreate (void)
{
int s;
const char **objects;
+ int high, low, mid, c;
if (os->nobject == os->sobject)
{
os->objects = objects;
os->sobject = s;
}
- os->objects[os->nobject++] = object;
+ high = os->nobject - 1;
+ low = 0;
+ mid = 0;
+ c = 1;
+ object = (char *)FcStrStaticName ((FcChar8 *)object);
+ while (low <= high)
+ {
+ mid = (low + high) >> 1;
+ c = os->objects[mid] - object;
+ if (c == 0)
+ return FcTrue;
+ if (c < 0)
+ low = mid + 1;
+ else
+ high = mid - 1;
+ }
+ if (c < 0)
+ mid++;
+ memmove (os->objects + mid + 1, os->objects + mid,
+ (os->nobject - mid) * sizeof (const char *));
+ os->objects[mid] = object;
+ os->nobject++;
return FcTrue;
}
return os;
}
+/*
+ * Font must have a containing value for every value in the pattern
+ */
static FcBool
-FcListValueListMatchAny (FcValueList *v1orig,
- FcValueList *v2orig)
-{
- FcValueList *v1, *v2;
-
- for (v1 = v1orig; v1; v1 = v1->next)
- for (v2 = v2orig; v2; v2 = v2->next)
- if (FcConfigCompareValue (v2->value, FcOpContains, v1->value))
- return FcTrue;
- return FcFalse;
-}
-
-static FcBool
-FcListValueListEqual (FcValueList *v1orig,
- FcValueList *v2orig)
+FcListValueListMatchAny (FcValueListPtr patOrig, /* pattern */
+ FcValueListPtr fntOrig) /* font */
{
- FcValueList *v1, *v2;
+ FcValueListPtr pat, fnt;
- for (v1 = v1orig; v1; v1 = v1->next)
- {
- for (v2 = v2orig; v2; v2 = v2->next)
- if (FcConfigCompareValue (v1->value, FcOpEqual, v2->value))
- break;
- if (!v2)
- return FcFalse;
- }
- for (v2 = v2orig; v2; v2 = v2->next)
+ for (pat = patOrig; pat != NULL; pat = FcValueListNext(pat))
{
- for (v1 = v1orig; v1; v1 = v1->next)
- if (FcConfigCompareValue (v1->value, FcOpEqual, v2->value))
+ 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,
+ FcOpListing,
+ &pat->value))
break;
- if (!v1)
+ }
+ if (fnt == NULL)
return FcFalse;
}
return FcTrue;
}
-/*
- * FcTrue iff all objects in "p" match "font"
- */
-
static FcBool
-FcListPatternMatchAny (FcPattern *p,
- FcPattern *font)
+FcListValueListEqual (FcValueListPtr v1orig,
+ FcValueListPtr v2orig)
{
- int i;
- FcPatternElt *e;
+ FcValueListPtr v1, v2;
- for (i = 0; i < p->num; i++)
+ for (v1 = v1orig; v1 != NULL; v1 = FcValueListNext(v1))
{
- e = FcPatternFind (font, p->elts[i].object, FcFalse);
- if (!e)
+ for (v2 = v2orig; v2 != NULL; v2 = FcValueListNext(v2))
+ if (FcValueEqual (FcValueCanonicalize(&(v1)->value),
+ FcValueCanonicalize(&(v2)->value)))
+ break;
+ if (v2 == NULL)
return FcFalse;
- if (!FcListValueListMatchAny (p->elts[i].values, e->values))
+ }
+ for (v2 = v2orig; v2 != NULL; v2 = FcValueListNext(v2))
+ {
+ for (v1 = v1orig; v1 != NULL; v1 = FcValueListNext(v1))
+ if (FcValueEqual (FcValueCanonicalize(&v1->value),
+ FcValueCanonicalize(&v2->value)))
+ break;
+ if (v1 == NULL)
return FcFalse;
}
return FcTrue;
for (i = 0; i < os->nobject; i++)
{
- e1 = FcPatternFind (p1, os->objects[i], FcFalse);
- e2 = FcPatternFind (p2, os->objects[i], FcFalse);
+ e1 = FcPatternObjectFindElt (p1, FcObjectFromName (os->objects[i]));
+ e2 = FcPatternObjectFindElt (p2, FcObjectFromName (os->objects[i]));
if (!e1 && !e2)
- return FcTrue;
+ continue;
if (!e1 || !e2)
return FcFalse;
- if (!FcListValueListEqual (e1->values, e2->values))
+ if (!FcListValueListEqual (FcPatternEltValues(e1),
+ FcPatternEltValues(e2)))
return FcFalse;
}
return FcTrue;
}
-static FcChar32
-FcListStringHash (const FcChar8 *s)
+/*
+ * FcTrue iff all objects in "p" match "font"
+ */
+
+FcBool
+FcListPatternMatchAny (const FcPattern *p,
+ const FcPattern *font)
{
- FcChar32 h = 0;
- FcChar8 c;
+ int i;
- while ((c = *s++))
+ for (i = 0; i < p->num; i++)
{
- c = FcToLower (c);
- h = ((h << 3) ^ (h >> 3)) ^ c;
+ FcPatternElt *pe = &FcPatternElts(p)[i];
+ FcPatternElt *fe = FcPatternObjectFindElt (font, pe->object);
+ if (!fe)
+ return FcFalse;
+ if (!FcListValueListMatchAny (FcPatternEltValues(pe), /* pat elts */
+ FcPatternEltValues(fe))) /* font elts */
+ return FcFalse;
}
- return h;
+ return FcTrue;
}
static FcChar32
}
static FcChar32
-FcListValueHash (FcValue v)
+FcListValueHash (FcValue *value)
{
+ FcValue v = FcValueCanonicalize(value);
switch (v.type) {
case FcTypeVoid:
return 0;
case FcTypeDouble:
return (FcChar32) (int) v.u.d;
case FcTypeString:
- return FcListStringHash (v.u.s);
+ return FcStrHashIgnoreCase (v.u.s);
case FcTypeBool:
return (FcChar32) v.u.b;
case FcTypeMatrix:
return FcListMatrixHash (v.u.m);
case FcTypeCharSet:
return FcCharSetCount (v.u.c);
+ case FcTypeFTFace:
+ return (long) v.u.f;
+ case FcTypeLangSet:
+ return FcLangSetHash (v.u.l);
}
return 0;
}
static FcChar32
-FcListValueListHash (FcValueList *list)
+FcListValueListHash (FcValueListPtr list)
{
FcChar32 h = 0;
- while (list)
+ while (list != NULL)
{
- h = h ^ FcListValueHash (list->value);
- list = list->next;
+ h = h ^ FcListValueHash (&list->value);
+ list = FcValueListNext(list);
}
return h;
}
for (n = 0; n < os->nobject; n++)
{
- e = FcPatternFind (font, os->objects[n], FcFalse);
+ e = FcPatternObjectFindElt (font, FcObjectFromName (os->objects[n]));
if (e)
- h = h ^ FcListValueListHash (e->values);
+ h = h ^ FcListValueListHash (FcPatternEltValues(e));
}
return h;
}
table->entries = 0;
}
+static int
+FcGetDefaultObjectLangIndex (FcPattern *font, FcObject object)
+{
+ FcChar8 *lang = FcGetDefaultLang ();
+ FcPatternElt *e = FcPatternObjectFindElt (font, object);
+ FcValueListPtr v;
+ FcValue value;
+ int idx = -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 || (res == FcLangDifferentCountry && idx < 0))
+ idx = i;
+ }
+ }
+ }
+
+ return (idx > 0) ? idx : 0;
+}
+
static FcBool
FcListAppend (FcListHashTable *table,
FcPattern *font,
{
int o;
FcPatternElt *e;
- FcValueList *v;
+ FcValueListPtr v;
FcChar32 hash;
FcListBucket **prev, *bucket;
+ int familyidx = -1;
+ int fullnameidx = -1;
+ int styleidx = -1;
+ int defidx = 0;
+ int idx;
hash = FcListPatternHash (font, os);
for (prev = &table->buckets[hash % FC_LIST_HASH_SIZE];
for (o = 0; o < os->nobject; o++)
{
- e = FcPatternFind (font, os->objects[o], FcFalse);
+ if (!strcmp (os->objects[o], FC_FAMILY) || !strcmp (os->objects[o], FC_FAMILYLANG))
+ {
+ if (familyidx < 0)
+ familyidx = FcGetDefaultObjectLangIndex (font, FC_FAMILYLANG_OBJECT);
+ 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);
+ 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);
+ defidx = styleidx;
+ }
+ else
+ defidx = 0;
+
+ e = FcPatternObjectFindElt (font, FcObjectFromName (os->objects[o]));
if (e)
{
- for (v = e->values; v; v = v->next)
+ for (v = FcPatternEltValues(e), idx = 0; v;
+ v = FcValueListNext(v), ++idx)
{
if (!FcPatternAdd (bucket->pattern,
os->objects[o],
- v->value, FcTrue))
+ FcValueCanonicalize(&v->value), defidx != idx))
goto bail2;
}
}
if (!s)
continue;
for (f = 0; f < s->nfont; f++)
- if (FcListPatternMatchAny (p, s->fonts[f]))
+ if (FcListPatternMatchAny (p, /* pattern */
+ s->fonts[f])) /* font */
if (!FcListAppend (&table, s->fonts[f], os))
goto bail1;
}
sets[nsets++] = config->fonts[FcSetApplication];
return FcFontSetList (config, sets, nsets, p, os);
}
+#define __fclist__
+#include "fcaliastail.h"
+#undef __fclist__