2 * $RCSId: xc/lib/fontconfig/src/fcpat.c,v 1.18 2002/09/18 17:11:46 tsi 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.
30 static FcPattern
** fcpatterns
= 0;
31 static int fcpattern_bank_count
= 0, fcpattern_ptr
, fcpattern_count
;
32 static FcPatternElt
** fcpatternelts
= 0;
33 static int fcpatternelt_ptr
, fcpatternelt_count
;
34 static FcValueList
** fcvaluelists
= 0;
35 static int fcvaluelist_bank_count
= 0, fcvaluelist_ptr
, fcvaluelist_count
;
37 static FcPatternEltPtr
38 FcPatternEltPtrCreateDynamic (FcPatternElt
* e
);
41 FcPatternCreate (void)
45 p
= (FcPattern
*) malloc (sizeof (FcPattern
));
48 FcMemAlloc (FC_MEM_PATTERN
, sizeof (FcPattern
));
51 p
->elts
= FcPatternEltPtrCreateDynamic(0);
52 p
->bank
= FC_BANK_DYNAMIC
;
58 FcValueDestroy (FcValue v
)
62 FcStrFree ((FcChar8
*) v
.u
.s
);
65 FcMatrixFree ((FcMatrix
*) v
.u
.m
);
68 FcCharSetDestroy ((FcCharSet
*) v
.u
.c
);
71 FcLangSetDestroy ((FcLangSet
*) v
.u
.l
);
79 FcValueCanonicalize (const FcValue
*v
)
81 if (v
->type
& FC_STORAGE_STATIC
)
85 switch (v
->type
& ~FC_STORAGE_STATIC
)
88 new.u
.s
= fc_value_string(v
);
89 new.type
= FcTypeString
;
92 new.u
.c
= fc_value_charset(v
);
93 new.type
= FcTypeCharSet
;
96 new.u
.l
= fc_value_langset(v
);
97 new.type
= FcTypeLangSet
;
106 FcValueSave (FcValue v
)
110 v
.u
.s
= FcStrCopy (v
.u
.s
);
115 v
.u
.m
= FcMatrixCopy (v
.u
.m
);
120 v
.u
.c
= FcCharSetCopy ((FcCharSet
*) v
.u
.c
);
125 v
.u
.l
= FcLangSetCopy (v
.u
.l
);
136 FcValueListDestroy (FcValueListPtr l
)
139 for (; FcValueListPtrU(l
); l
= next
)
141 switch (FcValueListPtrU(l
)->value
.type
) {
143 FcStrFree ((FcChar8
*)FcValueListPtrU(l
)->value
.u
.s
);
146 FcMatrixFree ((FcMatrix
*)FcValueListPtrU(l
)->value
.u
.m
);
150 ((FcCharSet
*) (FcValueListPtrU(l
)->value
.u
.c
));
154 ((FcLangSet
*) (FcValueListPtrU(l
)->value
.u
.l
));
159 next
= FcValueListPtrU(l
)->next
;
160 FcMemFree (FC_MEM_VALLIST
, sizeof (FcValueList
));
161 if (l
.bank
== FC_BANK_DYNAMIC
)
167 FcValueEqual (FcValue va
, FcValue vb
)
169 if (va
.type
!= vb
.type
)
171 if (va
.type
== FcTypeInteger
)
173 va
.type
= FcTypeDouble
;
176 if (vb
.type
== FcTypeInteger
)
178 vb
.type
= FcTypeDouble
;
181 if (va
.type
!= vb
.type
)
188 return va
.u
.i
== vb
.u
.i
;
190 return va
.u
.d
== vb
.u
.d
;
192 return FcStrCmpIgnoreCase (va
.u
.s
, vb
.u
.s
) == 0;
194 return va
.u
.b
== vb
.u
.b
;
196 return FcMatrixEqual (va
.u
.m
, vb
.u
.m
);
198 return FcCharSetEqual (va
.u
.c
, vb
.u
.c
);
200 return va
.u
.f
== vb
.u
.f
;
202 return FcLangSetEqual (va
.u
.l
, vb
.u
.l
);
208 FcDoubleHash (double d
)
218 FcStringHash (const FcChar8
*s
)
225 h
= ((h
<< 1) | (h
>> 31)) ^ c
;
230 FcValueHash (const FcValue
*v0
)
232 FcValue v
= FcValueCanonicalize(v0
);
237 return (FcChar32
) v
.u
.i
;
239 return FcDoubleHash (v
.u
.d
);
241 return FcStringHash (v
.u
.s
);
243 return (FcChar32
) v
.u
.b
;
245 return (FcDoubleHash (v
.u
.m
->xx
) ^
246 FcDoubleHash (v
.u
.m
->xy
) ^
247 FcDoubleHash (v
.u
.m
->yx
) ^
248 FcDoubleHash (v
.u
.m
->yy
));
250 return (FcChar32
) v
.u
.c
->num
;
252 return FcStringHash ((const FcChar8
*) ((FT_Face
) v
.u
.f
)->family_name
) ^
253 FcStringHash ((const FcChar8
*) ((FT_Face
) v
.u
.f
)->style_name
);
255 return FcLangSetHash (v
.u
.l
);
261 FcValueListEqual (FcValueListPtr la
, FcValueListPtr lb
)
263 if (FcValueListPtrU(la
) == FcValueListPtrU(lb
))
266 while (FcValueListPtrU(la
) && FcValueListPtrU(lb
))
268 if (!FcValueEqual (FcValueListPtrU(la
)->value
,
269 FcValueListPtrU(lb
)->value
))
271 la
= FcValueListPtrU(la
)->next
;
272 lb
= FcValueListPtrU(lb
)->next
;
274 if (FcValueListPtrU(la
) || FcValueListPtrU(lb
))
280 FcValueListHash (FcValueListPtr l
)
284 while (FcValueListPtrU(l
))
286 hash
= ((hash
<< 1) | (hash
>> 31)) ^
287 FcValueHash (&FcValueListPtrU(l
)->value
);
288 l
= FcValueListPtrU(l
)->next
;
294 FcPatternDestroy (FcPattern
*p
)
298 if (FcPatternFindFullFname (p
))
299 FcPatternAddFullFname (p
, 0);
301 if (p
->ref
== FC_REF_CONSTANT
|| --p
->ref
> 0)
304 for (i
= 0; i
< p
->num
; i
++)
305 FcValueListDestroy ((FcPatternEltU(p
->elts
)+i
)->values
);
308 if (FcPatternEltU(p
->elts
) && p
->elts
.bank
== FC_BANK_DYNAMIC
)
310 FcMemFree (FC_MEM_PATELT
, p
->size
* sizeof (FcPatternElt
));
311 free (FcPatternEltU(p
->elts
));
312 p
->elts
= FcPatternEltPtrCreateDynamic(0);
315 FcMemFree (FC_MEM_PATTERN
, sizeof (FcPattern
));
319 #define FC_VALUE_LIST_HASH_SIZE 257
320 #define FC_PATTERN_HASH_SIZE 67
322 typedef struct _FcValueListEnt FcValueListEnt
;
324 struct _FcValueListEnt
{
325 FcValueListEnt
*next
;
330 typedef union _FcValueListAlign
{
335 static int FcValueListFrozenCount
[FcTypeLangSet
+ 1];
336 static int FcValueListFrozenBytes
[FcTypeLangSet
+ 1];
337 static char FcValueListFrozenName
[][8] = {
350 FcValueListReport (void);
353 FcValueListReport (void)
357 printf ("Fc Frozen Values:\n");
358 printf ("\t%8s %9s %9s\n", "Type", "Count", "Bytes");
359 for (t
= FcTypeVoid
; t
<= FcTypeLangSet
; t
++)
360 printf ("\t%8s %9d %9d\n", FcValueListFrozenName
[t
],
361 FcValueListFrozenCount
[t
], FcValueListFrozenBytes
[t
]);
364 static FcValueListEnt
*
365 FcValueListEntCreate (FcValueListPtr h
)
367 FcValueListAlign
*ea
;
375 for (l
= h
; FcValueListPtrU(l
); l
= FcValueListPtrU(l
)->next
)
377 size
= sizeof (FcValueListAlign
) + n
* sizeof (FcValueList
);
378 FcValueListFrozenCount
[FcValueListPtrU(h
)->value
.type
]++;
379 FcValueListFrozenBytes
[FcValueListPtrU(h
)->value
.type
] += size
;
380 // this leaks for some reason
381 ea
= malloc (sizeof (FcValueListAlign
));
384 new = malloc (n
* sizeof (FcValueList
));
387 memset(new, 0, n
* sizeof (FcValueList
));
388 FcMemAlloc (FC_MEM_VALLIST
, size
);
390 e
->list
= (FcValueListPtr
) FcValueListPtrCreateDynamic(new);
391 for (l
= h
; FcValueListPtrU(l
);
392 l
= FcValueListPtrU(l
)->next
, new++)
394 if ((FcValueListPtrU(l
)->value
.type
& ~FC_STORAGE_STATIC
) == FcTypeString
)
396 new->value
.type
= FcTypeString
;
397 new->value
.u
.s
= FcStrStaticName
398 (fc_value_string(&FcValueListPtrU(l
)->value
));
402 new->value
= FcValueSave (FcValueCanonicalize
403 (&FcValueListPtrU(l
)->value
));
405 new->binding
= FcValueListPtrU(l
)->binding
;
406 if (FcValueListPtrU(FcValueListPtrU(l
)->next
))
408 new->next
= FcValueListPtrCreateDynamic(new + 1);
412 new->next
= FcValueListPtrCreateDynamic(0);
419 FcValueListEntDestroy (FcValueListEnt
*e
)
423 FcValueListFrozenCount
[FcValueListPtrU(e
->list
)->value
.type
]--;
425 /* XXX: We should perform these two operations with "size" as
426 computed in FcValueListEntCreate, but we don't have access to
427 that value here. Without this, the FcValueListFrozenBytes
428 values will be wrong as will the FcMemFree counts.
430 FcValueListFrozenBytes[e->list->value.type] -= size;
431 FcMemFree (FC_MEM_VALLIST, size);
434 for (l
= e
->list
; FcValueListPtrU(l
);
435 l
= FcValueListPtrU(l
)->next
)
437 if (FcValueListPtrU(l
)->value
.type
!= FcTypeString
)
438 FcValueDestroy (FcValueListPtrU(l
)->value
);
440 /* XXX: Are we being too chummy with the implementation here to
441 free(e) when it was actually the enclosing FcValueListAlign
442 that was allocated? */
446 static int FcValueListTotal
;
447 static int FcValueListUsed
;
449 static FcValueListEnt
*FcValueListHashTable
[FC_VALUE_LIST_HASH_SIZE
];
451 static FcValueListPtr
452 FcValueListFreeze (FcValueListPtr l
)
454 FcChar32 hash
= FcValueListHash (l
);
455 FcValueListEnt
**bucket
= &FcValueListHashTable
[hash
% FC_VALUE_LIST_HASH_SIZE
];
459 for (ent
= *bucket
; ent
; ent
= ent
->next
)
461 if (ent
->hash
== hash
&& FcValueListEqual (ent
->list
, l
))
465 ent
= FcValueListEntCreate (l
);
467 return FcValueListPtrCreateDynamic(0);
477 FcValueListThawAll (void)
480 FcValueListEnt
*ent
, *next
;
482 for (i
= 0; i
< FC_VALUE_LIST_HASH_SIZE
; i
++)
484 for (ent
= FcValueListHashTable
[i
]; ent
; ent
= next
)
487 FcValueListEntDestroy (ent
);
489 FcValueListHashTable
[i
] = 0;
492 FcValueListTotal
= 0;
497 FcPatternBaseHash (FcPattern
*b
)
499 FcChar32 hash
= b
->num
;
502 for (i
= 0; i
< b
->num
; i
++)
503 hash
= ((hash
<< 1) | (hash
>> 31)) ^
504 (long) (FcValueListPtrU((FcPatternEltU(b
->elts
)+i
)->values
));
508 typedef struct _FcPatternEnt FcPatternEnt
;
510 struct _FcPatternEnt
{
516 static int FcPatternTotal
;
517 static int FcPatternUsed
;
519 static FcPatternEnt
*FcPatternHashTable
[FC_VALUE_LIST_HASH_SIZE
];
522 FcPatternBaseFreeze (FcPattern
*b
)
526 FcChar32 hash
= FcPatternBaseHash (b
);
527 FcPatternEnt
**bucket
= &FcPatternHashTable
[hash
% FC_VALUE_LIST_HASH_SIZE
];
532 for (ent
= *bucket
; ent
; ent
= ent
->next
)
534 if (ent
->hash
== hash
&& b
->num
== ent
->pattern
->num
)
536 for (i
= 0; i
< b
->num
; i
++)
538 if (FcObjectPtrCompare((FcPatternEltU(b
->elts
)+i
)->object
,
539 (FcPatternEltU(ent
->pattern
->elts
)+i
)->object
) != 0)
541 if (FcValueListPtrU((FcPatternEltU(b
->elts
)+i
)->values
) !=
542 FcValueListPtrU((FcPatternEltU(ent
->pattern
->elts
)+i
)->values
))
551 * Compute size of pattern + elts
553 ent
= malloc (sizeof (FcPatternEnt
));
557 FcMemAlloc (FC_MEM_PATTERN
, sizeof (FcPatternEnt
));
560 ep
= FcPatternCreate();
564 epp
= malloc(b
->num
* sizeof (FcPatternElt
));
567 ep
->elts
= FcPatternEltPtrCreateDynamic(epp
);
569 FcMemAlloc (FC_MEM_PATELT
, sizeof (FcPatternElt
)*(b
->num
));
573 ep
->ref
= FC_REF_CONSTANT
;
575 for (i
= 0; i
< b
->num
; i
++)
577 (FcPatternEltU(ep
->elts
)+i
)->values
=
578 (FcPatternEltU(b
->elts
)+i
)->values
;
579 (FcPatternEltU(ep
->elts
)+i
)->object
=
580 (FcPatternEltU(b
->elts
)+i
)->object
;
589 FcMemFree (FC_MEM_PATTERN
, sizeof (FcPatternEnt
));
595 FcPatternBaseThawAll (void)
598 FcPatternEnt
*ent
, *next
;
600 for (i
= 0; i
< FC_VALUE_LIST_HASH_SIZE
; i
++)
602 for (ent
= FcPatternHashTable
[i
]; ent
; ent
= next
)
607 FcPatternHashTable
[i
] = 0;
615 FcPatternFreeze (FcPattern
*p
)
617 FcPattern
*b
, *n
= 0;
621 if (p
->ref
== FC_REF_CONSTANT
)
624 b
= FcPatternCreate();
632 e
= malloc(b
->num
* sizeof (FcPatternElt
));
635 b
->elts
= FcPatternEltPtrCreateDynamic(e
);
636 FcMemAlloc (FC_MEM_PATELT
, sizeof (FcPatternElt
)*(b
->num
));
639 * Freeze object lists
641 for (i
= 0; i
< p
->num
; i
++)
643 (FcPatternEltU(b
->elts
)+i
)->object
=
644 (FcPatternEltU(p
->elts
)+i
)->object
;
645 (FcPatternEltU(b
->elts
)+i
)->values
=
646 FcValueListFreeze((FcPatternEltU(p
->elts
)+i
)->values
);
647 if (!FcValueListPtrU((FcPatternEltU(p
->elts
)+i
)->values
))
653 n
= FcPatternBaseFreeze (b
);
655 if (FcDebug() & FC_DBG_MEMORY
)
657 printf ("ValueLists: total %9d used %9d\n", FcValueListTotal
, FcValueListUsed
);
658 printf ("Patterns: total %9d used %9d\n", FcPatternTotal
, FcPatternUsed
);
662 free(FcPatternEltU(b
->elts
));
663 b
->elts
= FcPatternEltPtrCreateDynamic(0);
664 FcMemFree (FC_MEM_PATELT
, sizeof (FcPatternElt
)*(b
->num
));
667 assert (FcPatternEqual (n
, p
));
673 FcPatternPosition (const FcPattern
*p
, const char *object
)
675 int low
, high
, mid
, c
;
678 obj
= FcObjectToPtr(object
);
685 mid
= (low
+ high
) >> 1;
686 c
= FcObjectPtrCompare((FcPatternEltU(p
->elts
)+mid
)->object
, obj
);
700 FcPatternFindElt (const FcPattern
*p
, const char *object
)
702 int i
= FcPatternPosition (p
, object
);
705 return FcPatternEltU(p
->elts
)+i
;
709 FcPatternInsertElt (FcPattern
*p
, const char *object
)
714 i
= FcPatternPosition (p
, object
);
719 /* reallocate array */
720 if (p
->num
+ 1 >= p
->size
)
722 int s
= p
->size
+ 16;
723 if (FcPatternEltU(p
->elts
))
725 FcPatternElt
*e0
= FcPatternEltU(p
->elts
);
726 e
= (FcPatternElt
*) realloc (e0
, s
* sizeof (FcPatternElt
));
727 if (!e
) /* maybe it was mmapped */
729 e
= malloc(s
* sizeof (FcPatternElt
));
731 memcpy(e
, e0
, p
->num
* sizeof (FcPatternElt
));
735 e
= (FcPatternElt
*) malloc (s
* sizeof (FcPatternElt
));
738 p
->elts
= FcPatternEltPtrCreateDynamic(e
);
740 FcMemFree (FC_MEM_PATELT
, p
->size
* sizeof (FcPatternElt
));
741 FcMemAlloc (FC_MEM_PATELT
, s
* sizeof (FcPatternElt
));
744 (FcPatternEltU(p
->elts
)+p
->size
)->object
= 0;
745 (FcPatternEltU(p
->elts
)+p
->size
)->values
=
746 FcValueListPtrCreateDynamic(0);
752 memmove (FcPatternEltU(p
->elts
) + i
+ 1,
753 FcPatternEltU(p
->elts
) + i
,
754 sizeof (FcPatternElt
) *
760 (FcPatternEltU(p
->elts
)+i
)->object
= FcObjectToPtr (object
);
761 (FcPatternEltU(p
->elts
)+i
)->values
= FcValueListPtrCreateDynamic(0);
764 return FcPatternEltU(p
->elts
)+i
;
768 FcPatternEqual (const FcPattern
*pa
, const FcPattern
*pb
)
775 if (pa
->num
!= pb
->num
)
777 for (i
= 0; i
< pa
->num
; i
++)
779 if (FcObjectPtrCompare((FcPatternEltU(pa
->elts
)+i
)->object
,
780 (FcPatternEltU(pb
->elts
)+i
)->object
) != 0)
782 if (!FcValueListEqual ((FcPatternEltU(pa
->elts
)+i
)->values
,
783 (FcPatternEltU(pb
->elts
)+i
)->values
))
790 FcPatternHash (const FcPattern
*p
)
795 for (i
= 0; i
< p
->num
; i
++)
797 h
= (((h
<< 1) | (h
>> 31)) ^
798 FcStringHash ((FcChar8
*)FcObjectPtrU ((FcPatternEltU(p
->elts
)+i
)->object
)) ^
799 FcValueListHash ((FcPatternEltU(p
->elts
)+i
)->values
));
805 FcPatternEqualSubset (const FcPattern
*pai
, const FcPattern
*pbi
, const FcObjectSet
*os
)
807 FcPatternElt
*ea
, *eb
;
810 for (i
= 0; i
< os
->nobject
; i
++)
812 ea
= FcPatternFindElt (pai
, os
->objects
[i
]);
813 eb
= FcPatternFindElt (pbi
, os
->objects
[i
]);
818 if (!FcValueListEqual (ea
->values
, eb
->values
))
831 FcPatternAddWithBinding (FcPattern
*p
,
834 FcValueBinding binding
,
838 FcValueListPtr
new, *prev
;
841 if (p
->ref
== FC_REF_CONSTANT
)
844 newp
= malloc (sizeof (FcValueList
));
848 memset(newp
, 0, sizeof (FcValueList
));
849 new = FcValueListPtrCreateDynamic(newp
);
850 FcMemAlloc (FC_MEM_VALLIST
, sizeof (FcValueList
));
852 value
= FcValueSave (value
);
853 if (value
.type
== FcTypeVoid
)
856 FcValueListPtrU(new)->value
= value
;
857 FcValueListPtrU(new)->binding
= binding
;
858 FcValueListPtrU(new)->next
= FcValueListPtrCreateDynamic(0);
860 e
= FcPatternInsertElt (p
, object
);
866 for (prev
= &e
->values
; FcValueListPtrU(*prev
); prev
= &FcValueListPtrU(*prev
)->next
)
872 FcValueListPtrU(new)->next
= e
->values
;
879 switch (value
.type
) {
881 FcStrFree ((FcChar8
*) value
.u
.s
);
884 FcMatrixFree ((FcMatrix
*) value
.u
.m
);
887 FcCharSetDestroy ((FcCharSet
*) value
.u
.c
);
890 FcLangSetDestroy ((FcLangSet
*) value
.u
.l
);
896 FcMemFree (FC_MEM_VALLIST
, sizeof (FcValueList
));
897 free (FcValueListPtrU(new));
903 FcPatternAdd (FcPattern
*p
, const char *object
, FcValue value
, FcBool append
)
905 return FcPatternAddWithBinding (p
, object
, value
, FcValueBindingStrong
, append
);
909 FcPatternAddWeak (FcPattern
*p
, const char *object
, FcValue value
, FcBool append
)
911 return FcPatternAddWithBinding (p
, object
, value
, FcValueBindingWeak
, append
);
915 FcPatternDel (FcPattern
*p
, const char *object
)
919 e
= FcPatternFindElt (p
, object
);
924 FcValueListDestroy (e
->values
);
926 /* shuffle existing ones down */
928 (FcPatternEltU(p
->elts
) + p
->num
- (e
+ 1)) *
929 sizeof (FcPatternElt
));
931 (FcPatternEltU(p
->elts
)+p
->num
)->object
= 0;
932 (FcPatternEltU(p
->elts
)+p
->num
)->values
= FcValueListPtrCreateDynamic(0);
937 FcPatternRemove (FcPattern
*p
, const char *object
, int id
)
940 FcValueListPtr
*prev
, l
;
942 e
= FcPatternFindElt (p
, object
);
945 for (prev
= &e
->values
;
946 FcValueListPtrU(l
= *prev
);
947 prev
= &FcValueListPtrU(l
)->next
)
951 *prev
= FcValueListPtrU(l
)->next
;
952 FcValueListPtrU(l
)->next
= FcValueListPtrCreateDynamic(0);
953 FcValueListDestroy (l
);
954 if (!FcValueListPtrU(e
->values
))
955 FcPatternDel (p
, object
);
964 FcPatternAddInteger (FcPattern
*p
, const char *object
, int i
)
968 v
.type
= FcTypeInteger
;
970 return FcPatternAdd (p
, object
, v
, FcTrue
);
974 FcPatternAddDouble (FcPattern
*p
, const char *object
, double d
)
978 v
.type
= FcTypeDouble
;
980 return FcPatternAdd (p
, object
, v
, FcTrue
);
985 FcPatternAddString (FcPattern
*p
, const char *object
, const FcChar8
*s
)
989 v
.type
= FcTypeString
;
990 v
.u
.s
= FcStrStaticName(s
);
991 return FcPatternAdd (p
, object
, v
, FcTrue
);
995 FcPatternAddMatrix (FcPattern
*p
, const char *object
, const FcMatrix
*s
)
999 v
.type
= FcTypeMatrix
;
1001 return FcPatternAdd (p
, object
, v
, FcTrue
);
1006 FcPatternAddBool (FcPattern
*p
, const char *object
, FcBool b
)
1010 v
.type
= FcTypeBool
;
1012 return FcPatternAdd (p
, object
, v
, FcTrue
);
1016 FcPatternAddCharSet (FcPattern
*p
, const char *object
, const FcCharSet
*c
)
1020 v
.type
= FcTypeCharSet
;
1021 v
.u
.c
= (FcCharSet
*)c
;
1022 return FcPatternAdd (p
, object
, v
, FcTrue
);
1026 FcPatternAddFTFace (FcPattern
*p
, const char *object
, const FT_Face f
)
1030 v
.type
= FcTypeFTFace
;
1032 return FcPatternAdd (p
, object
, v
, FcTrue
);
1036 FcPatternAddLangSet (FcPattern
*p
, const char *object
, const FcLangSet
*ls
)
1040 v
.type
= FcTypeLangSet
;
1041 v
.u
.l
= (FcLangSet
*)ls
;
1042 return FcPatternAdd (p
, object
, v
, FcTrue
);
1046 FcPatternGet (const FcPattern
*p
, const char *object
, int id
, FcValue
*v
)
1051 e
= FcPatternFindElt (p
, object
);
1053 return FcResultNoMatch
;
1054 for (l
= e
->values
; FcValueListPtrU(l
); l
= FcValueListPtrU(l
)->next
)
1058 *v
= FcValueCanonicalize(&FcValueListPtrU(l
)->value
);
1059 return FcResultMatch
;
1063 return FcResultNoId
;
1067 FcPatternGetInteger (const FcPattern
*p
, const char *object
, int id
, int *i
)
1072 r
= FcPatternGet (p
, object
, id
, &v
);
1073 if (r
!= FcResultMatch
)
1083 return FcResultTypeMismatch
;
1085 return FcResultMatch
;
1089 FcPatternGetDouble (const FcPattern
*p
, const char *object
, int id
, double *d
)
1094 r
= FcPatternGet (p
, object
, id
, &v
);
1095 if (r
!= FcResultMatch
)
1102 *d
= (double) v
.u
.i
;
1105 return FcResultTypeMismatch
;
1107 return FcResultMatch
;
1111 FcPatternGetString (const FcPattern
*p
, const char *object
, int id
, FcChar8
** s
)
1116 r
= FcPatternGet (p
, object
, id
, &v
);
1117 if (r
!= FcResultMatch
)
1119 if (v
.type
!= FcTypeString
)
1120 return FcResultTypeMismatch
;
1122 if (FcObjectToPtr(object
) == FcObjectToPtr(FC_FILE
))
1124 const char *fn
, *fpath
;
1128 fn
= FcPatternFindFullFname(p
);
1131 *s
= (FcChar8
*) fn
;
1132 return FcResultMatch
;
1137 *s
= (FcChar8
*) v
.u
.s
;
1138 return FcResultMatch
;
1141 fpath
= FcCacheFindBankDir (p
->bank
);
1142 size
= strlen((char*)fpath
) + 1 + strlen ((char *)v
.u
.s
) + 1;
1143 fname
= malloc (size
);
1145 return FcResultOutOfMemory
;
1147 FcMemAlloc (FC_MEM_STRING
, size
);
1148 strcpy ((char *)fname
, (char *)fpath
);
1149 strcat ((char *)fname
, "/");
1150 strcat ((char *)fname
, (char *)v
.u
.s
);
1152 FcPatternAddFullFname (p
, (const char *)fname
);
1153 *s
= (FcChar8
*)fname
;
1154 return FcResultMatch
;
1157 *s
= (FcChar8
*) v
.u
.s
;
1158 return FcResultMatch
;
1162 FcPatternGetMatrix(const FcPattern
*p
, const char *object
, int id
, FcMatrix
**m
)
1167 r
= FcPatternGet (p
, object
, id
, &v
);
1168 if (r
!= FcResultMatch
)
1170 if (v
.type
!= FcTypeMatrix
)
1171 return FcResultTypeMismatch
;
1172 *m
= (FcMatrix
*)v
.u
.m
;
1173 return FcResultMatch
;
1178 FcPatternGetBool(const FcPattern
*p
, const char *object
, int id
, FcBool
*b
)
1183 r
= FcPatternGet (p
, object
, id
, &v
);
1184 if (r
!= FcResultMatch
)
1186 if (v
.type
!= FcTypeBool
)
1187 return FcResultTypeMismatch
;
1189 return FcResultMatch
;
1193 FcPatternGetCharSet(const FcPattern
*p
, const char *object
, int id
, FcCharSet
**c
)
1198 r
= FcPatternGet (p
, object
, id
, &v
);
1199 if (r
!= FcResultMatch
)
1201 if (v
.type
!= FcTypeCharSet
)
1202 return FcResultTypeMismatch
;
1203 *c
= (FcCharSet
*)v
.u
.c
;
1204 return FcResultMatch
;
1208 FcPatternGetFTFace(const FcPattern
*p
, const char *object
, int id
, FT_Face
*f
)
1213 r
= FcPatternGet (p
, object
, id
, &v
);
1214 if (r
!= FcResultMatch
)
1216 if (v
.type
!= FcTypeFTFace
)
1217 return FcResultTypeMismatch
;
1218 *f
= (FT_Face
) v
.u
.f
;
1219 return FcResultMatch
;
1223 FcPatternGetLangSet(const FcPattern
*p
, const char *object
, int id
, FcLangSet
**ls
)
1228 r
= FcPatternGet (p
, object
, id
, &v
);
1229 if (r
!= FcResultMatch
)
1231 if (v
.type
!= FcTypeLangSet
)
1232 return FcResultTypeMismatch
;
1233 *ls
= (FcLangSet
*)v
.u
.l
;
1234 return FcResultMatch
;
1238 FcPatternDuplicate (const FcPattern
*orig
)
1245 new = FcPatternCreate ();
1249 e
= FcPatternEltU(orig
->elts
);
1251 for (i
= 0; i
< orig
->num
; i
++)
1253 for (l
= (e
+ i
)->values
;
1255 l
= FcValueListPtrU(l
)->next
)
1256 if (!FcPatternAdd (new, FcObjectPtrU((e
+ i
)->object
),
1257 FcValueCanonicalize(&FcValueListPtrU(l
)->value
),
1265 FcPatternDestroy (new);
1271 FcPatternReference (FcPattern
*p
)
1273 if (p
->ref
!= FC_REF_CONSTANT
)
1278 FcPatternVaBuild (FcPattern
*orig
, va_list va
)
1282 FcPatternVapBuild (ret
, orig
, va
);
1287 FcPatternBuild (FcPattern
*orig
, ...)
1291 va_start (va
, orig
);
1292 FcPatternVapBuild (orig
, orig
, va
);
1298 * Add all of the elements in 's' to 'p'
1301 FcPatternAppend (FcPattern
*p
, FcPattern
*s
)
1307 for (i
= 0; i
< s
->num
; i
++)
1309 e
= FcPatternEltU(s
->elts
)+i
;
1310 for (v
= e
->values
; FcValueListPtrU(v
);
1311 v
= FcValueListPtrU(v
)->next
)
1313 if (!FcPatternAddWithBinding (p
, FcObjectPtrU(e
->object
),
1314 FcValueCanonicalize(&FcValueListPtrU(v
)->value
),
1315 FcValueListPtrU(v
)->binding
, FcTrue
))
1322 #define OBJECT_HASH_SIZE 31
1323 static struct objectBucket
{
1324 struct objectBucket
*next
;
1326 } *FcObjectBuckets
[OBJECT_HASH_SIZE
];
1329 FcStrStaticName (const FcChar8
*name
)
1331 FcChar32 hash
= FcStringHash (name
);
1332 struct objectBucket
**p
;
1333 struct objectBucket
*b
;
1336 for (p
= &FcObjectBuckets
[hash
% OBJECT_HASH_SIZE
]; (b
= *p
); p
= &(b
->next
))
1337 if (b
->hash
== hash
&& !strcmp ((char *)name
, (char *) (b
+ 1)))
1338 return (FcChar8
*) (b
+ 1);
1339 size
= sizeof (struct objectBucket
) + strlen ((char *)name
) + 1;
1340 b
= malloc (size
+ sizeof (int));
1341 /* workaround glibc bug which reads strlen in groups of 4 */
1342 FcMemAlloc (FC_MEM_STATICSTR
, size
+ sizeof (int));
1347 strcpy ((char *) (b
+ 1), (char *)name
);
1349 return (FcChar8
*) (b
+ 1);
1353 FcStrStaticNameFini (void)
1356 struct objectBucket
*b
, *next
;
1359 for (i
= 0; i
< OBJECT_HASH_SIZE
; i
++)
1361 for (b
= FcObjectBuckets
[i
]; b
; b
= next
)
1364 name
= (char *) (b
+ 1);
1365 size
= sizeof (struct objectBucket
) + strlen (name
) + 1;
1366 FcMemFree (FC_MEM_STATICSTR
, size
);
1369 FcObjectBuckets
[i
] = 0;
1374 FcPatternFini (void)
1376 FcPatternBaseThawAll ();
1377 FcValueListThawAll ();
1378 FcStrStaticNameFini ();
1379 FcObjectStaticNameFini ();
1383 FcPatternEltU (FcPatternEltPtr pei
)
1385 if (pei
.bank
== FC_BANK_DYNAMIC
)
1388 return &fcpatternelts
[FcCacheBankToIndex(pei
.bank
)][pei
.u
.stat
];
1391 static FcPatternEltPtr
1392 FcPatternEltPtrCreateDynamic (FcPatternElt
* e
)
1394 FcPatternEltPtr
new;
1395 new.bank
= FC_BANK_DYNAMIC
;
1400 static FcPatternEltPtr
1401 FcPatternEltPtrCreateStatic (int bank
, int i
)
1403 FcPatternEltPtr
new;
1410 FcStrNewBank (void);
1412 FcStrNeededBytes (const FcChar8
* s
);
1414 FcStrDistributeBytes (FcCache
* metadata
, void * block_ptr
);
1415 static const FcChar8
*
1416 FcStrSerialize (int bank
, const FcChar8
* s
);
1418 FcStrUnserialize (FcCache metadata
, void *block_ptr
);
1421 FcValueListNewBank (void);
1423 FcValueListNeededBytes (FcValueList
* vl
);
1425 FcValueListDistributeBytes (FcCache
* metadata
, void *block_ptr
);
1426 static FcValueListPtr
1427 FcValueListSerialize(int bank
, FcValueList
*pi
);
1429 FcValueListUnserialize (FcCache metadata
, void *block_ptr
);
1433 FcPatternNewBank (void)
1435 fcpattern_count
= 0;
1436 fcpatternelt_count
= 0;
1439 FcValueListNewBank();
1443 FcPatternNeededBytes (FcPattern
* p
)
1448 fcpatternelt_count
+= p
->num
;
1450 for (i
= 0; i
< p
->num
; i
++)
1452 c
= FcValueListNeededBytes (FcValueListPtrU
1453 (((FcPatternEltU(p
->elts
)+i
)->values
)));
1459 return cum
+ sizeof (FcPattern
) + sizeof(FcPatternElt
)*p
->num
;
1463 FcPatternEnsureBank (int bi
)
1469 if (!fcpatterns
|| fcpattern_bank_count
<= bi
)
1471 int new_count
= bi
+ 4;
1472 pp
= realloc (fcpatterns
, sizeof (FcPattern
*) * new_count
);
1476 FcMemAlloc (FC_MEM_PATTERN
, sizeof (FcPattern
*) * new_count
);
1479 ep
= realloc (fcpatternelts
, sizeof (FcPatternElt
*) * new_count
);
1483 FcMemAlloc (FC_MEM_PATELT
, sizeof (FcPatternElt
*) * new_count
);
1486 for (i
= fcpattern_bank_count
; i
< new_count
; i
++)
1489 fcpatternelts
[i
] = 0;
1492 fcpattern_bank_count
= new_count
;
1495 FcMemAlloc (FC_MEM_PATTERN
, sizeof (FcPattern
) * fcpattern_count
);
1500 FcPatternDistributeBytes (FcCache
* metadata
, void * block_ptr
)
1502 int bi
= FcCacheBankToIndex(metadata
->bank
);
1504 if (!FcPatternEnsureBank(bi
))
1508 fcpatterns
[bi
] = (FcPattern
*)block_ptr
;
1509 block_ptr
= (void *)((char *)block_ptr
+
1510 (sizeof (FcPattern
) * fcpattern_count
));
1512 FcMemAlloc (FC_MEM_PATELT
, sizeof (FcPatternElt
) * fcpatternelt_count
);
1513 fcpatternelt_ptr
= 0;
1514 fcpatternelts
[bi
] = (FcPatternElt
*)block_ptr
;
1515 block_ptr
= (void *)((char *)block_ptr
+
1516 (sizeof (FcPatternElt
) * fcpatternelt_count
));
1518 metadata
->pattern_count
= fcpattern_count
;
1519 metadata
->patternelt_count
= fcpatternelt_count
;
1521 block_ptr
= FcStrDistributeBytes (metadata
, block_ptr
);
1522 block_ptr
= FcValueListDistributeBytes (metadata
, block_ptr
);
1527 FcPatternSerialize (int bank
, FcPattern
*old
)
1530 FcPatternElt
*e
, *nep
;
1532 FcValueListPtr v
, nv_head
, nvp
;
1533 int i
, elts
, bi
= FcCacheBankToIndex(bank
);
1535 p
= &fcpatterns
[bi
][fcpattern_ptr
++];
1537 elts
= fcpatternelt_ptr
;
1538 nep
= &fcpatternelts
[bi
][elts
];
1542 fcpatternelt_ptr
+= old
->num
;
1544 for (e
= FcPatternEltU(old
->elts
), i
=0; i
< old
->num
; i
++, e
++)
1547 nvp
= nv_head
= FcValueListSerialize(bank
, FcValueListPtrU(v
));
1548 if (!FcValueListPtrU(nv_head
))
1550 nv
= FcValueListPtrU(nvp
);
1554 v
= FcValueListPtrU(v
)->next
,
1555 nv
= FcValueListPtrU(nv
->next
))
1558 if (FcValueListPtrU(FcValueListPtrU(v
)->next
))
1560 nvp
= FcValueListSerialize
1561 (bank
, FcValueListPtrU(FcValueListPtrU(v
)->next
));
1566 nep
[i
].values
= nv_head
;
1567 nep
[i
].object
= e
->object
;
1570 p
->elts
= old
->elts
;
1571 p
->elts
= FcPatternEltPtrCreateStatic(bank
, elts
);
1574 p
->ref
= FC_REF_CONSTANT
;
1579 FcPatternUnserialize (FcCache metadata
, void *block_ptr
)
1581 int bi
= FcCacheBankToIndex(metadata
.bank
);
1582 if (!FcPatternEnsureBank(bi
))
1585 FcMemAlloc (FC_MEM_PATTERN
, sizeof (FcPattern
) * metadata
.pattern_count
);
1586 fcpatterns
[bi
] = (FcPattern
*)block_ptr
;
1587 block_ptr
= (void *)((char *)block_ptr
+
1588 (sizeof (FcPattern
) * metadata
.pattern_count
));
1590 FcMemAlloc (FC_MEM_PATELT
,
1591 sizeof (FcPatternElt
) * metadata
.patternelt_count
);
1592 fcpatternelts
[bi
] = (FcPatternElt
*)block_ptr
;
1593 block_ptr
= (void *)((char *)block_ptr
+
1594 (sizeof (FcPatternElt
) * metadata
.patternelt_count
));
1596 block_ptr
= FcStrUnserialize (metadata
, block_ptr
);
1597 block_ptr
= FcValueListUnserialize (metadata
, block_ptr
);
1603 FcValueListNewBank (void)
1605 fcvaluelist_count
= 0;
1612 FcValueListNeededBytes (FcValueList
*p
)
1619 vl
= FcValueListPtrU(vl
->next
))
1621 FcValue v
= FcValueCanonicalize(&vl
->value
); // unserialize just in case
1626 cum
+= FcCharSetNeededBytes(v
.u
.c
);
1629 cum
+= FcLangSetNeededBytes(v
.u
.l
);
1632 cum
+= FcStrNeededBytes(v
.u
.s
);
1636 fcvaluelist_count
++;
1637 cum
+= sizeof (FcValueList
);
1644 FcValueListEnsureBank (int bi
)
1648 if (!fcvaluelists
|| fcvaluelist_bank_count
<= bi
)
1650 int new_count
= bi
+ 2, i
;
1652 pvl
= realloc (fcvaluelists
, sizeof (FcValueList
*) * new_count
);
1656 FcMemAlloc (FC_MEM_VALLIST
, sizeof (FcValueList
*) * new_count
);
1659 for (i
= fcvaluelist_bank_count
; i
< new_count
; i
++)
1660 fcvaluelists
[i
] = 0;
1662 fcvaluelist_bank_count
= new_count
;
1668 FcValueListDistributeBytes (FcCache
* metadata
, void *block_ptr
)
1670 int bi
= FcCacheBankToIndex(metadata
->bank
);
1672 if (!FcValueListEnsureBank(bi
))
1675 FcMemAlloc (FC_MEM_VALLIST
, sizeof (FcValueList
) * fcvaluelist_count
);
1676 fcvaluelist_ptr
= 0;
1677 fcvaluelists
[bi
] = (FcValueList
*)block_ptr
;
1678 block_ptr
= (void *)((char *)block_ptr
+
1679 (sizeof (FcValueList
) * fcvaluelist_count
));
1680 metadata
->valuelist_count
= fcvaluelist_count
;
1682 block_ptr
= FcCharSetDistributeBytes(metadata
, block_ptr
);
1683 block_ptr
= FcLangSetDistributeBytes(metadata
, block_ptr
);
1688 static FcValueListPtr
1689 FcValueListSerialize(int bank
, FcValueList
*pi
)
1693 int bi
= FcCacheBankToIndex(bank
);
1697 new.bank
= FC_BANK_DYNAMIC
;
1702 fcvaluelists
[bi
][fcvaluelist_ptr
] = *pi
;
1704 new.u
.stat
= fcvaluelist_ptr
++;
1705 v
= &fcvaluelists
[bi
][new.u
.stat
].value
;
1711 const FcChar8
* s
= FcStrSerialize(bank
, v
->u
.s
);
1713 return FcValueListPtrCreateDynamic(pi
);
1714 v
->u
.s_off
= s
- (const FcChar8
*)v
;
1715 v
->type
|= FC_STORAGE_STATIC
;
1723 FcCharSet
* c
= FcCharSetSerialize(bank
, (FcCharSet
*)v
->u
.c
);
1725 return FcValueListPtrCreateDynamic(pi
);
1726 v
->u
.c_off
= (char *)c
- (char *)v
;
1727 v
->type
|= FC_STORAGE_STATIC
;
1733 FcLangSet
* l
= FcLangSetSerialize(bank
, (FcLangSet
*)v
->u
.l
);
1735 return FcValueListPtrCreateDynamic(pi
);
1736 v
->u
.l_off
= (char *)l
- (char *)v
;
1737 v
->type
|= FC_STORAGE_STATIC
;
1747 FcValueListUnserialize (FcCache metadata
, void *block_ptr
)
1749 int bi
= FcCacheBankToIndex(metadata
.bank
);
1751 if (!FcValueListEnsureBank(bi
))
1754 FcMemAlloc (FC_MEM_VALLIST
,
1755 sizeof (FcValueList
) * metadata
.valuelist_count
);
1756 fcvaluelists
[bi
] = (FcValueList
*)block_ptr
;
1757 block_ptr
= (void *)((char *)block_ptr
+
1758 (sizeof (FcValueList
) * metadata
.valuelist_count
));
1760 block_ptr
= FcCharSetUnserialize(metadata
, block_ptr
);
1761 block_ptr
= FcLangSetUnserialize(metadata
, block_ptr
);
1767 FcValueListPtrU (FcValueListPtr pi
)
1769 if (pi
.bank
== FC_BANK_DYNAMIC
)
1772 return &fcvaluelists
[FcCacheBankToIndex(pi
.bank
)][pi
.u
.stat
];
1776 FcValueListPtrCreateDynamic(FcValueList
* p
)
1780 r
.bank
= FC_BANK_DYNAMIC
;
1785 static FcChar8
** static_strs
;
1786 static int static_str_bank_count
= 0, fcstr_ptr
, fcstr_count
;
1788 static struct objectBucket
*FcStrBuckets
[OBJECT_HASH_SIZE
];
1794 struct objectBucket
*b
, *next
;
1797 for (i
= 0; i
< OBJECT_HASH_SIZE
; i
++)
1799 for (b
= FcStrBuckets
[i
]; b
; b
= next
)
1802 name
= (char *) (b
+ 1);
1803 size
= sizeof (struct objectBucket
) + strlen (name
) + 1;
1804 FcMemFree (FC_MEM_STATICSTR
, size
);
1807 FcStrBuckets
[i
] = 0;
1814 FcStrNeededBytes (const FcChar8
* s
)
1816 FcChar32 hash
= FcStringHash ((const FcChar8
*) s
);
1817 struct objectBucket
**p
;
1818 struct objectBucket
*b
;
1821 for (p
= &FcStrBuckets
[hash
% OBJECT_HASH_SIZE
]; (b
= *p
); p
= &(b
->next
))
1822 if (b
->hash
== hash
&& !strcmp ((char *)s
, (char *) (b
+ 1)))
1824 size
= sizeof (struct objectBucket
) + strlen ((char *)s
) + 1 + sizeof(char *);
1826 FcMemAlloc (FC_MEM_STATICSTR
, size
);
1831 strcpy ((char *) (b
+ 1), (char *)s
);
1832 *(char **)((char *) (b
+ 1) + strlen((char *)s
) + 1) = 0;
1835 fcstr_count
+= strlen((char *)s
) + 1;
1836 return strlen((char *)s
) + 1;
1840 FcStrEnsureBank (int bi
)
1844 if (!static_strs
|| static_str_bank_count
<= bi
)
1846 int new_count
= bi
+ 4, i
;
1847 ss
= realloc (static_strs
, sizeof (const char *) * new_count
);
1851 FcMemAlloc (FC_MEM_STRING
, sizeof (const char *) * (new_count
-static_str_bank_count
));
1854 for (i
= static_str_bank_count
; i
< new_count
; i
++)
1856 static_str_bank_count
= new_count
;
1862 FcStrDistributeBytes (FcCache
* metadata
, void * block_ptr
)
1864 int bi
= FcCacheBankToIndex(metadata
->bank
);
1865 if (!FcStrEnsureBank(bi
))
1868 FcMemAlloc (FC_MEM_STRING
, sizeof (char) * fcstr_count
);
1869 static_strs
[bi
] = (FcChar8
*)block_ptr
;
1870 block_ptr
= (void *)((char *)block_ptr
+ (sizeof (char) * fcstr_count
));
1871 metadata
->str_count
= fcstr_count
;
1877 static const FcChar8
*
1878 FcStrSerialize (int bank
, const FcChar8
* s
)
1880 FcChar32 hash
= FcStringHash ((const FcChar8
*) s
);
1881 struct objectBucket
**p
;
1882 struct objectBucket
*b
;
1883 int bi
= FcCacheBankToIndex(bank
);
1885 for (p
= &FcStrBuckets
[hash
% OBJECT_HASH_SIZE
]; (b
= *p
); p
= &(b
->next
))
1886 if (b
->hash
== hash
&& !strcmp ((char *)s
, (char *) (b
+ 1)))
1888 FcChar8
* t
= *(FcChar8
**)(((FcChar8
*)(b
+ 1)) + strlen ((char *)s
) + 1);
1891 strcpy((char *)(static_strs
[bi
] + fcstr_ptr
), (char *)s
);
1892 *(FcChar8
**)((FcChar8
*) (b
+ 1) + strlen((char *)s
) + 1) = (static_strs
[bi
] + fcstr_ptr
);
1893 fcstr_ptr
+= strlen((char *)s
) + 1;
1894 t
= *(FcChar8
**)(((FcChar8
*)(b
+ 1)) + strlen ((char *)s
) + 1);
1902 FcStrUnserialize (FcCache metadata
, void *block_ptr
)
1904 int bi
= FcCacheBankToIndex(metadata
.bank
);
1905 if (!FcStrEnsureBank(bi
))
1908 FcMemAlloc (FC_MEM_STRING
, sizeof (char) * metadata
.str_count
);
1909 static_strs
[bi
] = (FcChar8
*)block_ptr
;
1910 block_ptr
= (void *)((char *)block_ptr
+
1911 (sizeof (char) * metadata
.str_count
));
1916 /* we don't store these in the FcPattern itself because
1917 * we don't want to serialize the directory names */
1919 /* I suppose this should be cleaned, too... */
1920 typedef struct _FcPatternDirMapping
{
1923 } FcPatternDirMapping
;
1925 #define PATTERNDIR_HASH_SIZE 31
1926 static struct patternDirBucket
{
1927 struct patternDirBucket
*next
;
1928 FcPatternDirMapping m
;
1929 } FcPatternDirBuckets
[PATTERNDIR_HASH_SIZE
];
1932 FcPatternAddFullFname (const FcPattern
*p
, const char *fname
)
1934 struct patternDirBucket
*pb
;
1936 /* N.B. FcPatternHash fails, since it's contents-based, not
1937 * address-based, and we're in the process of mutating the FcPattern. */
1938 for (pb
= &FcPatternDirBuckets
1939 [((int)p
/ sizeof (FcPattern
*)) % PATTERNDIR_HASH_SIZE
];
1940 pb
->m
.p
!= p
&& pb
->next
;
1946 pb
->m
.fname
= fname
;
1950 pb
->next
= malloc (sizeof (struct patternDirBucket
));
1953 FcMemAlloc (FC_MEM_CACHE
, sizeof (struct patternDirBucket
));
1957 pb
->next
->m
.fname
= fname
;
1961 FcPatternFindFullFname (const FcPattern
*p
)
1963 struct patternDirBucket
*pb
;
1965 for (pb
= &FcPatternDirBuckets
1966 [((int)p
/ sizeof (FcPattern
*)) % PATTERNDIR_HASH_SIZE
];