]>
git.wh0rd.org - fontconfig.git/blob - src/fclist.c
2 * fontconfig/src/fclist.c
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;
70 object
= (char *)FcStrStaticName ((FcChar8
*)object
);
73 mid
= (low
+ high
) >> 1;
74 c
= os
->objects
[mid
] - object
;
84 memmove (os
->objects
+ mid
+ 1, os
->objects
+ mid
,
85 (os
->nobject
- mid
) * sizeof (const char *));
86 os
->objects
[mid
] = object
;
92 FcObjectSetDestroy (FcObjectSet
*os
)
96 FcMemFree (FC_MEM_OBJECTPTR
, os
->sobject
* sizeof (const char *));
97 free ((void *) os
->objects
);
99 FcMemFree (FC_MEM_OBJECTSET
, sizeof (FcObjectSet
));
104 FcObjectSetVaBuild (const char *first
, va_list va
)
108 FcObjectSetVapBuild (ret
, first
, va
);
113 FcObjectSetBuild (const char *first
, ...)
118 va_start (va
, first
);
119 FcObjectSetVapBuild (os
, first
, va
);
125 * Font must have a containing value for every value in the pattern
128 FcListValueListMatchAny (FcValueListPtr patOrig
, /* pattern */
129 FcValueListPtr fntOrig
) /* font */
131 FcValueListPtr pat
, fnt
;
133 for (pat
= patOrig
; pat
!= NULL
; pat
= FcValueListNext(pat
))
135 for (fnt
= fntOrig
; fnt
!= NULL
; fnt
= FcValueListNext(fnt
))
138 * make sure the font 'contains' the pattern.
139 * (OpListing is OpContains except for strings
140 * where it requires an exact match)
142 if (FcConfigCompareValue (&fnt
->value
,
154 FcListValueListEqual (FcValueListPtr v1orig
,
155 FcValueListPtr v2orig
)
157 FcValueListPtr v1
, v2
;
159 for (v1
= v1orig
; v1
!= NULL
; v1
= FcValueListNext(v1
))
161 for (v2
= v2orig
; v2
!= NULL
; v2
= FcValueListNext(v2
))
162 if (FcValueEqual (FcValueCanonicalize(&(v1
)->value
),
163 FcValueCanonicalize(&(v2
)->value
)))
168 for (v2
= v2orig
; v2
!= NULL
; v2
= FcValueListNext(v2
))
170 for (v1
= v1orig
; v1
!= NULL
; v1
= FcValueListNext(v1
))
171 if (FcValueEqual (FcValueCanonicalize(&v1
->value
),
172 FcValueCanonicalize(&v2
->value
)))
181 FcListPatternEqual (FcPattern
*p1
,
186 FcPatternElt
*e1
, *e2
;
188 for (i
= 0; i
< os
->nobject
; i
++)
190 e1
= FcPatternObjectFindElt (p1
, FcObjectFromName (os
->objects
[i
]));
191 e2
= FcPatternObjectFindElt (p2
, FcObjectFromName (os
->objects
[i
]));
196 if (!FcListValueListEqual (FcPatternEltValues(e1
),
197 FcPatternEltValues(e2
)))
204 * FcTrue iff all objects in "p" match "font"
208 FcListPatternMatchAny (const FcPattern
*p
,
209 const FcPattern
*font
)
213 for (i
= 0; i
< p
->num
; i
++)
215 FcPatternElt
*pe
= &FcPatternElts(p
)[i
];
216 FcPatternElt
*fe
= FcPatternObjectFindElt (font
, pe
->object
);
219 if (!FcListValueListMatchAny (FcPatternEltValues(pe
), /* pat elts */
220 FcPatternEltValues(fe
))) /* font elts */
227 FcListMatrixHash (const FcMatrix
*m
)
229 int xx
= (int) (m
->xx
* 100),
230 xy
= (int) (m
->xy
* 100),
231 yx
= (int) (m
->yx
* 100),
232 yy
= (int) (m
->yy
* 100);
234 return ((FcChar32
) xx
) ^ ((FcChar32
) xy
) ^ ((FcChar32
) yx
) ^ ((FcChar32
) yy
);
238 FcListValueHash (FcValue
*value
)
240 FcValue v
= FcValueCanonicalize(value
);
245 return (FcChar32
) v
.u
.i
;
247 return (FcChar32
) (int) v
.u
.d
;
249 return FcStrHashIgnoreCase (v
.u
.s
);
251 return (FcChar32
) v
.u
.b
;
253 return FcListMatrixHash (v
.u
.m
);
255 return FcCharSetCount (v
.u
.c
);
259 return FcLangSetHash (v
.u
.l
);
265 FcListValueListHash (FcValueListPtr list
)
271 h
= h
^ FcListValueHash (&list
->value
);
272 list
= FcValueListNext(list
);
278 FcListPatternHash (FcPattern
*font
,
285 for (n
= 0; n
< os
->nobject
; n
++)
287 e
= FcPatternObjectFindElt (font
, FcObjectFromName (os
->objects
[n
]));
289 h
= h
^ FcListValueListHash (FcPatternEltValues(e
));
294 typedef struct _FcListBucket
{
295 struct _FcListBucket
*next
;
300 #define FC_LIST_HASH_SIZE 4099
302 typedef struct _FcListHashTable
{
304 FcListBucket
*buckets
[FC_LIST_HASH_SIZE
];
308 FcListHashTableInit (FcListHashTable
*table
)
311 memset (table
->buckets
, '\0', sizeof (table
->buckets
));
315 FcListHashTableCleanup (FcListHashTable
*table
)
318 FcListBucket
*bucket
, *next
;
320 for (i
= 0; i
< FC_LIST_HASH_SIZE
; i
++)
322 for (bucket
= table
->buckets
[i
]; bucket
; bucket
= next
)
325 FcPatternDestroy (bucket
->pattern
);
326 FcMemFree (FC_MEM_LISTBUCK
, sizeof (FcListBucket
));
329 table
->buckets
[i
] = 0;
335 FcGetDefaultObjectLangIndex (FcPattern
*font
, FcObject object
)
337 FcChar8
*lang
= FcGetDefaultLang ();
338 FcPatternElt
*e
= FcPatternObjectFindElt (font
, object
);
346 for (v
= FcPatternEltValues(e
), i
= 0; v
; v
= FcValueListNext(v
), ++i
)
348 value
= FcValueCanonicalize (&v
->value
);
350 if (value
.type
== FcTypeString
)
352 FcLangResult res
= FcLangCompare (value
.u
.s
, lang
);
353 if (res
== FcLangEqual
|| (res
== FcLangDifferentCountry
&& idx
< 0))
359 return (idx
> 0) ? idx
: 0;
363 FcListAppend (FcListHashTable
*table
,
371 FcListBucket
**prev
, *bucket
;
373 int fullnameidx
= -1;
378 hash
= FcListPatternHash (font
, os
);
379 for (prev
= &table
->buckets
[hash
% FC_LIST_HASH_SIZE
];
380 (bucket
= *prev
); prev
= &(bucket
->next
))
382 if (bucket
->hash
== hash
&&
383 FcListPatternEqual (bucket
->pattern
, font
, os
))
386 bucket
= (FcListBucket
*) malloc (sizeof (FcListBucket
));
389 FcMemAlloc (FC_MEM_LISTBUCK
, sizeof (FcListBucket
));
392 bucket
->pattern
= FcPatternCreate ();
393 if (!bucket
->pattern
)
396 for (o
= 0; o
< os
->nobject
; o
++)
398 if (!strcmp (os
->objects
[o
], FC_FAMILY
) || !strcmp (os
->objects
[o
], FC_FAMILYLANG
))
401 familyidx
= FcGetDefaultObjectLangIndex (font
, FC_FAMILYLANG_OBJECT
);
404 else if (!strcmp (os
->objects
[o
], FC_FULLNAME
) || !strcmp (os
->objects
[o
], FC_FULLNAMELANG
))
407 fullnameidx
= FcGetDefaultObjectLangIndex (font
, FC_FULLNAMELANG_OBJECT
);
408 defidx
= fullnameidx
;
410 else if (!strcmp (os
->objects
[o
], FC_STYLE
) || !strcmp (os
->objects
[o
], FC_STYLELANG
))
413 styleidx
= FcGetDefaultObjectLangIndex (font
, FC_STYLELANG_OBJECT
);
419 e
= FcPatternObjectFindElt (font
, FcObjectFromName (os
->objects
[o
]));
422 for (v
= FcPatternEltValues(e
), idx
= 0; v
;
423 v
= FcValueListNext(v
), ++idx
)
425 if (!FcPatternAdd (bucket
->pattern
,
427 FcValueCanonicalize(&v
->value
), defidx
!= idx
))
438 FcPatternDestroy (bucket
->pattern
);
440 FcMemFree (FC_MEM_LISTBUCK
, sizeof (FcListBucket
));
447 FcFontSetList (FcConfig
*config
,
457 FcListHashTable table
;
459 FcListBucket
*bucket
;
464 if (!FcInitBringUptoDate ())
467 config
= FcConfigGetCurrent ();
471 FcListHashTableInit (&table
);
475 os
= FcObjectGetSet ();
480 * Walk all available fonts adding those that
481 * match to the hash table
483 for (set
= 0; set
< nsets
; set
++)
488 for (f
= 0; f
< s
->nfont
; f
++)
489 if (FcListPatternMatchAny (p
, /* pattern */
490 s
->fonts
[f
])) /* font */
491 if (!FcListAppend (&table
, s
->fonts
[f
], os
))
500 for (i
= 0; i
< FC_LIST_HASH_SIZE
; i
++)
502 if ((bucket
= table
.buckets
[i
]))
505 for (; bucket
; bucket
= bucket
->next
)
515 printf ("used: %d max: %d avg: %g\n", full
, max
,
516 (double) ents
/ FC_LIST_HASH_SIZE
);
520 * Walk the hash table and build
523 ret
= FcFontSetCreate ();
526 for (i
= 0; i
< FC_LIST_HASH_SIZE
; i
++)
527 while ((bucket
= table
.buckets
[i
]))
529 if (!FcFontSetAdd (ret
, bucket
->pattern
))
531 table
.buckets
[i
] = bucket
->next
;
532 FcMemFree (FC_MEM_LISTBUCK
, sizeof (FcListBucket
));
539 FcFontSetDestroy (ret
);
541 FcListHashTableCleanup (&table
);
544 FcObjectSetDestroy (os
);
549 FcFontList (FcConfig
*config
,
558 if (!FcInitBringUptoDate ())
561 config
= FcConfigGetCurrent ();
566 if (config
->fonts
[FcSetSystem
])
567 sets
[nsets
++] = config
->fonts
[FcSetSystem
];
568 if (config
->fonts
[FcSetApplication
])
569 sets
[nsets
++] = config
->fonts
[FcSetApplication
];
570 return FcFontSetList (config
, sets
, nsets
, p
, os
);
573 #include "fcaliastail.h"