X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffclist.c;h=d804c150386b5909c9853db9c2a88289c62df107;hb=2e44cbe1b9bf466718167e9e05077743df36ab21;hp=5468b2a619598d46164f4a3aaf2626d387d5a9cc;hpb=5b1bfa5d82aeb67056a38e93e22f69c4bfe4ce5b;p=fontconfig.git diff --git a/src/fclist.c b/src/fclist.c index 5468b2a..d804c15 100644 --- a/src/fclist.c +++ b/src/fclist.c @@ -1,7 +1,7 @@ /* - * $XFree86: xc/lib/fontconfig/src/fclist.c,v 1.4 2002/06/02 21:07:56 keithp Exp $ + * fontconfig/src/fclist.c * - * 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 @@ -13,17 +13,17 @@ * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR * 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 #include "fcint.h" +#include FcObjectSet * FcObjectSetCreate (void) @@ -67,10 +67,11 @@ FcObjectSetAdd (FcObjectSet *os, const char *object) low = 0; mid = 0; c = 1; + object = (char *)FcStrStaticName ((FcChar8 *)object); while (low <= high) { mid = (low + high) >> 1; - c = strcmp (os->objects[mid], object); + c = os->objects[mid] - object; if (c == 0) return FcTrue; if (c < 0) @@ -120,39 +121,57 @@ FcObjectSetBuild (const char *first, ...) return os; } +/* + * Font must have a containing value for every value in the pattern + */ static FcBool -FcListValueListMatchAny (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 (v2->value, FcOpContains, v1->value)) - return FcTrue; - return FcFalse; + 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, + FcOpListing, + &pat->value)) + break; + } + if (fnt == NULL) + return FcFalse; + } + return FcTrue; } static FcBool -FcListValueListEqual (FcValueList *v1orig, - FcValueList *v2orig) +FcListValueListEqual (FcValueListPtr v1orig, + FcValueListPtr v2orig) { - FcValueList *v1, *v2; + FcValueListPtr v1, v2; - for (v1 = v1orig; v1; v1 = v1->next) + for (v1 = v1orig; v1 != NULL; v1 = FcValueListNext(v1)) { - for (v2 = v2orig; v2; v2 = v2->next) - if (FcConfigCompareValue (v1->value, FcOpEqual, v2->value)) + for (v2 = v2orig; v2 != NULL; v2 = FcValueListNext(v2)) + if (FcValueEqual (FcValueCanonicalize(&(v1)->value), + FcValueCanonicalize(&(v2)->value))) break; - if (!v2) + if (v2 == NULL) return FcFalse; } - for (v2 = v2orig; v2; v2 = v2->next) + for (v2 = v2orig; v2 != NULL; v2 = FcValueListNext(v2)) { - for (v1 = v1orig; v1; v1 = v1->next) - if (FcConfigCompareValue (v1->value, FcOpEqual, v2->value)) + for (v1 = v1orig; v1 != NULL; v1 = FcValueListNext(v1)) + if (FcValueEqual (FcValueCanonicalize(&v1->value), + FcValueCanonicalize(&v2->value))) break; - if (!v1) + if (v1 == NULL) return FcFalse; } return FcTrue; @@ -168,13 +187,14 @@ FcListPatternEqual (FcPattern *p1, for (i = 0; i < os->nobject; i++) { - e1 = FcPatternFindElt (p1, os->objects[i]); - e2 = FcPatternFindElt (p2, os->objects[i]); + 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; @@ -184,38 +204,25 @@ FcListPatternEqual (FcPattern *p1, * FcTrue iff all objects in "p" match "font" */ -static FcBool -FcListPatternMatchAny (FcPattern *p, - FcPattern *font) +FcBool +FcListPatternMatchAny (const FcPattern *p, + const FcPattern *font) { int i; - FcPatternElt *e; for (i = 0; i < p->num; i++) { - e = FcPatternFindElt (font, p->elts[i].object); - if (!e) + FcPatternElt *pe = &FcPatternElts(p)[i]; + FcPatternElt *fe = FcPatternObjectFindElt (font, pe->object); + if (!fe) return FcFalse; - if (!FcListValueListMatchAny (p->elts[i].values, e->values)) + if (!FcListValueListMatchAny (FcPatternEltValues(pe), /* pat elts */ + FcPatternEltValues(fe))) /* font elts */ return FcFalse; } return FcTrue; } -static FcChar32 -FcListStringHash (const FcChar8 *s) -{ - FcChar32 h = 0; - FcChar8 c; - - while ((c = *s++)) - { - c = FcToLower (c); - h = ((h << 3) ^ (h >> 3)) ^ c; - } - return h; -} - static FcChar32 FcListMatrixHash (const FcMatrix *m) { @@ -228,8 +235,9 @@ FcListMatrixHash (const FcMatrix *m) } static FcChar32 -FcListValueHash (FcValue v) +FcListValueHash (FcValue *value) { + FcValue v = FcValueCanonicalize(value); switch (v.type) { case FcTypeVoid: return 0; @@ -238,7 +246,7 @@ FcListValueHash (FcValue v) 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: @@ -246,20 +254,22 @@ FcListValueHash (FcValue v) case FcTypeCharSet: return FcCharSetCount (v.u.c); case FcTypeFTFace: - return (FcChar32) v.u.f; + 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; } @@ -274,9 +284,9 @@ FcListPatternHash (FcPattern *font, for (n = 0; n < os->nobject; n++) { - e = FcPatternFindElt (font, os->objects[n]); + e = FcPatternObjectFindElt (font, FcObjectFromName (os->objects[n])); if (e) - h = h ^ FcListValueListHash (e->values); + h = h ^ FcListValueListHash (FcPatternEltValues(e)); } return h; } @@ -321,6 +331,37 @@ FcListHashTableCleanup (FcListHashTable *table) 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) + return i; + + if (res == FcLangDifferentCountry && idx < 0) + idx = i; + } + } + } + + return (idx > 0) ? idx : 0; +} + static FcBool FcListAppend (FcListHashTable *table, FcPattern *font, @@ -328,9 +369,14 @@ FcListAppend (FcListHashTable *table, { 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]; @@ -352,14 +398,36 @@ FcListAppend (FcListHashTable *table, for (o = 0; o < os->nobject; o++) { - e = FcPatternFindElt (font, os->objects[o]); + 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; } } @@ -392,6 +460,7 @@ FcFontSetList (FcConfig *config, FcListHashTable table; int i; FcListBucket *bucket; + int destroy_os = 0; if (!config) { @@ -403,6 +472,13 @@ FcFontSetList (FcConfig *config, goto bail0; } FcListHashTableInit (&table); + + if (!os) + { + os = FcObjectGetSet (); + destroy_os = 1; + } + /* * Walk all available fonts adding those that * match to the hash table @@ -413,7 +489,8 @@ FcFontSetList (FcConfig *config, 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; } @@ -466,6 +543,8 @@ bail2: bail1: FcListHashTableCleanup (&table); bail0: + if (destroy_os) + FcObjectSetDestroy (os); return 0; } @@ -479,6 +558,9 @@ FcFontList (FcConfig *config, if (!config) { + if (!FcInitBringUptoDate ()) + return 0; + config = FcConfigGetCurrent (); if (!config) return 0; @@ -490,3 +572,6 @@ FcFontList (FcConfig *config, sets[nsets++] = config->fonts[FcSetApplication]; return FcFontSetList (config, sets, nsets, p, os); } +#define __fclist__ +#include "fcaliastail.h" +#undef __fclist__