]>
git.wh0rd.org - fontconfig.git/blob - src/fclist.c
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
] = FcObjectStaticName (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 FcListMatrixHash (const FcMatrix
*m
)
225 int xx
= (int) (m
->xx
* 100),
226 xy
= (int) (m
->xy
* 100),
227 yx
= (int) (m
->yx
* 100),
228 yy
= (int) (m
->yy
* 100);
230 return ((FcChar32
) xx
) ^ ((FcChar32
) xy
) ^ ((FcChar32
) yx
) ^ ((FcChar32
) yy
);
234 FcListValueHash (FcValue v
)
240 return (FcChar32
) v
.u
.i
;
242 return (FcChar32
) (int) v
.u
.d
;
244 return FcStrHashIgnoreCase (v
.u
.s
);
246 return (FcChar32
) v
.u
.b
;
248 return FcListMatrixHash (v
.u
.m
);
250 return FcCharSetCount (v
.u
.c
);
254 return FcLangSetHash (v
.u
.l
);
260 FcListValueListHash (FcValueList
*list
)
266 h
= h
^ FcListValueHash (list
->value
);
273 FcListPatternHash (FcPattern
*font
,
280 for (n
= 0; n
< os
->nobject
; n
++)
282 e
= FcPatternFindElt (font
, os
->objects
[n
]);
284 h
= h
^ FcListValueListHash (e
->values
);
289 typedef struct _FcListBucket
{
290 struct _FcListBucket
*next
;
295 #define FC_LIST_HASH_SIZE 4099
297 typedef struct _FcListHashTable
{
299 FcListBucket
*buckets
[FC_LIST_HASH_SIZE
];
303 FcListHashTableInit (FcListHashTable
*table
)
306 memset (table
->buckets
, '\0', sizeof (table
->buckets
));
310 FcListHashTableCleanup (FcListHashTable
*table
)
313 FcListBucket
*bucket
, *next
;
315 for (i
= 0; i
< FC_LIST_HASH_SIZE
; i
++)
317 for (bucket
= table
->buckets
[i
]; bucket
; bucket
= next
)
320 FcPatternDestroy (bucket
->pattern
);
321 FcMemFree (FC_MEM_LISTBUCK
, sizeof (FcListBucket
));
324 table
->buckets
[i
] = 0;
330 FcListAppend (FcListHashTable
*table
,
338 FcListBucket
**prev
, *bucket
;
340 hash
= FcListPatternHash (font
, os
);
341 for (prev
= &table
->buckets
[hash
% FC_LIST_HASH_SIZE
];
342 (bucket
= *prev
); prev
= &(bucket
->next
))
344 if (bucket
->hash
== hash
&&
345 FcListPatternEqual (bucket
->pattern
, font
, os
))
348 bucket
= (FcListBucket
*) malloc (sizeof (FcListBucket
));
351 FcMemAlloc (FC_MEM_LISTBUCK
, sizeof (FcListBucket
));
354 bucket
->pattern
= FcPatternCreate ();
355 if (!bucket
->pattern
)
358 for (o
= 0; o
< os
->nobject
; o
++)
360 e
= FcPatternFindElt (font
, os
->objects
[o
]);
363 for (v
= e
->values
; v
; v
= v
->next
)
365 if (!FcPatternAdd (bucket
->pattern
,
378 FcPatternDestroy (bucket
->pattern
);
380 FcMemFree (FC_MEM_LISTBUCK
, sizeof (FcListBucket
));
387 FcFontSetList (FcConfig
*config
,
397 FcListHashTable table
;
399 FcListBucket
*bucket
;
403 if (!FcInitBringUptoDate ())
406 config
= FcConfigGetCurrent ();
410 FcListHashTableInit (&table
);
412 * Walk all available fonts adding those that
413 * match to the hash table
415 for (set
= 0; set
< nsets
; set
++)
420 for (f
= 0; f
< s
->nfont
; f
++)
421 if (FcListPatternMatchAny (p
, /* pattern */
422 s
->fonts
[f
])) /* font */
423 if (!FcListAppend (&table
, s
->fonts
[f
], os
))
432 for (i
= 0; i
< FC_LIST_HASH_SIZE
; i
++)
434 if ((bucket
= table
.buckets
[i
]))
437 for (; bucket
; bucket
= bucket
->next
)
447 printf ("used: %d max: %d avg: %g\n", full
, max
,
448 (double) ents
/ FC_LIST_HASH_SIZE
);
452 * Walk the hash table and build
455 ret
= FcFontSetCreate ();
458 for (i
= 0; i
< FC_LIST_HASH_SIZE
; i
++)
459 while ((bucket
= table
.buckets
[i
]))
461 if (!FcFontSetAdd (ret
, bucket
->pattern
))
463 table
.buckets
[i
] = bucket
->next
;
464 FcMemFree (FC_MEM_LISTBUCK
, sizeof (FcListBucket
));
471 FcFontSetDestroy (ret
);
473 FcListHashTableCleanup (&table
);
479 FcFontList (FcConfig
*config
,
488 config
= FcConfigGetCurrent ();
493 if (config
->fonts
[FcSetSystem
])
494 sets
[nsets
++] = config
->fonts
[FcSetSystem
];
495 if (config
->fonts
[FcSetApplication
])
496 sets
[nsets
++] = config
->fonts
[FcSetApplication
];
497 return FcFontSetList (config
, sets
, nsets
, p
, os
);