]>
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.
26 #include <sys/types.h>
32 FcObjectSetCreate (void)
36 os
= (FcObjectSet
*) malloc (sizeof (FcObjectSet
));
39 FcMemAlloc (FC_MEM_OBJECTSET
, sizeof (FcObjectSet
));
47 FcObjectSetAdd (FcObjectSet
*os
, const char *object
)
52 int high
, low
, mid
, c
;
54 if (os
->nobject
== os
->sobject
)
58 objects
= (FcObjectPtr
*) realloc ((void *) os
->objects
,
59 s
* sizeof (FcObjectPtr
));
61 objects
= (FcObjectPtr
*) malloc (s
* sizeof (FcObjectPtr
));
65 FcMemFree (FC_MEM_OBJECTPTR
, os
->sobject
* sizeof (const char *));
66 FcMemAlloc (FC_MEM_OBJECTPTR
, s
* sizeof (const char *));
67 os
->objects
= objects
;
70 high
= os
->nobject
- 1;
74 obj
= FcObjectStaticName (object
);
77 mid
= (low
+ high
) >> 1;
78 c
= FcObjectPtrCompare(os
->objects
[mid
], obj
);
88 memmove (os
->objects
+ mid
+ 1, os
->objects
+ mid
,
89 (os
->nobject
- mid
) * sizeof (FcObjectPtr
));
90 os
->objects
[mid
] = obj
;
96 FcObjectSetDestroy (FcObjectSet
*os
)
100 FcMemFree (FC_MEM_OBJECTPTR
, os
->sobject
* sizeof (const char *));
101 free ((void *) os
->objects
);
103 FcMemFree (FC_MEM_OBJECTSET
, sizeof (FcObjectSet
));
108 FcObjectSetVaBuild (const char *first
, va_list va
)
112 FcObjectSetVapBuild (ret
, first
, va
);
117 FcObjectSetBuild (const char *first
, ...)
122 va_start (va
, first
);
123 FcObjectSetVapBuild (os
, first
, va
);
129 * Font must have a containing value for every value in the pattern
132 FcListValueListMatchAny (FcValueListPtr patOrig
, /* pattern */
133 FcValueListPtr fntOrig
) /* font */
135 FcValueListPtr pat
, fnt
;
137 for (pat
= patOrig
; FcValueListPtrU(pat
);
138 pat
= FcValueListPtrU(pat
)->next
)
140 for (fnt
= fntOrig
; FcValueListPtrU(fnt
);
141 fnt
= FcValueListPtrU(fnt
)->next
)
144 * make sure the font 'contains' the pattern.
145 * (OpListing is OpContains except for strings
146 * where it requires an exact match)
148 if (FcConfigCompareValue (FcValueListPtrU(fnt
)->value
,
150 FcValueListPtrU(pat
)->value
))
153 if (!FcValueListPtrU(fnt
))
160 FcListValueListEqual (FcValueListPtr v1orig
,
161 FcValueListPtr v2orig
)
163 FcValueListPtr v1
, v2
;
165 for (v1
= v1orig
; FcValueListPtrU(v1
);
166 v1
= FcValueListPtrU(v1
)->next
)
168 for (v2
= v2orig
; FcValueListPtrU(v2
);
169 v2
= FcValueListPtrU(v2
)->next
)
170 if (FcValueEqual (FcValueListPtrU(v1
)->value
,
171 FcValueListPtrU(v2
)->value
))
173 if (!FcValueListPtrU(v2
))
176 for (v2
= v2orig
; FcValueListPtrU(v2
);
177 v2
= FcValueListPtrU(v2
)->next
)
179 for (v1
= v1orig
; FcValueListPtrU(v1
);
180 v1
= FcValueListPtrU(v1
)->next
)
181 if (FcValueEqual (FcValueListPtrU(v1
)->value
,
182 FcValueListPtrU(v2
)->value
))
184 if (!FcValueListPtrU(v1
))
191 FcListPatternEqual (FcPattern
*p1
,
196 FcPatternElt
*e1
, *e2
;
198 for (i
= 0; i
< os
->nobject
; i
++)
200 e1
= FcPatternFindElt (p1
, FcObjectPtrU(os
->objects
[i
]));
201 e2
= FcPatternFindElt (p2
, FcObjectPtrU(os
->objects
[i
]));
206 if (!FcListValueListEqual (e1
->values
, e2
->values
))
213 * FcTrue iff all objects in "p" match "font"
217 FcListPatternMatchAny (const FcPattern
*p
,
218 const FcPattern
*font
)
223 for (i
= 0; i
< p
->num
; i
++)
225 e
= FcPatternFindElt (font
,
226 FcObjectPtrU((FcPatternEltU(p
->elts
)+i
)->object
));
229 if (!FcListValueListMatchAny ((FcPatternEltU(p
->elts
)+i
)->values
, /* pat elts */
230 e
->values
)) /* font elts */
237 FcListMatrixHash (const FcMatrix
*m
)
239 int xx
= (int) (m
->xx
* 100),
240 xy
= (int) (m
->xy
* 100),
241 yx
= (int) (m
->yx
* 100),
242 yy
= (int) (m
->yy
* 100);
244 return ((FcChar32
) xx
) ^ ((FcChar32
) xy
) ^ ((FcChar32
) yx
) ^ ((FcChar32
) yy
);
248 FcListValueHash (FcValue v
)
254 return (FcChar32
) v
.u
.i
;
256 return (FcChar32
) (int) v
.u
.d
;
258 return FcStrHashIgnoreCase (FcObjectPtrU(v
.u
.si
));
260 return (FcChar32
) v
.u
.b
;
262 return FcListMatrixHash (FcMatrixPtrU(v
.u
.mi
));
264 return FcCharSetCount (FcCharSetPtrU(v
.u
.ci
));
268 return FcLangSetHash (FcLangSetPtrU(v
.u
.li
));
274 FcListValueListHash (FcValueListPtr list
)
278 while (FcValueListPtrU(list
))
280 h
= h
^ FcListValueHash (FcValueListPtrU(list
)->value
);
281 list
= FcValueListPtrU(list
)->next
;
287 FcListPatternHash (FcPattern
*font
,
294 for (n
= 0; n
< os
->nobject
; n
++)
296 e
= FcPatternFindElt (font
, FcObjectPtrU(os
->objects
[n
]));
298 h
= h
^ FcListValueListHash (e
->values
);
303 typedef struct _FcListBucket
{
304 struct _FcListBucket
*next
;
309 #define FC_LIST_HASH_SIZE 4099
311 typedef struct _FcListHashTable
{
313 FcListBucket
*buckets
[FC_LIST_HASH_SIZE
];
317 FcListHashTableInit (FcListHashTable
*table
)
320 memset (table
->buckets
, '\0', sizeof (table
->buckets
));
324 FcListHashTableCleanup (FcListHashTable
*table
)
327 FcListBucket
*bucket
, *next
;
329 for (i
= 0; i
< FC_LIST_HASH_SIZE
; i
++)
331 for (bucket
= table
->buckets
[i
]; bucket
; bucket
= next
)
334 FcPatternDestroy (bucket
->pattern
);
335 FcMemFree (FC_MEM_LISTBUCK
, sizeof (FcListBucket
));
338 table
->buckets
[i
] = 0;
344 FcListAppend (FcListHashTable
*table
,
352 FcListBucket
**prev
, *bucket
;
354 hash
= FcListPatternHash (font
, os
);
355 for (prev
= &table
->buckets
[hash
% FC_LIST_HASH_SIZE
];
356 (bucket
= *prev
); prev
= &(bucket
->next
))
358 if (bucket
->hash
== hash
&&
359 FcListPatternEqual (bucket
->pattern
, font
, os
))
362 bucket
= (FcListBucket
*) malloc (sizeof (FcListBucket
));
365 FcMemAlloc (FC_MEM_LISTBUCK
, sizeof (FcListBucket
));
368 bucket
->pattern
= FcPatternCreate ();
369 if (!bucket
->pattern
)
372 for (o
= 0; o
< os
->nobject
; o
++)
374 e
= FcPatternFindElt (font
, FcObjectPtrU(os
->objects
[o
]));
377 for (v
= e
->values
; FcValueListPtrU(v
);
378 v
= FcValueListPtrU(v
)->next
)
380 if (!FcPatternAdd (bucket
->pattern
,
381 FcObjectPtrU(os
->objects
[o
]),
382 FcValueListPtrU(v
)->value
, FcTrue
))
393 FcPatternDestroy (bucket
->pattern
);
395 FcMemFree (FC_MEM_LISTBUCK
, sizeof (FcListBucket
));
402 FcFontSetList (FcConfig
*config
,
412 FcListHashTable table
;
414 FcListBucket
*bucket
;
418 if (!FcInitBringUptoDate ())
421 config
= FcConfigGetCurrent ();
425 FcListHashTableInit (&table
);
427 * Walk all available fonts adding those that
428 * match to the hash table
430 for (set
= 0; set
< nsets
; set
++)
435 for (f
= 0; f
< s
->nfont
; f
++)
436 if (FcListPatternMatchAny (p
, /* pattern */
437 s
->fonts
[f
])) /* font */
438 if (!FcListAppend (&table
, s
->fonts
[f
], os
))
447 for (i
= 0; i
< FC_LIST_HASH_SIZE
; i
++)
449 if ((bucket
= table
.buckets
[i
]))
452 for (; bucket
; bucket
= bucket
->next
)
462 printf ("used: %d max: %d avg: %g\n", full
, max
,
463 (double) ents
/ FC_LIST_HASH_SIZE
);
467 * Walk the hash table and build
470 ret
= FcFontSetCreate ();
473 for (i
= 0; i
< FC_LIST_HASH_SIZE
; i
++)
474 while ((bucket
= table
.buckets
[i
]))
476 if (!FcFontSetAdd (ret
, bucket
->pattern
))
478 table
.buckets
[i
] = bucket
->next
;
479 FcMemFree (FC_MEM_LISTBUCK
, sizeof (FcListBucket
));
486 FcFontSetDestroy (ret
);
488 FcListHashTableCleanup (&table
);
494 FcFontList (FcConfig
*config
,
503 config
= FcConfigGetCurrent ();
508 if (config
->fonts
[FcSetSystem
])
509 sets
[nsets
++] = config
->fonts
[FcSetSystem
];
510 if (config
->fonts
[FcSetApplication
])
511 sets
[nsets
++] = config
->fonts
[FcSetApplication
];
512 return FcFontSetList (config
, sets
, nsets
, p
, os
);